• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 /**
17  ******************************************************************************
18  * @file    M4PTO3GPP_API.c
19  * @brief   Picture to 3gpp Service implementation.
20  * @note
21  ******************************************************************************
22 */
23 
24 /*16 bytes signature to be written in the generated 3gp files */
25 #define M4PTO3GPP_SIGNATURE     "NXP-SW : PTO3GPP"
26 
27 /****************/
28 /*** Includes ***/
29 /****************/
30 
31 /**
32  *  Our header */
33 #include "M4PTO3GPP_InternalTypes.h"
34 #include "M4PTO3GPP_API.h"
35 
36 /**
37  *  Our errors */
38 #include "M4PTO3GPP_ErrorCodes.h"
39 
40 #ifdef M4VSS_SUPPORT_ENCODER_MPEG4
41 #include "VideoEditorVideoEncoder.h"
42 #endif
43 
44 
45 /**
46  *  OSAL headers */
47 #include "M4OSA_Memory.h"       /* OSAL memory management */
48 #include "M4OSA_Debug.h"        /* OSAL debug management */
49 
50 
51 /************************/
52 /*** Various Magicals ***/
53 /************************/
54 
55 #define M4PTO3GPP_WRITER_AUDIO_STREAM_ID                1
56 #define M4PTO3GPP_WRITER_VIDEO_STREAM_ID                2
57 #define M4PTO3GPP_QUANTIZER_STEP                        4       /**< Quantizer step */
58 #define M4PTO3GPP_WRITER_AUDIO_PROFILE_LEVEL            0xFF    /**< No specific profile and
59                                                                      level */
60 #define M4PTO3GPP_WRITER_AUDIO_AMR_TIME_SCALE           8000    /**< AMR */
61 #define M4PTO3GPP_BITRATE_REGULATION_CTS_PERIOD_IN_MS   500     /**< MAGICAL */
62 #define M4PTO3GPP_MARGE_OF_FILE_SIZE                    25000   /**< MAGICAL */
63 /**
64  ******************************************************************************
65  * define   AMR 12.2 kbps silence frame
66  ******************************************************************************
67 */
68 #define M4PTO3GPP_AMR_AU_SILENCE_FRAME_122_SIZE     32
69 #define M4PTO3GPP_AMR_AU_SILENCE_FRAME_122_DURATION 20
70 const M4OSA_UInt8 M4PTO3GPP_AMR_AU_SILENCE_122_FRAME[M4PTO3GPP_AMR_AU_SILENCE_FRAME_122_SIZE]=
71 { 0x3C, 0x91, 0x17, 0x16, 0xBE, 0x66, 0x78, 0x00, 0x00, 0x01, 0xE7, 0xAF,
72   0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
74 
75 #define M4PTO3GPP_AMR_AU_SILENCE_FRAME_048_SIZE     13
76 #define M4PTO3GPP_AMR_AU_SILENCE_FRAME_048_DURATION 20
77 const M4OSA_UInt8 M4PTO3GPP_AMR_AU_SILENCE_048_FRAME[M4PTO3GPP_AMR_AU_SILENCE_FRAME_048_SIZE] =
78 { 0x04, 0xFF, 0x18, 0xC7, 0xF0, 0x0D, 0x04, 0x33, 0xFF, 0xE0, 0x00, 0x00, 0x00 };
79 
80 /***************************/
81 /*** "Private" functions ***/
82 /***************************/
83 static M4OSA_ERR M4PTO3GPP_Ready4Processing(M4PTO3GPP_InternalContext* pC);
84 
85 /****************************/
86 /*** "External" functions ***/
87 /****************************/
88 extern M4OSA_ERR M4WRITER_3GP_getInterfaces(M4WRITER_OutputFileType* pType,
89                                             M4WRITER_GlobalInterface** SrcGlobalInterface,
90                                             M4WRITER_DataInterface** SrcDataInterface);
91 extern M4OSA_ERR M4READER_AMR_getInterfaces(M4READER_MediaType *pMediaType,
92                                             M4READER_GlobalInterface **pRdrGlobalInterface,
93                                             M4READER_DataInterface **pRdrDataInterface);
94 extern M4OSA_ERR M4READER_3GP_getInterfaces(M4READER_MediaType *pMediaType,
95                                             M4READER_GlobalInterface **pRdrGlobalInterface,
96                                             M4READER_DataInterface **pRdrDataInterface);
97 
98 /****************************/
99 /*** "Static" functions ***/
100 /****************************/
101 static M4OSA_ERR M4PTO3GPP_writeAmrSilence122Frame(
102                                     M4WRITER_DataInterface* pWriterDataIntInterface,
103                                     M4WRITER_Context* pWriterContext,
104                                     M4SYS_AccessUnit* pWriterAudioAU,
105                                     M4OSA_Time mtIncCts);
106 static M4OSA_ERR M4PTO3GPP_writeAmrSilence048Frame(
107                                    M4WRITER_DataInterface* pWriterDataIntInterface,
108                                    M4WRITER_Context* pWriterContext,
109                                    M4SYS_AccessUnit* pWriterAudioAU,
110                                    M4OSA_Time mtIncCts);
111 /**
112  ******************************************************************************
113  * M4OSA_ERR M4PTO3GPP_GetVersion(M4_VersionInfo* pVersionInfo);
114  * @brief   Get the M4PTO3GPP version.
115  * @note    Can be called anytime. Do not need any context.
116  * @param   pVersionInfo        (OUT) Pointer to a version info structure
117  * @return  M4NO_ERROR:         No error
118  * @return  M4ERR_PARAMETER:    pVersionInfo is M4OSA_NULL (If Debug Level >= 2)
119  ******************************************************************************
120 */
121 
122 /*********************************************************/
M4PTO3GPP_GetVersion(M4_VersionInfo * pVersionInfo)123 M4OSA_ERR M4PTO3GPP_GetVersion(M4_VersionInfo* pVersionInfo)
124 /*********************************************************/
125 {
126     M4OSA_TRACE3_1("M4PTO3GPP_GetVersion called with pVersionInfo=0x%x", pVersionInfo);
127 
128     /**
129      *  Check input parameters */
130     M4OSA_DEBUG_IF2((M4OSA_NULL==pVersionInfo),M4ERR_PARAMETER,
131             "M4PTO3GPP_GetVersion: pVersionInfo is M4OSA_NULL");
132 
133     pVersionInfo->m_major       = M4PTO3GPP_VERSION_MAJOR;
134     pVersionInfo->m_minor       = M4PTO3GPP_VERSION_MINOR;
135     pVersionInfo->m_revision    = M4PTO3GPP_VERSION_REVISION;
136 
137     return M4NO_ERROR;
138 }
139 
140 /**
141  ******************************************************************************
142  * M4OSA_ERR M4PTO3GPP_Init(M4PTO3GPP_Context* pContext);
143  * @brief   Initializes the M4PTO3GPP (allocates an execution context).
144  * @note
145  * @param   pContext            (OUT) Pointer on the M4PTO3GPP context to allocate
146  * @param   pFileReadPtrFct     (IN) Pointer to OSAL file reader functions
147  * @param   pFileWritePtrFct    (IN) Pointer to OSAL file writer functions
148  * @return  M4NO_ERROR:         No error
149  * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (If Debug Level >= 2)
150  * @return  M4ERR_ALLOC:        There is no more available memory
151  ******************************************************************************
152 */
153 /*********************************************************/
M4PTO3GPP_Init(M4PTO3GPP_Context * pContext,M4OSA_FileReadPointer * pFileReadPtrFct,M4OSA_FileWriterPointer * pFileWritePtrFct)154 M4OSA_ERR M4PTO3GPP_Init(   M4PTO3GPP_Context* pContext,
155                             M4OSA_FileReadPointer* pFileReadPtrFct,
156                             M4OSA_FileWriterPointer* pFileWritePtrFct)
157 /*********************************************************/
158 {
159     M4PTO3GPP_InternalContext *pC;
160     M4OSA_UInt32 i;
161 
162     M4OSA_TRACE3_1("M4PTO3GPP_Init called with pContext=0x%x", pContext);
163 
164     /**
165      *  Check input parameters */
166     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
167             "M4PTO3GPP_Init: pContext is M4OSA_NULL");
168 
169     /**
170      *  Allocate the M4PTO3GPP context and return it to the user */
171     pC = (M4PTO3GPP_InternalContext*)M4OSA_32bitAlignedMalloc(sizeof(M4PTO3GPP_InternalContext), M4PTO3GPP,
172         (M4OSA_Char *)"M4PTO3GPP_InternalContext");
173     *pContext = pC;
174     if (M4OSA_NULL == pC)
175     {
176         M4OSA_TRACE1_0("M4PTO3GPP_Step(): unable to allocate M4PTO3GPP_InternalContext,\
177                        returning M4ERR_ALLOC");
178         return M4ERR_ALLOC;
179     }
180 
181     /**
182      *  Init the context. All pointers must be initialized to M4OSA_NULL because CleanUp()
183         can be called just after Init(). */
184     pC->m_State = M4PTO3GPP_kState_CREATED;
185     pC->m_VideoState = M4PTO3GPP_kStreamState_NOSTREAM;
186     pC->m_AudioState = M4PTO3GPP_kStreamState_NOSTREAM;
187 
188     /**
189      *  Reader stuff */
190     pC->m_pReaderAudioAU        = M4OSA_NULL;
191     pC->m_pReaderAudioStream    = M4OSA_NULL;
192 
193     /**
194      *  Writer stuff */
195     pC->m_pEncoderHeader        = M4OSA_NULL;
196     pC->m_pWriterVideoStream    = M4OSA_NULL;
197     pC->m_pWriterAudioStream    = M4OSA_NULL;
198     pC->m_pWriterVideoStreamInfo= M4OSA_NULL;
199     pC->m_pWriterAudioStreamInfo= M4OSA_NULL;
200 
201     /**
202      *  Contexts of the used modules  */
203     pC->m_pAudioReaderContext    = M4OSA_NULL;
204     pC->m_p3gpWriterContext  = M4OSA_NULL;
205     pC->m_pMp4EncoderContext = M4OSA_NULL;
206     pC->m_eEncoderState = M4PTO3GPP_kNoEncoder;
207 
208     /**
209      *  Interfaces of the used modules */
210     pC->m_pReaderGlobInt    = M4OSA_NULL;
211     pC->m_pReaderDataInt    = M4OSA_NULL;
212     pC->m_pWriterGlobInt    = M4OSA_NULL;
213     pC->m_pWriterDataInt    = M4OSA_NULL;
214     pC->m_pEncoderInt       = M4OSA_NULL;
215     pC->m_pEncoderExternalAPI = M4OSA_NULL;
216     pC->m_pEncoderUserData = M4OSA_NULL;
217 
218     /**
219      * Fill the OSAL file function set */
220     pC->pOsalFileRead = pFileReadPtrFct;
221     pC->pOsalFileWrite = pFileWritePtrFct;
222 
223     /**
224      *  Video rate control stuff */
225     pC->m_mtCts             = 0.0F;
226     pC->m_mtNextCts         = 0.0F;
227     pC->m_mtAudioCts        = 0.0F;
228     pC->m_AudioOffSet       = 0.0F;
229     pC->m_dLastVideoRegulCts= 0.0F;
230     pC->m_PrevAudioCts      = 0.0F;
231     pC->m_DeltaAudioCts     = 0.0F;
232 
233     pC->m_MaxFileSize       = 0;
234     pC->m_CurrentFileSize   = 0;
235 
236     pC->m_IsLastPicture         = M4OSA_FALSE;
237     pC->m_bAudioPaddingSilence  = M4OSA_FALSE;
238     pC->m_bLastInternalCallBack = M4OSA_FALSE;
239     pC->m_NbCurrentFrame        = 0;
240 
241     pC->pSavedPlane = M4OSA_NULL;
242     pC->uiSavedDuration = 0;
243 
244     M4OSA_TRACE3_0("M4PTO3GPP_Init(): returning M4NO_ERROR");
245     return M4NO_ERROR;
246 }
247 
248 /**
249  ******************************************************************************
250  * M4OSA_ERR M4PTO3GPP_Open(M4PTO3GPP_Context pContext, M4PTO3GPP_Params* pParams);
251  * @brief   Set the M4PTO3GPP input and output files.
252  * @note    It opens the input file, but the output file may not be created yet.
253  * @param   pContext            (IN) M4PTO3GPP context
254  * @param   pParams             (IN) Pointer to the parameters for the PTO3GPP.
255  * @note    The pointed structure can be de-allocated after this function returns because
256  *          it is internally copied by the PTO3GPP
257  * @return  M4NO_ERROR:         No error
258  * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
259  * @return  M4ERR_STATE:        M4PTO3GPP is not in an appropriate state for this function to be
260                                  called
261  * @return  M4ERR_ALLOC:        There is no more available memory
262  * @return  ERR_PTO3GPP_INVALID_VIDEO_FRAME_SIZE_FOR_H263 The output video frame
263  *                              size parameter is incompatible with H263 encoding
264  * @return  ERR_PTO3GPP_UNDEFINED_OUTPUT_VIDEO_FORMAT       The output video format
265                                                             parameter is undefined
266  * @return  ERR_PTO3GPP_UNDEFINED_OUTPUT_VIDEO_BITRATE      The output video bit-rate parameter
267                                                             is undefined
268  * @return  ERR_PTO3GPP_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE   The output video frame size parameter
269                                                             is undefined
270  * @return  ERR_PTO3GPP_UNDEFINED_OUTPUT_FILE_SIZE          The output file size parameter
271                                                             is undefined
272  * @return  ERR_PTO3GPP_UNDEFINED_AUDIO_PADDING             The output audio padding parameter
273                                                             is undefined
274  * @return  ERR_PTO3GPP_UNHANDLED_AUDIO_TRACK_INPUT_FILE    The input audio file contains
275                                                             a track format not handled by PTO3GPP
276  ******************************************************************************
277 */
278 /*********************************************************/
M4PTO3GPP_Open(M4PTO3GPP_Context pContext,M4PTO3GPP_Params * pParams)279 M4OSA_ERR M4PTO3GPP_Open(M4PTO3GPP_Context pContext, M4PTO3GPP_Params* pParams)
280 /*********************************************************/
281 {
282     M4PTO3GPP_InternalContext   *pC = (M4PTO3GPP_InternalContext*)(pContext);
283     M4OSA_ERR                   err = M4NO_ERROR;
284 
285     M4READER_MediaFamily    mediaFamily;
286     M4_StreamHandler*       pStreamHandler;
287     M4READER_MediaType      readerMediaType;
288 
289     M4OSA_TRACE2_2("M4PTO3GPP_Open called with pContext=0x%x, pParams=0x%x", pContext, pParams);
290 
291     /**
292      *  Check input parameters */
293     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, \
294                     "M4PTO3GPP_Open: pContext is M4OSA_NULL");
295     M4OSA_DEBUG_IF2((M4OSA_NULL == pParams),  M4ERR_PARAMETER, \
296                     "M4PTO3GPP_Open: pParams is M4OSA_NULL");
297 
298     /**
299      *  Check parameters correctness */
300     M4OSA_DEBUG_IF2((M4OSA_NULL == pParams->pPictureCallbackFct),
301                M4ERR_PARAMETER, "M4PTO3GPP_Open: pC->m_Params.pPictureCallbackFct is M4OSA_NULL");
302     M4OSA_DEBUG_IF2((M4OSA_NULL == pParams->pPictureCallbackCtxt),
303                 M4ERR_PARAMETER,
304                  "M4PTO3GPP_Open: pC->m_Params.pPictureCallbackCtxt is M4OSA_NULL");
305     M4OSA_DEBUG_IF2((M4OSA_NULL == pParams->pOutput3gppFile),
306                 M4ERR_PARAMETER, "M4PTO3GPP_Open: pC->m_Params.pOutput3gppFile is M4OSA_NULL");
307     M4OSA_DEBUG_IF2((M4OSA_NULL == pParams->pTemporaryFile),
308                 M4ERR_PARAMETER, "M4PTO3GPP_Open: pC->m_Params.pTemporaryFile is M4OSA_NULL");
309 
310     /**
311      * Video Format */
312     if( (M4VIDEOEDITING_kH263 != pParams->OutputVideoFormat) &&
313         (M4VIDEOEDITING_kMPEG4 != pParams->OutputVideoFormat) &&
314         (M4VIDEOEDITING_kH264 != pParams->OutputVideoFormat)) {
315         M4OSA_TRACE1_0("M4PTO3GPP_Open: Undefined output video format");
316         return ERR_PTO3GPP_UNDEFINED_OUTPUT_VIDEO_FORMAT;
317      }
318 
319      /**
320      * Video Bitrate */
321     if(!((M4VIDEOEDITING_k16_KBPS       == pParams->OutputVideoBitrate) ||
322          (M4VIDEOEDITING_k24_KBPS       == pParams->OutputVideoBitrate) ||
323          (M4VIDEOEDITING_k32_KBPS       == pParams->OutputVideoBitrate) ||
324          (M4VIDEOEDITING_k48_KBPS       == pParams->OutputVideoBitrate) ||
325          (M4VIDEOEDITING_k64_KBPS       == pParams->OutputVideoBitrate) ||
326          (M4VIDEOEDITING_k96_KBPS       == pParams->OutputVideoBitrate) ||
327          (M4VIDEOEDITING_k128_KBPS      == pParams->OutputVideoBitrate) ||
328          (M4VIDEOEDITING_k192_KBPS      == pParams->OutputVideoBitrate) ||
329          (M4VIDEOEDITING_k256_KBPS      == pParams->OutputVideoBitrate) ||
330          (M4VIDEOEDITING_k288_KBPS      == pParams->OutputVideoBitrate) ||
331          (M4VIDEOEDITING_k384_KBPS      == pParams->OutputVideoBitrate) ||
332          (M4VIDEOEDITING_k512_KBPS      == pParams->OutputVideoBitrate) ||
333          (M4VIDEOEDITING_k800_KBPS      == pParams->OutputVideoBitrate) ||
334          /*+ New Encoder bitrates */
335          (M4VIDEOEDITING_k2_MBPS        == pParams->OutputVideoBitrate) ||
336          (M4VIDEOEDITING_k5_MBPS        == pParams->OutputVideoBitrate) ||
337          (M4VIDEOEDITING_k8_MBPS        == pParams->OutputVideoBitrate) ||
338          (M4VIDEOEDITING_kVARIABLE_KBPS == pParams->OutputVideoBitrate))) {
339         M4OSA_TRACE1_0("M4PTO3GPP_Open: Undefined output video bitrate");
340         return ERR_PTO3GPP_UNDEFINED_OUTPUT_VIDEO_BITRATE;
341     }
342 
343     /**
344      * Video frame size */
345     if (!((M4VIDEOEDITING_kSQCIF == pParams->OutputVideoFrameSize) ||
346           (M4VIDEOEDITING_kQQVGA == pParams->OutputVideoFrameSize) ||
347           (M4VIDEOEDITING_kQCIF == pParams->OutputVideoFrameSize) ||
348           (M4VIDEOEDITING_kQVGA == pParams->OutputVideoFrameSize) ||
349           (M4VIDEOEDITING_kCIF  == pParams->OutputVideoFrameSize) ||
350           (M4VIDEOEDITING_kVGA  == pParams->OutputVideoFrameSize) ||
351 
352           (M4VIDEOEDITING_kNTSC == pParams->OutputVideoFrameSize) ||
353           (M4VIDEOEDITING_kWVGA == pParams->OutputVideoFrameSize) ||
354 
355           (M4VIDEOEDITING_k640_360 == pParams->OutputVideoFrameSize) ||
356           (M4VIDEOEDITING_k854_480 == pParams->OutputVideoFrameSize) ||
357           (M4VIDEOEDITING_k1280_720 == pParams->OutputVideoFrameSize) ||
358           (M4VIDEOEDITING_k1080_720 == pParams->OutputVideoFrameSize) ||
359           (M4VIDEOEDITING_k960_720 == pParams->OutputVideoFrameSize) ||
360           (M4VIDEOEDITING_k1920_1080 == pParams->OutputVideoFrameSize))) {
361         M4OSA_TRACE1_0("M4PTO3GPP_Open: Undefined output video frame size");
362         return ERR_PTO3GPP_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE;
363     }
364 
365     /**
366      * Maximum size of the output 3GPP file */
367     if (!((M4PTO3GPP_k50_KB     == pParams->OutputFileMaxSize) ||
368           (M4PTO3GPP_k75_KB     == pParams->OutputFileMaxSize) ||
369           (M4PTO3GPP_k100_KB    == pParams->OutputFileMaxSize) ||
370           (M4PTO3GPP_k150_KB    == pParams->OutputFileMaxSize) ||
371           (M4PTO3GPP_k200_KB    == pParams->OutputFileMaxSize) ||
372           (M4PTO3GPP_k300_KB    == pParams->OutputFileMaxSize) ||
373           (M4PTO3GPP_k400_KB    == pParams->OutputFileMaxSize) ||
374           (M4PTO3GPP_k500_KB    == pParams->OutputFileMaxSize) ||
375           (M4PTO3GPP_kUNLIMITED == pParams->OutputFileMaxSize))) {
376         M4OSA_TRACE1_0("M4PTO3GPP_Open: Undefined output 3GPP file size");
377         return ERR_PTO3GPP_UNDEFINED_OUTPUT_FILE_SIZE;
378     }
379 
380     /* Audio padding */
381     if (M4OSA_NULL != pParams->pInputAudioTrackFile) {
382         if ((!( (M4PTO3GPP_kAudioPaddingMode_None   == pParams->AudioPaddingMode) ||
383                 (M4PTO3GPP_kAudioPaddingMode_Silence== pParams->AudioPaddingMode) ||
384                 (M4PTO3GPP_kAudioPaddingMode_Loop   == pParams->AudioPaddingMode)))) {
385             M4OSA_TRACE1_0("M4PTO3GPP_Open: Undefined audio padding");
386             return ERR_PTO3GPP_UNDEFINED_AUDIO_PADDING;
387         }
388     }
389 
390     /**< Size check for H263 (only valid sizes are CIF, QCIF and SQCIF) */
391     if ((M4VIDEOEDITING_kH263 == pParams->OutputVideoFormat) &&
392         (M4VIDEOEDITING_kSQCIF != pParams->OutputVideoFrameSize) &&
393         (M4VIDEOEDITING_kQCIF != pParams->OutputVideoFrameSize) &&
394         (M4VIDEOEDITING_kCIF != pParams->OutputVideoFrameSize)) {
395         M4OSA_TRACE1_0("M4PTO3GPP_Open():\
396              returning ERR_PTO3GPP_INVALID_VIDEO_FRAME_SIZE_FOR_H263");
397         return ERR_PTO3GPP_INVALID_VIDEO_FRAME_SIZE_FOR_H263;
398     }
399 
400     /**
401      *  Check state automaton */
402     if (M4PTO3GPP_kState_CREATED != pC->m_State) {
403         M4OSA_TRACE1_1("M4PTO3GPP_Open(): Wrong State (%d), returning M4ERR_STATE", pC->m_State);
404         return M4ERR_STATE;
405     }
406 
407     /**
408      * Copy the M4PTO3GPP_Params structure */
409     memcpy((void *)(&pC->m_Params),
410                 (void *)pParams, sizeof(M4PTO3GPP_Params));
411     M4OSA_TRACE1_1("M4PTO3GPP_Open: outputVideoBitrate = %d", pC->m_Params.OutputVideoBitrate);
412 
413     /***********************************/
414     /* Open input file with the reader */
415     /***********************************/
416     if (M4OSA_NULL != pC->m_Params.pInputAudioTrackFile) {
417         /**
418          * Get the reader interface according to the input audio file type */
419         switch(pC->m_Params.AudioFileFormat)
420         {
421 #ifdef M4VSS_SUPPORT_READER_AMR
422         case M4VIDEOEDITING_kFileType_AMR:
423         err = M4READER_AMR_getInterfaces( &readerMediaType, &pC->m_pReaderGlobInt,
424                 &pC->m_pReaderDataInt);
425         if (M4NO_ERROR != err)
426         {
427             M4OSA_TRACE1_1("M4PTO3GPP_Open(): M4READER_AMR_getInterfaces returns 0x%x", err);
428             return err;
429         }
430             break;
431 #endif
432 
433 #ifdef AAC_SUPPORTED
434         case M4VIDEOEDITING_kFileType_3GPP:
435             err = M4READER_3GP_getInterfaces( &readerMediaType, &pC->m_pReaderGlobInt,
436                     &pC->m_pReaderDataInt);
437             if (M4NO_ERROR != err)
438             {
439                 M4OSA_TRACE1_1("M4PTO3GPP_Open(): M4READER_3GP_getInterfaces returns 0x%x", err);
440                 return err;
441             }
442             break;
443 #endif
444 
445         default:
446             return ERR_PTO3GPP_UNHANDLED_AUDIO_TRACK_INPUT_FILE;
447         }
448 
449         /**
450          *  Initializes the reader shell */
451         err = pC->m_pReaderGlobInt->m_pFctCreate(&pC->m_pAudioReaderContext);
452         if (M4NO_ERROR != err)
453         {
454             M4OSA_TRACE1_1("M4PTO3GPP_Open(): pReaderGlobInt->m_pFctCreate returns 0x%x", err);
455             return err;
456         }
457 
458         pC->m_pReaderDataInt->m_readerContext = pC->m_pAudioReaderContext;
459         /**< Link the reader interface to the reader context */
460 
461         /**
462          *  Set the reader shell file access functions */
463         err = pC->m_pReaderGlobInt->m_pFctSetOption(pC->m_pAudioReaderContext,
464             M4READER_kOptionID_SetOsaFileReaderFctsPtr,  (M4OSA_DataOption)pC->pOsalFileRead);
465         if (M4NO_ERROR != err)
466         {
467             M4OSA_TRACE1_1("M4PTO3GPP_Open(): pReaderGlobInt->m_pFctSetOption returns 0x%x", err);
468             return err;
469         }
470 
471         /**
472          *  Open the input audio file */
473         err = pC->m_pReaderGlobInt->m_pFctOpen(pC->m_pAudioReaderContext,
474             pC->m_Params.pInputAudioTrackFile);
475         if (M4NO_ERROR != err)
476         {
477             M4OSA_TRACE1_1("M4PTO3GPP_Open(): pReaderGlobInt->m_pFctOpen returns 0x%x", err);
478             pC->m_pReaderGlobInt->m_pFctDestroy(pC->m_pAudioReaderContext);
479             pC->m_pAudioReaderContext = M4OSA_NULL;
480             return err;
481         }
482 
483         /**
484          *  Get the audio streams from the input file */
485         err = M4NO_ERROR;
486         while (M4NO_ERROR == err)
487         {
488             err = pC->m_pReaderGlobInt->m_pFctGetNextStream(pC->m_pAudioReaderContext,
489                 &mediaFamily, &pStreamHandler);
490 
491             if((err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE)) ||
492                    (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS)))
493             {
494                 err = M4NO_ERROR;
495                 continue;
496             }
497 
498             if (M4NO_ERROR == err) /**< One stream found */
499             {
500                 /**< Found an audio stream */
501                 if ((M4READER_kMediaFamilyAudio == mediaFamily)
502                     && (M4OSA_NULL == pC->m_pReaderAudioStream))
503                 {
504                     pC->m_pReaderAudioStream = (M4_AudioStreamHandler*)pStreamHandler;
505                     /**< Keep pointer to the audio stream */
506                     M4OSA_TRACE3_0("M4PTO3GPP_Open(): Found an audio stream in input");
507                     pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
508 
509                     /**
510                      *  Allocate audio AU used for read operations */
511                     pC->m_pReaderAudioAU = (M4_AccessUnit*)M4OSA_32bitAlignedMalloc(sizeof(M4_AccessUnit),
512                         M4PTO3GPP,(M4OSA_Char *)"pReaderAudioAU");
513                     if (M4OSA_NULL == pC->m_pReaderAudioAU)
514                     {
515                         M4OSA_TRACE1_0("M4PTO3GPP_Open(): unable to allocate pReaderAudioAU, \
516                                        returning M4ERR_ALLOC");
517                         return M4ERR_ALLOC;
518                     }
519 
520                     /**
521                      *  Initializes an access Unit */
522                     err = pC->m_pReaderGlobInt->m_pFctFillAuStruct(pC->m_pAudioReaderContext,
523                             pStreamHandler, pC->m_pReaderAudioAU);
524                     if (M4NO_ERROR != err)
525                     {
526                         M4OSA_TRACE1_1("M4PTO3GPP_Open():\
527                          pReaderGlobInt->m_pFctFillAuStruct(audio)returns 0x%x", err);
528                         return err;
529                     }
530                 }
531                 else
532                 {
533                     pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
534                 }
535             }
536             else if (M4WAR_NO_MORE_STREAM != err) /**< Unexpected error code */
537             {
538                 M4OSA_TRACE1_1("M4PTO3GPP_Open():\
539                      pReaderGlobInt->m_pFctGetNextStream returns 0x%x",
540                     err);
541                 return err;
542             }
543         } /* while*/
544     } /*if (M4OSA_NULL != pC->m_Params.pInputAudioTrackFile)*/
545 
546     pC->m_VideoState = M4PTO3GPP_kStreamState_STARTED;
547 
548     /**
549      * Init the audio stream */
550     if (M4OSA_NULL != pC->m_pReaderAudioStream)
551     {
552         pC->m_AudioState = M4PTO3GPP_kStreamState_STARTED;
553         err = pC->m_pReaderGlobInt->m_pFctReset(pC->m_pAudioReaderContext,
554             (M4_StreamHandler*)pC->m_pReaderAudioStream);
555         if (M4NO_ERROR != err)
556         {
557             M4OSA_TRACE1_1("M4PTO3GPP_Open(): pReaderDataInt->m_pFctReset(audio returns 0x%x",
558                  err);
559             return err;
560         }
561     }
562 
563     /**
564      *  Update state automaton */
565     pC->m_State = M4PTO3GPP_kState_OPENED;
566 
567     /**
568      * Get the max File size */
569     switch(pC->m_Params.OutputFileMaxSize)
570     {
571     case M4PTO3GPP_k50_KB:  pC->m_MaxFileSize = 50000;  break;
572     case M4PTO3GPP_k75_KB:  pC->m_MaxFileSize = 75000;  break;
573     case M4PTO3GPP_k100_KB: pC->m_MaxFileSize = 100000; break;
574     case M4PTO3GPP_k150_KB: pC->m_MaxFileSize = 150000; break;
575     case M4PTO3GPP_k200_KB: pC->m_MaxFileSize = 200000; break;
576     case M4PTO3GPP_k300_KB: pC->m_MaxFileSize = 300000; break;
577     case M4PTO3GPP_k400_KB: pC->m_MaxFileSize = 400000; break;
578     case M4PTO3GPP_k500_KB: pC->m_MaxFileSize = 500000; break;
579     case M4PTO3GPP_kUNLIMITED:
580     default:                                            break;
581     }
582 
583     M4OSA_TRACE3_0("M4PTO3GPP_Open(): returning M4NO_ERROR");
584     return M4NO_ERROR;
585 }
586 
587 /**
588  ******************************************************************************
589  * M4OSA_ERR M4PTO3GPP_Step(M4PTO3GPP_Context pContext);
590  * @brief   Perform one step of trancoding.
591  * @note
592  * @param   pContext            (IN) M4PTO3GPP context
593  * @return  M4NO_ERROR          No error
594  * @return  M4ERR_PARAMETER     pContext is M4OSA_NULL
595  * @return  M4ERR_STATE:    M4PTO3GPP is not in an appropriate state for this function
596  *                           to be called
597  * @return  M4PTO3GPP_WAR_END_OF_PROCESSING Encoding completed
598  ******************************************************************************
599 */
600 /*********************************************************/
M4PTO3GPP_Step(M4PTO3GPP_Context pContext)601 M4OSA_ERR M4PTO3GPP_Step(M4PTO3GPP_Context pContext)
602 /*********************************************************/
603 {
604     M4PTO3GPP_InternalContext *pC = (M4PTO3GPP_InternalContext*)(pContext);
605     M4OSA_ERR err = M4NO_ERROR;
606     M4OSA_UInt32 l_uiAudioStepCount = 0;
607     M4OSA_Int32  JumpToTime = 0;
608     M4OSA_Time  mtIncCts;
609 
610     /**
611      *  Check input parameters */
612     M4OSA_DEBUG_IF2((M4OSA_NULL==pContext), M4ERR_PARAMETER,
613                 "M4PTO3GPP_Step: pContext is M4OSA_NULL");
614 
615     /**
616      *  Check state automaton */
617     if ( !((M4PTO3GPP_kState_OPENED == pC->m_State) || (M4PTO3GPP_kState_READY == pC->m_State)) )
618     {
619         M4OSA_TRACE1_1("M4PTO3GPP_Step(): Wrong State (%d), returning M4ERR_STATE", pC->m_State);
620         return M4ERR_STATE;
621     }
622 
623     /******************************************************************/
624     /**
625      *  In case this is the first step, we prepare the decoder, the encoder and the writer */
626     if (M4PTO3GPP_kState_OPENED == pC->m_State)
627     {
628         M4OSA_TRACE2_0("M4PTO3GPP_Step(): This is the first step, \
629                        calling M4PTO3GPP_Ready4Processing");
630 
631         /**
632          *  Prepare the reader, the decoder, the encoder, the writer... */
633         err = M4PTO3GPP_Ready4Processing(pC);
634         if (M4NO_ERROR != err)
635         {
636             M4OSA_TRACE1_1("M4PTO3GPP_Step(): M4PTO3GPP_Ready4Processing() returns 0x%x", err);
637             return err;
638         }
639 
640         /**
641          *  Update state automaton */
642         pC->m_State = M4PTO3GPP_kState_READY;
643 
644         M4OSA_TRACE3_0("M4PTO3GPP_Step(): returning M4NO_ERROR (a)");
645         return M4NO_ERROR; /**< we only do that in the first step, \
646                            first REAL step will be the next one */
647     }
648 
649 
650     /*
651      * Check if we reached the targeted file size.
652      * We do that before the encoding, because the core encoder has to know if this is
653      * the last frame to encode */
654     err = pC->m_pWriterGlobInt->pFctGetOption(pC->m_p3gpWriterContext,
655         M4WRITER_kFileSizeAudioEstimated, (M4OSA_DataOption) &pC->m_CurrentFileSize);
656     if ((0 != pC->m_MaxFileSize) &&
657         /**< Add a marge to the file size in order to never exceed the max file size */
658        ((pC->m_CurrentFileSize + M4PTO3GPP_MARGE_OF_FILE_SIZE) >= pC->m_MaxFileSize))
659     {
660         pC->m_IsLastPicture = M4OSA_TRUE;
661     }
662 
663     /******************************************************************
664     *  At that point we are in M4PTO3GPP_kState_READY state
665     *  We perform one step of video encoding
666     ******************************************************************/
667 
668     /************* VIDEO ENCODING ***************/
669     if (M4PTO3GPP_kStreamState_STARTED == pC->m_VideoState) /**<If the video encoding is going on*/
670     {   /**
671          * Call the encoder  */
672         pC->m_NbCurrentFrame++;
673 
674         /* Check if it is the last frame the to encode */
675         if((pC->m_Params.NbVideoFrames > 0) \
676             && (pC->m_NbCurrentFrame >= pC->m_Params.NbVideoFrames))
677         {
678             pC->m_IsLastPicture = M4OSA_TRUE;
679         }
680 
681         M4OSA_TRACE2_2("M4PTO3GPP_Step(): Calling pEncoderInt->pFctEncode with videoCts = %.2f\
682                        nb = %lu", pC->m_mtCts, pC->m_NbCurrentFrame);
683 
684         err = pC->m_pEncoderInt->pFctEncode(pC->m_pMp4EncoderContext, M4OSA_NULL,
685             /**< The input plane is null because the input Picture will be obtained by the\
686             VPP filter from the context */
687                                         pC->m_mtCts,
688                                         (pC->m_IsLastPicture ?
689                                         M4ENCODER_kLastFrame : M4ENCODER_kNormalFrame) );
690         /**< Last param set to M4OSA_TRUE signals that this is the last frame to be encoded,\
691         M4OSA_FALSE else */
692 
693         M4OSA_TRACE3_2("M4PTO3GPP_Step(): pEncoderInt->pFctEncode returns 0x%x, vidFormat =0x%x",
694             err, pC->m_Params.OutputVideoFormat);
695         if((M4NO_ERROR == err) && (M4VIDEOEDITING_kH264 == pC->m_Params.OutputVideoFormat))
696         {
697             /* Check if last frame.*
698             *                  */
699             if(M4OSA_TRUE == pC->m_IsLastPicture)
700             {
701                 M4OSA_TRACE3_0("M4PTO3GPP_Step(): Last picture");
702                 pC->m_VideoState = M4PTO3GPP_kStreamState_FINISHED;
703             }
704 
705         }
706 
707         if (M4WAR_NO_MORE_AU == err) /**< The video encoding is finished */
708         {
709             M4OSA_TRACE3_0("M4PTO3GPP_Step(): pEncoderInt->pFctEncode returns M4WAR_NO_MORE_AU");
710             pC->m_VideoState = M4PTO3GPP_kStreamState_FINISHED;
711         }
712         else if (M4NO_ERROR != err)     /**< Unexpected error code */
713         {
714             if( (((M4OSA_UInt32)M4WAR_WRITER_STOP_REQ) == err) ||
715                     (((M4OSA_UInt32)M4ERR_ALLOC) == err) )
716             {
717                 M4OSA_TRACE1_0("M4PTO3GPP_Step: returning ERR_PTO3GPP_ENCODER_ACCES_UNIT_ERROR");
718                 return ERR_PTO3GPP_ENCODER_ACCES_UNIT_ERROR;
719             }
720             else
721             {
722                 M4OSA_TRACE1_1("M4PTO3GPP_Step(): pEncoderInt->pFctEncode(last) (a) returns 0x%x",
723                     err);
724                 return err;
725             }
726         }
727     } /**< End of video encoding */
728 
729 
730     /****** AUDIO TRANSCODING (read + null encoding + write) ******/
731     if (M4PTO3GPP_kStreamState_STARTED == pC->m_AudioState)
732     {
733         while ( (M4PTO3GPP_kStreamState_STARTED == pC->m_AudioState) &&
734                 (pC->m_mtAudioCts < pC->m_mtNextCts))
735 
736         {
737             l_uiAudioStepCount++;
738             if (M4OSA_FALSE == pC->m_bAudioPaddingSilence)
739             {
740                 /**< Read the next audio AU in the input Audio file */
741                 err = pC->m_pReaderDataInt->m_pFctGetNextAu(pC->m_pAudioReaderContext,
742                     (M4_StreamHandler*)pC->m_pReaderAudioStream, pC->m_pReaderAudioAU);
743                 pC->m_mtAudioCts = pC->m_pReaderAudioAU->m_CTS + pC->m_AudioOffSet;
744 
745                 if (M4WAR_NO_MORE_AU == err)    /* The audio transcoding is finished */
746                 {
747                     M4OSA_TRACE2_0("M4PTO3GPP_Step():\
748                                   pReaderDataInt->m_pFctGetNextAu(audio) returns \
749                                     M4WAR_NO_MORE_AU");
750                     switch(pC->m_Params.AudioPaddingMode)
751                     {
752                         case M4PTO3GPP_kAudioPaddingMode_None:
753 
754                             pC->m_AudioState = M4PTO3GPP_kStreamState_FINISHED;
755                             break;
756 
757                         case M4PTO3GPP_kAudioPaddingMode_Silence:
758 
759                             if (M4DA_StreamTypeAudioAmrNarrowBand
760                                 != pC->m_pReaderAudioStream->m_basicProperties.m_streamType)
761                                 /**< Do nothing if the input audio file format is not AMR */
762                             {
763                                 pC->m_AudioState = M4PTO3GPP_kStreamState_FINISHED;
764                             }
765                             else
766                             {
767                                 pC->m_bAudioPaddingSilence = M4OSA_TRUE;
768                             }
769                             break;
770 
771                         case M4PTO3GPP_kAudioPaddingMode_Loop:
772 
773                             /**< Jump to the beginning of the audio file */
774                             err = pC->m_pReaderGlobInt->m_pFctJump(pC->m_pAudioReaderContext,
775                                 (M4_StreamHandler*)pC->m_pReaderAudioStream, &JumpToTime);
776 
777                             if (M4NO_ERROR != err)
778                             {
779                                 M4OSA_TRACE1_1("M4PTO3GPP_Step(): \
780                                               pReaderDataInt->m_pFctReset(audio returns 0x%x",
781                                                err);
782                                 return err;
783                             }
784 
785                             if (M4DA_StreamTypeAudioAmrNarrowBand
786                                 == pC->m_pReaderAudioStream->m_basicProperties.m_streamType)
787                             {
788                                 pC->m_mtAudioCts += 20; /*< SEMC bug fixed at Lund */
789                                 pC->m_AudioOffSet = pC->m_mtAudioCts;
790 
791                                 /**
792                                  * 'BZZZ' bug fix:
793                                  * add a silence frame */
794                                 mtIncCts = (M4OSA_Time)((pC->m_mtAudioCts) *
795                                     (pC->m_pWriterAudioStream->timeScale / 1000.0));
796                                 err = M4PTO3GPP_writeAmrSilence122Frame(pC->m_pWriterDataInt,
797                                     pC->m_p3gpWriterContext, &pC->m_WriterAudioAU, mtIncCts);
798 
799                                 if (M4NO_ERROR != err)
800                                 {
801                                     M4OSA_TRACE1_1("M4PTO3GPP_Step(): \
802                                                    M4PTO3GPP_AddAmrSilenceSid returns 0x%x", err);
803                                     return err;
804                                 }/**< Add => no audio cts increment...*/
805                             }
806                             else
807                             {
808                                 pC->m_AudioOffSet = pC->m_mtAudioCts + pC->m_DeltaAudioCts;
809                             }
810                             break;
811                     } /* end of: switch */
812                 }
813                 else if (M4NO_ERROR != err)
814                 {
815                     M4OSA_TRACE1_1("M4PTO3GPP_Step(): pReaderDataInt->m_pFctGetNextAu(Audio)\
816                                    returns 0x%x", err);
817                     return err;
818                 }
819                 else
820                 {
821                     /**
822                      * Save the delta Cts (AAC only) */
823                     pC->m_DeltaAudioCts = pC->m_pReaderAudioAU->m_CTS - pC->m_PrevAudioCts;
824                     pC->m_PrevAudioCts  = pC->m_pReaderAudioAU->m_CTS;
825 
826                     /**
827                      *  Prepare the writer AU */
828                     err = pC->m_pWriterDataInt->pStartAU(pC->m_p3gpWriterContext, 1,
829                         &pC->m_WriterAudioAU);
830                     if (M4NO_ERROR != err)
831                     {
832                         M4OSA_TRACE1_1("M4PTO3GPP_Step(): pWriterDataInt->pStartAU(Audio)\
833                                        returns 0x%x", err);
834                         return err;
835                     }
836 
837                     /**
838                      *  Copy audio data from reader AU to writer AU */
839                     M4OSA_TRACE2_1("M4PTO3GPP_Step(): Copying audio AU: size=%d",
840                         pC->m_pReaderAudioAU->m_size);
841                     memcpy((void *)pC->m_WriterAudioAU.dataAddress,
842                         (void *)pC->m_pReaderAudioAU->m_dataAddress,
843                         pC->m_pReaderAudioAU->m_size);
844                     pC->m_WriterAudioAU.size = pC->m_pReaderAudioAU->m_size;
845 
846                     /**
847                      *  Convert CTS unit from milliseconds to timescale */
848                     if (M4DA_StreamTypeAudioAmrNarrowBand
849                         != pC->m_pReaderAudioStream->m_basicProperties.m_streamType)
850                     {
851                         pC->m_WriterAudioAU.CTS  = (M4OSA_Time)
852                             ((pC->m_AudioOffSet + pC->m_pReaderAudioAU->m_CTS)
853                             * pC->m_pWriterAudioStream->timeScale / 1000.0);
854                     }
855                     else
856                     {
857                         pC->m_WriterAudioAU.CTS = (M4OSA_Time)(pC->m_mtAudioCts *
858                             (pC->m_pWriterAudioStream->timeScale / 1000.0));
859                     }
860                     pC->m_WriterAudioAU.nbFrag = 0;
861                     M4OSA_TRACE2_1("M4PTO3GPP_Step(): audio AU: CTS=%d ms", pC->m_mtAudioCts
862                         /*pC->m_pReaderAudioAU->m_CTS*/);
863 
864                     /**
865                      *  Write it to the output file */
866                     err = pC->m_pWriterDataInt->pProcessAU(pC->m_p3gpWriterContext, 1,
867                         &pC->m_WriterAudioAU);
868 
869                     if (M4NO_ERROR != err)
870                     {
871                         M4OSA_TRACE1_1("M4PTO3GPP_Step(): pWriterDataInt->pProcessAU(Audio)\
872                                        returns 0x%x", err);
873                         return err;
874                     }
875                 }
876             }
877             else /**< M4OSA_TRUE == pC->m_bAudioPaddingSilence */
878             {
879                 if (M4DA_StreamTypeAudioAmrNarrowBand ==
880                     pC->m_pReaderAudioStream->m_basicProperties.m_streamType)
881                 {
882                     /**
883                      * Fill in audio au with silence */
884                     pC->m_mtAudioCts += 20;
885 
886                     /**
887                      * Padd with silence */
888                     mtIncCts = (M4OSA_Time)(pC->m_mtAudioCts
889                         * (pC->m_pWriterAudioStream->timeScale / 1000.0));
890                     err = M4PTO3GPP_writeAmrSilence048Frame(pC->m_pWriterDataInt,
891                         pC->m_p3gpWriterContext, &pC->m_WriterAudioAU, mtIncCts);
892 
893                     if (M4NO_ERROR != err)
894                     {
895                         M4OSA_TRACE1_1("M4PTO3GPP_Step(): M4PTO3GPP_AddAmrSilenceSid returns 0x%x",
896                             err);
897                         return err;
898                     }
899                 }
900                 else /**< Do nothing if the input audio file format is not AMR */
901                 {
902                     pC->m_AudioState = M4PTO3GPP_kStreamState_FINISHED;
903                 }
904 
905             }
906         } /**< while */
907     } /**< End of audio encoding */
908 
909     pC->m_mtCts = pC->m_mtNextCts;
910 
911     /**
912      *  The transcoding is finished when no stream is being encoded anymore */
913     if (M4PTO3GPP_kStreamState_FINISHED == pC->m_VideoState)
914     {
915         pC->m_State = M4PTO3GPP_kState_FINISHED;
916         M4OSA_TRACE2_0("M4PTO3GPP_Step(): transcoding finished, returning M4WAR_NO_MORE_AU");
917         return M4PTO3GPP_WAR_END_OF_PROCESSING;
918     }
919 
920     M4OSA_TRACE3_0("M4PTO3GPP_Step(): returning M4NO_ERROR (b)");
921     return M4NO_ERROR;
922 }
923 
924 /**
925  ******************************************************************************
926  * M4OSA_ERR M4PTO3GPP_Close(M4PTO3GPP_Context pContext);
927  * @brief   Finish the M4PTO3GPP transcoding.
928  * @note    The output 3GPP file is ready to be played after this call
929  * @param   pContext            (IN) M4PTO3GPP context
930  * @return  M4NO_ERROR:         No error
931  * @return  M4ERR_PARAMETER:    pContext is M4OSA_NULL (If Debug Level >= 2)
932  * @return  M4ERR_STATE:    M4PTO3GPP is not in an appropriate state for this function to be called
933  ******************************************************************************
934 */
935 /*********************************************************/
M4PTO3GPP_Close(M4PTO3GPP_Context pContext)936 M4OSA_ERR M4PTO3GPP_Close(M4PTO3GPP_Context pContext)
937 /*********************************************************/
938 {
939     M4PTO3GPP_InternalContext *pC = (M4PTO3GPP_InternalContext*)(pContext);
940     M4OSA_ERR    osaErr = M4NO_ERROR;
941     M4OSA_UInt32 lastCTS;
942     M4ENCODER_Header* encHeader;
943     M4SYS_StreamIDmemAddr streamHeader;
944 
945     M4OSA_TRACE3_1("M4PTO3GPP_Close called with pContext=0x%x", pContext);
946 
947     /**
948      *  Check input parameters */
949     M4OSA_DEBUG_IF2((M4OSA_NULL==pContext), M4ERR_PARAMETER, "M4PTO3GPP_Close:\
950                                                              pContext is M4OSA_NULL");
951 
952     /* Check state automaton */
953     if ((pC->m_State != M4PTO3GPP_kState_OPENED) &&
954         (pC->m_State != M4PTO3GPP_kState_READY) &&
955         (pC->m_State != M4PTO3GPP_kState_FINISHED))
956     {
957         M4OSA_TRACE1_1("M4PTO3GPP_Close(): Wrong State (%d), returning M4ERR_STATE", pC->m_State);
958         return M4ERR_STATE;
959     }
960 
961     /*************************************/
962     /******** Finish the encoding ********/
963     /*************************************/
964     if (M4PTO3GPP_kState_READY == pC->m_State)
965     {
966         pC->m_State = M4PTO3GPP_kState_FINISHED;
967     }
968 
969     if (M4PTO3GPP_kEncoderRunning == pC->m_eEncoderState)
970     {
971         if (pC->m_pEncoderInt->pFctStop != M4OSA_NULL)
972         {
973             osaErr = pC->m_pEncoderInt->pFctStop(pC->m_pMp4EncoderContext);
974             if (M4NO_ERROR != osaErr)
975             {
976                 M4OSA_TRACE1_1("M4PTO3GPP_close: m_pEncoderInt->pFctStop returns 0x%x", osaErr);
977                 /* Well... how the heck do you handle a failed cleanup? */
978             }
979         }
980 
981         pC->m_eEncoderState = M4PTO3GPP_kEncoderStopped;
982     }
983 
984     /* Has the encoder actually been opened? Don't close it if that's not the case. */
985     if (M4PTO3GPP_kEncoderStopped == pC->m_eEncoderState)
986     {
987         osaErr = pC->m_pEncoderInt->pFctClose(pC->m_pMp4EncoderContext);
988         if (M4NO_ERROR != osaErr)
989         {
990             M4OSA_TRACE1_1("M4PTO3GPP_close: m_pEncoderInt->pFctClose returns 0x%x", osaErr);
991             /* Well... how the heck do you handle a failed cleanup? */
992         }
993 
994         pC->m_eEncoderState = M4PTO3GPP_kEncoderClosed;
995     }
996 
997     /*******************************/
998     /******** Close 3GP out ********/
999     /*******************************/
1000 
1001     if (M4OSA_NULL != pC->m_p3gpWriterContext)  /* happens in state _SET */
1002     {
1003         /* HW encoder: fetch the DSI from the shell video encoder, and feed it to the writer before
1004         closing it. */
1005         if ((M4VIDEOEDITING_kMPEG4 == pC->m_Params.OutputVideoFormat)
1006             || (M4VIDEOEDITING_kH264 == pC->m_Params.OutputVideoFormat))
1007         {
1008             osaErr = pC->m_pEncoderInt->pFctGetOption(pC->m_pMp4EncoderContext,
1009                 M4ENCODER_kOptionID_EncoderHeader,
1010                                                             (M4OSA_DataOption)&encHeader);
1011             if ( (M4NO_ERROR != osaErr) || (M4OSA_NULL == encHeader->pBuf) )
1012             {
1013                 M4OSA_TRACE1_1("M4PTO3GPP_close: failed to get the encoder header (err 0x%x)",
1014                     osaErr);
1015                 /**< no return here, we still have stuff to deallocate after close, even if \
1016                 it fails. */
1017             }
1018             else
1019             {
1020                 /* set this header in the writer */
1021                 streamHeader.streamID = M4PTO3GPP_WRITER_VIDEO_STREAM_ID;
1022                 streamHeader.size = encHeader->Size;
1023                 streamHeader.addr = (M4OSA_MemAddr32)encHeader->pBuf;
1024                 osaErr = pC->m_pWriterGlobInt->pFctSetOption(pC->m_p3gpWriterContext,
1025                     M4WRITER_kDSI, &streamHeader);
1026                 if (M4NO_ERROR != osaErr)
1027                 {
1028                     M4OSA_TRACE1_1("M4PTO3GPP_close: failed to set the DSI in the writer \
1029                                 (err 0x%x)   ", osaErr);
1030                 }
1031             }
1032         }
1033 
1034         /* Update last Video CTS */
1035         lastCTS = (M4OSA_UInt32)pC->m_mtCts;
1036 
1037         osaErr = pC->m_pWriterGlobInt->pFctSetOption(pC->m_p3gpWriterContext,
1038             (M4OSA_UInt32)M4WRITER_kMaxFileDuration, &lastCTS);
1039         if (M4NO_ERROR != osaErr)
1040         {
1041             M4OSA_TRACE1_1("M4PTO3GPP_Close: SetOption(M4WRITER_kMaxFileDuration) returns 0x%x",
1042                 osaErr);
1043         }
1044 
1045         /* Write and close the 3GP output file */
1046         osaErr = pC->m_pWriterGlobInt->pFctCloseWrite(pC->m_p3gpWriterContext);
1047         if (M4NO_ERROR != osaErr)
1048         {
1049             M4OSA_TRACE1_1("M4PTO3GPP_Close: pWriterGlobInt->pFctCloseWrite returns 0x%x", osaErr);
1050             /**< don't return yet, we have to close other things */
1051         }
1052         pC->m_p3gpWriterContext = M4OSA_NULL;
1053     }
1054 
1055     /**
1056      * State transition */
1057     pC->m_State = M4PTO3GPP_kState_CLOSED;
1058 
1059     M4OSA_TRACE3_1("M4PTO3GPP_Close(): returning 0x%x", osaErr);
1060     return osaErr;
1061 }
1062 
1063 
1064 /**
1065  ******************************************************************************
1066  * M4OSA_ERR M4PTO3GPP_CleanUp(M4PTO3GPP_Context pContext);
1067  * @brief   Free all resources used by the M4PTO3GPP.
1068  * @note    The context is no more valid after this call
1069  * @param   pContext            (IN) M4PTO3GPP context
1070  * @return  M4NO_ERROR:         No error
1071  * @return  M4ERR_PARAMETER:    pContext is M4OSA_NULL (If Debug Level >= 2)
1072  ******************************************************************************
1073 */
1074 /*********************************************************/
M4PTO3GPP_CleanUp(M4PTO3GPP_Context pContext)1075 M4OSA_ERR M4PTO3GPP_CleanUp(M4PTO3GPP_Context pContext)
1076 /*********************************************************/
1077 {
1078     M4OSA_ERR err = M4NO_ERROR;
1079     M4PTO3GPP_InternalContext *pC = (M4PTO3GPP_InternalContext*)(pContext);
1080 
1081     M4OSA_TRACE3_1("M4PTO3GPP_CleanUp called with pContext=0x%x", pContext);
1082 
1083     /**
1084      *  Check input parameters */
1085     M4OSA_DEBUG_IF2((M4OSA_NULL==pContext),M4ERR_PARAMETER, "M4PTO3GPP_CleanUp: pContext \
1086                                                             is M4OSA_NULL");
1087 
1088     /**
1089      *  First call Close, if needed, to clean the video encoder */
1090 
1091     if ((M4PTO3GPP_kState_OPENED == pC->m_State) || (M4PTO3GPP_kState_READY == pC->m_State)
1092         || (M4PTO3GPP_kState_FINISHED == pC->m_State))
1093     {
1094         err = M4PTO3GPP_Close(pContext);
1095         if (M4NO_ERROR != err)
1096         {
1097             M4OSA_TRACE1_1("M4PTO3GPP_CleanUp: M4PTO3GPP_Close returns 0x%x", err);
1098             /**< don't return, we have to free other components */
1099         }
1100     }
1101 
1102     /**
1103      *  Free Audio reader stuff, if needed */
1104 
1105     if (M4OSA_NULL != pC->m_pAudioReaderContext) /**< may be M4OSA_NULL if M4PTO3GPP_Open was not\
1106                                                  called */
1107     {
1108 
1109         err = pC->m_pReaderGlobInt->m_pFctClose(pC->m_pAudioReaderContext);
1110         if (M4NO_ERROR != err)
1111         {
1112             M4OSA_TRACE1_1("M4PTO3GPP_CleanUp: pReaderGlobInt->m_pFctClose returns 0x%x", err);
1113             /**< don't return, we have to free other components */
1114         }
1115         err = pC->m_pReaderGlobInt->m_pFctDestroy(pC->m_pAudioReaderContext);
1116         pC->m_pAudioReaderContext = M4OSA_NULL;
1117         if (M4NO_ERROR != err)
1118         {
1119             M4OSA_TRACE1_1("M4PTO3GPP_CleanUp: pReaderGlobInt->m_pFctDestroy returns 0x%x", err);
1120             /**< don't return, we have to free other components */
1121         }
1122     }
1123 
1124     if (M4OSA_NULL != pC->m_pReaderAudioAU)
1125     {
1126         free(pC->m_pReaderAudioAU);
1127         pC->m_pReaderAudioAU = M4OSA_NULL;
1128     }
1129 
1130     /**
1131      *  Free video encoder stuff, if needed */
1132     if (M4OSA_NULL != pC->m_pMp4EncoderContext)
1133     {
1134         err = pC->m_pEncoderInt->pFctCleanup(pC->m_pMp4EncoderContext);
1135         pC->m_pMp4EncoderContext = M4OSA_NULL;
1136         if (M4NO_ERROR != err)
1137         {
1138             M4OSA_TRACE1_1("M4PTO3GPP_CleanUp: pEncoderInt->pFctDestroy returns 0x%x", err);
1139             /**< don't return, we have to free other components */
1140         }
1141     }
1142 
1143     if (M4OSA_NULL != pC->m_pWriterVideoStream)
1144     {
1145         free(pC->m_pWriterVideoStream);
1146         pC->m_pWriterVideoStream = M4OSA_NULL;
1147     }
1148     if (M4OSA_NULL != pC->m_pWriterAudioStream)
1149     {
1150         free(pC->m_pWriterAudioStream);
1151         pC->m_pWriterAudioStream = M4OSA_NULL;
1152     }
1153     if (M4OSA_NULL != pC->m_pWriterVideoStreamInfo)
1154     {
1155         free(pC->m_pWriterVideoStreamInfo);
1156         pC->m_pWriterVideoStreamInfo = M4OSA_NULL;
1157     }
1158     if (M4OSA_NULL != pC->m_pWriterAudioStreamInfo)
1159     {
1160         free(pC->m_pWriterAudioStreamInfo);
1161         pC->m_pWriterAudioStreamInfo = M4OSA_NULL;
1162     }
1163 
1164 
1165     /**
1166      *  Free the shells interfaces */
1167     if (M4OSA_NULL != pC->m_pReaderGlobInt)
1168     {
1169         free(pC->m_pReaderGlobInt);
1170         pC->m_pReaderGlobInt = M4OSA_NULL;
1171     }
1172     if (M4OSA_NULL != pC->m_pReaderDataInt)
1173     {
1174         free(pC->m_pReaderDataInt);
1175         pC->m_pReaderDataInt = M4OSA_NULL;
1176     }
1177 
1178     if(M4OSA_NULL != pC->m_pEncoderInt)
1179     {
1180         free(pC->m_pEncoderInt);
1181         pC->m_pEncoderInt = M4OSA_NULL;
1182     }
1183     if(M4OSA_NULL != pC->m_pWriterGlobInt)
1184     {
1185         free(pC->m_pWriterGlobInt);
1186         pC->m_pWriterGlobInt = M4OSA_NULL;
1187     }
1188     if(M4OSA_NULL != pC->m_pWriterDataInt)
1189     {
1190         free(pC->m_pWriterDataInt);
1191         pC->m_pWriterDataInt = M4OSA_NULL;
1192     }
1193     /**< Do not free pC->pOsaMemoryPtrFct and pC->pOsaMemoryPtrFct, because it's owned by the \
1194     application */
1195 
1196     /**
1197      *  Free the context itself */
1198     free(pC);
1199     pC = M4OSA_NULL;
1200 
1201     M4OSA_TRACE3_0("M4PTO3GPP_CleanUp(): returning M4NO_ERROR");
1202     return M4NO_ERROR;
1203 }
1204 
1205 /********************* INTERNAL FUNCTIONS *********************/
1206 
1207 /**
1208  ******************************************************************************
1209  * M4OSA_ERR M4PTO3GPP_Ready4Processing(M4PTO3GPP_InternalContext* pC);
1210  * @brief   Prepare all resources and interfaces for the transcoding.
1211  * @note    It is called by the first M4OSA_Step() call
1212  * @param   pC          (IN) M4PTO3GPP private context
1213  * @return  M4NO_ERROR: No error
1214  * @return  Any error returned by an underlaying module
1215  ******************************************************************************
1216 */
1217 /******************************************************/
M4PTO3GPP_Ready4Processing(M4PTO3GPP_InternalContext * pC)1218 M4OSA_ERR M4PTO3GPP_Ready4Processing(M4PTO3GPP_InternalContext* pC)
1219 /******************************************************/
1220 {
1221     M4OSA_ERR               err = M4NO_ERROR;
1222     M4WRITER_OutputFileType outputFileType;
1223     M4OSA_UInt32            uiVersion;
1224     M4ENCODER_Format        encFormat;
1225     M4ENCODER_AdvancedParams   EncParams;    /**< Encoder advanced parameters */
1226     M4SYS_StreamIDValue     optionValue;
1227 
1228     M4OSA_TRACE3_1("M4PTO3GPP_Ready4Processing called with pC=0x%x", pC);
1229 
1230     /******************************/
1231     /******************************/
1232 
1233     /********************************************/
1234     /********                            ********/
1235     /******** Video Encoder Parames init ********/
1236     /********                            ********/
1237     /********************************************/
1238 
1239     /**
1240      *  Get the correct encoder interface */
1241     switch(pC->m_Params.OutputVideoFormat)
1242     {
1243         case M4VIDEOEDITING_kMPEG4:
1244 #ifdef M4VSS_SUPPORT_ENCODER_MPEG4
1245                 err = VideoEditorVideoEncoder_getInterface_MPEG4(&encFormat, &pC->m_pEncoderInt,
1246                     M4ENCODER_OPEN_ADVANCED);
1247 #else /* software MPEG4 encoder not available! */
1248                 M4OSA_TRACE1_0("No MPEG4 encoder available! Did you forget to register one?");
1249                 err = M4ERR_STATE;
1250 #endif /* software MPEG4 encoder available? */
1251             break;
1252         case M4VIDEOEDITING_kH263:
1253 #ifdef M4VSS_SUPPORT_ENCODER_MPEG4
1254                 err = VideoEditorVideoEncoder_getInterface_H263(&encFormat, &pC->m_pEncoderInt,
1255                     M4ENCODER_OPEN_ADVANCED);
1256 #else /* software H263 encoder not available! */
1257                 M4OSA_TRACE1_0("No H263 encoder available! Did you forget to register one?");
1258                 err = M4ERR_STATE;
1259 #endif /* software H263 encoder available? */
1260             break;
1261         case M4VIDEOEDITING_kH264:
1262 #ifdef M4VSS_SUPPORT_ENCODER_AVC
1263                 err = VideoEditorVideoEncoder_getInterface_H264(&encFormat, &pC->m_pEncoderInt,
1264                     M4ENCODER_OPEN_ADVANCED);
1265 #else /* software H264 encoder not available! */
1266                 M4OSA_TRACE1_0("M4PTO3GPP_Ready4Processing: No H264 encoder available!\
1267                                Did you forget to register one?");
1268                 err = M4ERR_STATE;
1269 #endif /* software H264 encoder available? */
1270             break;
1271         default:
1272             M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: unknown format 0x%x returning \
1273                            ERR_M4PTO3GPP_UNDEFINED_OUTPUT_VIDEO_FORMAT",
1274                            pC->m_Params.OutputVideoFormat);
1275             return ERR_PTO3GPP_UNDEFINED_OUTPUT_VIDEO_FORMAT;
1276     }
1277     if (M4NO_ERROR != err)
1278     {
1279         M4OSA_TRACE1_1("switch(pC->m_Params.OutputVideoFormat): getInterfaces returns 0x%x", err);
1280         return err;
1281     }
1282 
1283     /**
1284      *  Fill encoder parameters according to M4PTO3GPP settings */
1285 
1286     /**
1287      * Video frame size */
1288     switch(pC->m_Params.OutputVideoFrameSize)
1289     {
1290         case M4VIDEOEDITING_kSQCIF :
1291             EncParams.FrameHeight = M4ENCODER_SQCIF_Height;
1292             EncParams.FrameWidth  = M4ENCODER_SQCIF_Width;
1293             break;
1294         case M4VIDEOEDITING_kQQVGA :
1295             EncParams.FrameHeight = M4ENCODER_QQVGA_Height;
1296             EncParams.FrameWidth  = M4ENCODER_QQVGA_Width;
1297             break;
1298         case M4VIDEOEDITING_kQCIF :
1299             EncParams.FrameHeight = M4ENCODER_QCIF_Height;
1300             EncParams.FrameWidth  = M4ENCODER_QCIF_Width;
1301             break;
1302         case M4VIDEOEDITING_kQVGA :
1303             EncParams.FrameHeight = M4ENCODER_QVGA_Height;
1304             EncParams.FrameWidth  = M4ENCODER_QVGA_Width;
1305             break;
1306         case M4VIDEOEDITING_kCIF :
1307             EncParams.FrameHeight = M4ENCODER_CIF_Height;
1308             EncParams.FrameWidth  = M4ENCODER_CIF_Width;
1309             break;
1310         case M4VIDEOEDITING_kVGA :
1311             EncParams.FrameHeight = M4ENCODER_VGA_Height;
1312             EncParams.FrameWidth  = M4ENCODER_VGA_Width;
1313             break;
1314 /* +PR LV5807 */
1315         case M4VIDEOEDITING_kWVGA :
1316             EncParams.FrameHeight = M4ENCODER_WVGA_Height;
1317             EncParams.FrameWidth  = M4ENCODER_WVGA_Width;
1318             break;
1319         case M4VIDEOEDITING_kNTSC:
1320             EncParams.FrameHeight = M4ENCODER_NTSC_Height;
1321             EncParams.FrameWidth  = M4ENCODER_NTSC_Width;
1322             break;
1323 /* -PR LV5807 */
1324 /* +CR Google */
1325         case M4VIDEOEDITING_k640_360:
1326             EncParams.FrameHeight = M4ENCODER_640_360_Height;
1327             EncParams.FrameWidth  = M4ENCODER_640_360_Width;
1328             break;
1329 
1330         case M4VIDEOEDITING_k854_480:
1331             EncParams.FrameHeight = M4ENCODER_854_480_Height;
1332             EncParams.FrameWidth  = M4ENCODER_854_480_Width;
1333             break;
1334 
1335         case M4VIDEOEDITING_k1280_720:
1336             EncParams.FrameHeight = M4ENCODER_1280_720_Height;
1337             EncParams.FrameWidth  = M4ENCODER_1280_720_Width;
1338             break;
1339 
1340         case M4VIDEOEDITING_k1080_720:
1341             EncParams.FrameHeight = M4ENCODER_1080_720_Height;
1342             EncParams.FrameWidth  = M4ENCODER_1080_720_Width;
1343             break;
1344 
1345         case M4VIDEOEDITING_k960_720:
1346             EncParams.FrameHeight = M4ENCODER_960_720_Height;
1347             EncParams.FrameWidth  = M4ENCODER_960_720_Width;
1348             break;
1349 
1350         case M4VIDEOEDITING_k1920_1080:
1351             EncParams.FrameHeight = M4ENCODER_1920_1080_Height;
1352             EncParams.FrameWidth  = M4ENCODER_1920_1080_Width;
1353             break;
1354 /* -CR Google */
1355         default :
1356             M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: unknown format 0x%x returning \
1357                            ERR_M4PTO3GPP_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE",
1358                            pC->m_Params.OutputVideoFrameSize);
1359             return ERR_PTO3GPP_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE;
1360     }
1361 
1362     EncParams.InputFormat = M4ENCODER_kIYUV420;
1363 
1364     /**
1365      * Video bitrate */
1366     switch(pC->m_Params.OutputVideoBitrate)
1367     {
1368         case M4VIDEOEDITING_k16_KBPS:
1369         case M4VIDEOEDITING_k24_KBPS:
1370         case M4VIDEOEDITING_k32_KBPS:
1371         case M4VIDEOEDITING_k48_KBPS:
1372         case M4VIDEOEDITING_k64_KBPS:
1373         case M4VIDEOEDITING_k96_KBPS:
1374         case M4VIDEOEDITING_k128_KBPS:
1375         case M4VIDEOEDITING_k192_KBPS:
1376         case M4VIDEOEDITING_k256_KBPS:
1377         case M4VIDEOEDITING_k288_KBPS:
1378         case M4VIDEOEDITING_k384_KBPS:
1379         case M4VIDEOEDITING_k512_KBPS:
1380         case M4VIDEOEDITING_k800_KBPS:
1381 /*+ New Encoder bitrates */
1382         case M4VIDEOEDITING_k2_MBPS:
1383         case M4VIDEOEDITING_k5_MBPS:
1384         case M4VIDEOEDITING_k8_MBPS:
1385 /*- New Encoder bitrates */
1386             EncParams.Bitrate = pC->m_Params.OutputVideoBitrate;
1387             break;
1388 
1389         case M4VIDEOEDITING_kVARIABLE_KBPS:
1390 /*+ New Encoder bitrates */
1391             EncParams.Bitrate = M4VIDEOEDITING_k8_MBPS;
1392 /*- New Encoder bitrates */
1393             break;
1394 
1395         default :
1396             M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: unknown format 0x%x returning\
1397                            ERR_M4PTO3GPP_UNDEFINED_OUTPUT_VIDEO_BITRATE",
1398                            pC->m_Params.OutputVideoBitrate);
1399             return ERR_PTO3GPP_UNDEFINED_OUTPUT_VIDEO_BITRATE;
1400     }
1401 
1402     /**
1403      * Video format */
1404     switch(pC->m_Params.OutputVideoFormat)
1405     {
1406         case M4VIDEOEDITING_kMPEG4 :
1407             EncParams.Format    = M4ENCODER_kMPEG4;
1408             break;
1409         case M4VIDEOEDITING_kH263 :
1410             EncParams.Format    = M4ENCODER_kH263;
1411             break;
1412         case M4VIDEOEDITING_kH264:
1413             EncParams.Format    = M4ENCODER_kH264;
1414             break;
1415         default :
1416             M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: unknown format 0x%x returning\
1417                            ERR_M4PTO3GPP_UNDEFINED_OUTPUT_VIDEO_FORMAT",
1418                            pC->m_Params.OutputVideoFormat);
1419             return ERR_PTO3GPP_UNDEFINED_OUTPUT_VIDEO_FORMAT;
1420     }
1421 
1422     /**
1423      * Video frame rate (set it to max = 30 fps) */
1424     EncParams.uiTimeScale = 30;
1425     EncParams.uiRateFactor = 1;
1426 
1427     EncParams.FrameRate = M4ENCODER_k30_FPS;
1428 
1429 
1430     /******************************/
1431     /******** 3GP out init ********/
1432     /******************************/
1433 
1434     /* Get the 3GPP writer interface */
1435     err = M4WRITER_3GP_getInterfaces(&outputFileType, &pC->m_pWriterGlobInt, &pC->m_pWriterDataInt);
1436     if (M4NO_ERROR != err)
1437     {
1438         M4OSA_TRACE1_1("M4WRITER_3GP_getInterfaces: M4WRITER_3GP_getInterfaces returns 0x%x", err);
1439         return err;
1440     }
1441 
1442     /* Init the 3GPP writer */
1443     err = pC->m_pWriterGlobInt->pFctOpen(&pC->m_p3gpWriterContext, pC->m_Params.pOutput3gppFile,
1444         pC->pOsalFileWrite, pC->m_Params.pTemporaryFile, pC->pOsalFileRead);
1445     if (M4NO_ERROR != err)
1446     {
1447         M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: pWriterGlobInt->pFctOpen returns 0x%x", err);
1448         return err;
1449     }
1450 
1451     /**
1452      *  Link to the writer context in the writer interface */
1453     pC->m_pWriterDataInt->pWriterContext = pC->m_p3gpWriterContext;
1454 
1455     /**
1456      *  Set the product description string in the written file */
1457     err = pC->m_pWriterGlobInt->pFctSetOption(pC->m_p3gpWriterContext, M4WRITER_kEmbeddedString,
1458         (M4OSA_DataOption)M4PTO3GPP_SIGNATURE);
1459     if (M4NO_ERROR != err)
1460     {
1461         M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: \
1462                        pWriterGlobInt->pFctSetOption(M4WRITER_kEmbeddedString) returns 0x%x", err);
1463         return err;
1464     }
1465 
1466     /**
1467      *  Set the product version in the written file */
1468     uiVersion = M4VIDEOEDITING_VERSION_MAJOR*100 + M4VIDEOEDITING_VERSION_MINOR*10
1469         + M4VIDEOEDITING_VERSION_REVISION;
1470     err = pC->m_pWriterGlobInt->pFctSetOption(pC->m_p3gpWriterContext, M4WRITER_kEmbeddedVersion,
1471         (M4OSA_DataOption)&uiVersion);
1472     if (M4NO_ERROR != err)
1473     {
1474         M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: \
1475                        pWriterGlobInt->pFctSetOption(M4WRITER_kEmbeddedVersion) returns 0x%x", err);
1476         return err;
1477     }
1478 
1479     /**
1480      *  Allocate and fill the video stream structures for the writer */
1481     pC->m_pWriterVideoStream =
1482         (M4SYS_StreamDescription*)M4OSA_32bitAlignedMalloc(sizeof(M4SYS_StreamDescription), M4PTO3GPP,
1483         (M4OSA_Char *)"pWriterVideoStream");
1484     if (M4OSA_NULL == pC->m_pWriterVideoStream)
1485     {
1486         M4OSA_TRACE1_0("M4PTO3GPP_Ready4Processing(): unable to allocate pWriterVideoStream, \
1487                        returning M4ERR_ALLOC");
1488         return M4ERR_ALLOC;
1489     }
1490     pC->m_pWriterVideoStreamInfo =
1491         (M4WRITER_StreamVideoInfos*)M4OSA_32bitAlignedMalloc(sizeof(M4WRITER_StreamVideoInfos), M4PTO3GPP,
1492         (M4OSA_Char *)"pWriterVideoStreamInfo");
1493     if (M4OSA_NULL == pC->m_pWriterVideoStreamInfo)
1494     {
1495         M4OSA_TRACE1_0("M4PTO3GPP_Ready4Processing(): unable to allocate pWriterVideoStreamInfo,\
1496                        returning M4ERR_ALLOC");
1497         return M4ERR_ALLOC;
1498     }
1499 
1500     /**
1501      * Fill Video properties structure for the AddStream method */
1502     pC->m_pWriterVideoStreamInfo->height        = EncParams.FrameHeight;
1503     pC->m_pWriterVideoStreamInfo->width         = EncParams.FrameWidth;
1504     pC->m_pWriterVideoStreamInfo->fps           = 0;        /**< Not used by the core writer */
1505     pC->m_pWriterVideoStreamInfo->Header.pBuf   = M4OSA_NULL;
1506     /** No header, will be set by setOption */
1507     pC->m_pWriterVideoStreamInfo->Header.Size   = 0;
1508 
1509     /**
1510      *  Fill Video stream description structure for the AddStream method */
1511     pC->m_pWriterVideoStream->streamID = M4PTO3GPP_WRITER_VIDEO_STREAM_ID;
1512 
1513     /**
1514      * Video format */
1515     switch(pC->m_Params.OutputVideoFormat)
1516     {
1517         case M4VIDEOEDITING_kMPEG4:
1518             pC->m_pWriterVideoStream->streamType = M4SYS_kMPEG_4;   break;
1519         case M4VIDEOEDITING_kH263:
1520             pC->m_pWriterVideoStream->streamType = M4SYS_kH263;     break;
1521         case M4VIDEOEDITING_kH264:
1522             pC->m_pWriterVideoStream->streamType = M4SYS_kH264;     break;
1523         default :
1524             M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: unknown format 0x%x returning \
1525                            ERR_M4PTO3GPP_UNDEFINED_OUTPUT_VIDEO_FORMAT",
1526                            pC->m_Params.OutputVideoFormat);
1527             return ERR_PTO3GPP_UNDEFINED_OUTPUT_VIDEO_FORMAT;
1528     }
1529 
1530     /**
1531      * Video bitrate */
1532     switch(pC->m_Params.OutputVideoBitrate)
1533     {
1534         case M4VIDEOEDITING_k16_KBPS:
1535         case M4VIDEOEDITING_k24_KBPS:
1536         case M4VIDEOEDITING_k32_KBPS:
1537         case M4VIDEOEDITING_k48_KBPS:
1538         case M4VIDEOEDITING_k64_KBPS:
1539         case M4VIDEOEDITING_k96_KBPS:
1540         case M4VIDEOEDITING_k128_KBPS:
1541         case M4VIDEOEDITING_k192_KBPS:
1542         case M4VIDEOEDITING_k256_KBPS:
1543         case M4VIDEOEDITING_k288_KBPS:
1544         case M4VIDEOEDITING_k384_KBPS:
1545         case M4VIDEOEDITING_k512_KBPS:
1546         case M4VIDEOEDITING_k800_KBPS:
1547 /*+ New Encoder bitrates */
1548         case M4VIDEOEDITING_k2_MBPS:
1549         case M4VIDEOEDITING_k5_MBPS:
1550         case M4VIDEOEDITING_k8_MBPS:
1551 /*- New Encoder bitrates */
1552             pC->m_pWriterVideoStream->averageBitrate = pC->m_Params.OutputVideoBitrate;
1553             break;
1554 
1555         case M4VIDEOEDITING_kVARIABLE_KBPS :
1556             pC->m_pWriterVideoStream->averageBitrate = 0;
1557             break;
1558 
1559         default :
1560             M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: unknown format 0x%x returning\
1561                            ERR_M4PTO3GPP_UNDEFINED_OUTPUT_VIDEO_BITRATE",
1562                            pC->m_Params.OutputVideoBitrate);
1563             return ERR_PTO3GPP_UNDEFINED_OUTPUT_VIDEO_BITRATE;
1564     }
1565 
1566     pC->m_pWriterVideoStream->duration                  = 0;        /**< Duration is not known */
1567     pC->m_pWriterVideoStream->timeScale                 = 0;    /**< Not used by the core writer */
1568     pC->m_pWriterVideoStream->maxBitrate                = pC->m_pWriterVideoStream->averageBitrate;
1569     pC->m_pWriterVideoStream->profileLevel              = 0;    /**< Not used by the core writer */
1570     pC->m_pWriterVideoStream->decoderSpecificInfo       = (M4OSA_MemAddr32)
1571                                                             (pC->m_pWriterVideoStreamInfo);
1572     pC->m_pWriterVideoStream->decoderSpecificInfoSize   = sizeof(M4WRITER_StreamVideoInfos);
1573 
1574     /**
1575      * Update AU properties for video stream */
1576     pC->m_WriterVideoAU.CTS         = pC->m_WriterVideoAU.DTS = 0;  /** Reset time */
1577     pC->m_WriterVideoAU.size        = 0;
1578     pC->m_WriterVideoAU.frag        = M4OSA_NULL;
1579     pC->m_WriterVideoAU.nbFrag      = 0;                            /** No fragment */
1580     pC->m_WriterVideoAU.stream      = pC->m_pWriterVideoStream;
1581     pC->m_WriterVideoAU.attribute   = AU_RAP;
1582     pC->m_WriterVideoAU.dataAddress = M4OSA_NULL;
1583 
1584     /**
1585      *  If there is an audio input, allocate and fill the audio stream structures for the writer */
1586     if(M4OSA_NULL != pC->m_pReaderAudioStream)
1587     {
1588         pC->m_pWriterAudioStream =
1589             (M4SYS_StreamDescription*)M4OSA_32bitAlignedMalloc(sizeof(M4SYS_StreamDescription), M4PTO3GPP,
1590             (M4OSA_Char *)"pWriterAudioStream");
1591         if (M4OSA_NULL == pC->m_pWriterAudioStream)
1592         {
1593             M4OSA_TRACE1_0("M4PTO3GPP_Ready4Processing(): unable to allocate pWriterAudioStream, \
1594                            returning M4ERR_ALLOC");
1595             return M4ERR_ALLOC;
1596         }
1597         pC->m_pWriterAudioStreamInfo =
1598             (M4WRITER_StreamAudioInfos*)M4OSA_32bitAlignedMalloc(sizeof(M4WRITER_StreamAudioInfos), M4PTO3GPP,
1599             (M4OSA_Char *)"pWriterAudioStreamInfo");
1600         if (M4OSA_NULL == pC->m_pWriterAudioStreamInfo)
1601         {
1602             M4OSA_TRACE1_0("M4PTO3GPP_Ready4Processing(): unable to allocate \
1603                            pWriterAudioStreamInfo, returning M4ERR_ALLOC");
1604             return M4ERR_ALLOC;
1605         }
1606 
1607         pC->m_pWriterAudioStreamInfo->nbSamplesPerSec = 0; /**< unused by our shell writer */
1608         pC->m_pWriterAudioStreamInfo->nbBitsPerSample = 0; /**< unused by our shell writer */
1609         pC->m_pWriterAudioStreamInfo->nbChannels = 1;      /**< unused by our shell writer */
1610 
1611         if( (M4OSA_NULL != pC->m_pReaderAudioStream) && /* audio could have been discarded */
1612             (M4OSA_NULL != pC->m_pReaderAudioStream->m_basicProperties.m_pDecoderSpecificInfo) )
1613         {
1614             /* If we copy the stream from the input, we copy its DSI */
1615             pC->m_pWriterAudioStreamInfo->Header.Size =
1616                 pC->m_pReaderAudioStream->m_basicProperties.m_decoderSpecificInfoSize;
1617             pC->m_pWriterAudioStreamInfo->Header.pBuf =
1618                 (M4OSA_MemAddr8)pC->m_pReaderAudioStream->m_basicProperties.m_pDecoderSpecificInfo;
1619         }
1620         else
1621         {
1622             /* Writer will put a default DSI */
1623             pC->m_pWriterAudioStreamInfo->Header.Size = 0;
1624             pC->m_pWriterAudioStreamInfo->Header.pBuf = M4OSA_NULL;
1625         }
1626 
1627         /**
1628          * Add the audio stream */
1629         switch (pC->m_pReaderAudioStream->m_basicProperties.m_streamType)
1630         {
1631             case M4DA_StreamTypeAudioAmrNarrowBand:
1632                 pC->m_pWriterAudioStream->streamType = M4SYS_kAMR;
1633                 break;
1634             case M4DA_StreamTypeAudioAac:
1635                 pC->m_pWriterAudioStream->streamType = M4SYS_kAAC;
1636                 break;
1637             case M4DA_StreamTypeAudioEvrc:
1638                 pC->m_pWriterAudioStream->streamType = M4SYS_kEVRC;
1639                 break;
1640             default:
1641                 M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: unhandled audio format (0x%x),\
1642                                returning ERR_PTO3GPP_UNDEFINED_OUTPUT_VIDEO_BITRATE",
1643                                pC->m_pReaderAudioStream->m_basicProperties.m_streamType);
1644                 return ERR_PTO3GPP_UNDEFINED_OUTPUT_AUDIO_FORMAT;
1645         }
1646 
1647         /*
1648          * Fill Audio stream description structure for the AddStream method */
1649         pC->m_pWriterAudioStream->streamID                  = M4PTO3GPP_WRITER_AUDIO_STREAM_ID;
1650         pC->m_pWriterAudioStream->duration                  = 0;/**< Duration is not known yet */
1651         pC->m_pWriterAudioStream->timeScale                 = M4PTO3GPP_WRITER_AUDIO_AMR_TIME_SCALE;
1652         pC->m_pWriterAudioStream->profileLevel              = M4PTO3GPP_WRITER_AUDIO_PROFILE_LEVEL;
1653         pC->m_pWriterAudioStream->averageBitrate            =
1654                                 pC->m_pReaderAudioStream->m_basicProperties.m_averageBitRate;
1655         pC->m_pWriterAudioStream->maxBitrate                =
1656                                 pC->m_pWriterAudioStream->averageBitrate;
1657 
1658         /**
1659          * Our writer shell interface is a little tricky: we put M4WRITER_StreamAudioInfos \
1660             in the DSI pointer... */
1661         pC->m_pWriterAudioStream->decoderSpecificInfo =
1662                     (M4OSA_MemAddr32)pC->m_pWriterAudioStreamInfo;
1663 
1664         /**
1665          * Update AU properties for audio stream */
1666         pC->m_WriterAudioAU.CTS         = pC->m_WriterAudioAU.DTS = 0;  /** Reset time */
1667         pC->m_WriterAudioAU.size        = 0;
1668         pC->m_WriterAudioAU.frag        = M4OSA_NULL;
1669         pC->m_WriterAudioAU.nbFrag      = 0;                            /** No fragment */
1670         pC->m_WriterAudioAU.stream      = pC->m_pWriterAudioStream;
1671         pC->m_WriterAudioAU.attribute   = AU_RAP;
1672         pC->m_WriterAudioAU.dataAddress = M4OSA_NULL;
1673     }
1674 
1675     /************************************/
1676     /******** Video Encoder Init ********/
1677     /************************************/
1678 
1679     /**
1680      * PTO uses its own bitrate regulation, not the "true" core regulation */
1681     EncParams.bInternalRegulation = M4OSA_TRUE; //M4OSA_FALSE;
1682     EncParams.uiStartingQuantizerValue = M4PTO3GPP_QUANTIZER_STEP;
1683 
1684     EncParams.videoProfile = pC->m_Params.videoProfile;
1685     EncParams.videoLevel = pC->m_Params.videoLevel;
1686 
1687     /**
1688      * Other encoder settings */
1689 
1690     EncParams.uiHorizontalSearchRange  = 0;             /* use default */
1691     EncParams.uiVerticalSearchRange    = 0;             /* use default */
1692     EncParams.bErrorResilience         = M4OSA_FALSE;   /* no error resilience */
1693     EncParams.uiIVopPeriod             = 15;             /* use default */
1694     EncParams.uiMotionEstimationTools  = 0;             /* M4V_MOTION_EST_TOOLS_ALL */
1695     EncParams.bAcPrediction            = M4OSA_TRUE;    /* use AC prediction */
1696     EncParams.bDataPartitioning        = M4OSA_FALSE;   /* no data partitioning */
1697 
1698 
1699     /**
1700      * Create video encoder */
1701     err = pC->m_pEncoderInt->pFctInit(&pC->m_pMp4EncoderContext, pC->m_pWriterDataInt,
1702                                     M4PTO3GPP_applyVPP, pC, pC->m_pEncoderExternalAPI,
1703                                     pC->m_pEncoderUserData);
1704     if (M4NO_ERROR != err)
1705     {
1706         M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: EncoderInt->pFctInit returns 0x%x", err);
1707         return err;
1708     }
1709 
1710     pC->m_eEncoderState = M4PTO3GPP_kEncoderClosed;
1711 
1712     err = pC->m_pEncoderInt->pFctOpen(pC->m_pMp4EncoderContext, &pC->m_WriterVideoAU, &EncParams);
1713     if (M4NO_ERROR != err)
1714     {
1715         M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: EncoderInt->pFctOpen returns 0x%x", err);
1716         return err;
1717     }
1718 
1719     pC->m_eEncoderState = M4PTO3GPP_kEncoderStopped;
1720 
1721     if (M4OSA_NULL != pC->m_pEncoderInt->pFctStart)
1722     {
1723         err = pC->m_pEncoderInt->pFctStart(pC->m_pMp4EncoderContext);
1724 
1725         if (M4NO_ERROR != err)
1726         {
1727             M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: EncoderInt->pFctStart returns 0x%x", err);
1728             return err;
1729         }
1730     }
1731 
1732     pC->m_eEncoderState = M4PTO3GPP_kEncoderRunning;
1733 
1734     /**
1735      * No more  setoption on "M4ENCODER_kVideoFragmentSize" here.
1736      * It is now automaticly and "smartly" set in the encoder shell. */
1737 
1738     /**************************************/
1739     /******** 3GP out add streams  ********/
1740     /**************************************/
1741 
1742     err = pC->m_pWriterGlobInt->pFctAddStream(pC->m_p3gpWriterContext, pC->m_pWriterVideoStream);
1743     if (M4NO_ERROR != err)
1744     {
1745         M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: pWriterGlobInt->pFctAddStream(video) returns\
1746                        0x%x", err);
1747         return err;
1748     }
1749 
1750     /**
1751      * Set video max au size */
1752     optionValue.streamID    = M4PTO3GPP_WRITER_VIDEO_STREAM_ID;
1753     optionValue.value = (M4OSA_UInt32)(1.5F * (M4OSA_Float)(pC->m_pWriterVideoStreamInfo->width
1754                                                 * pC->m_pWriterVideoStreamInfo->height)
1755                                                 * M4PTO3GPP_VIDEO_MIN_COMPRESSION_RATIO);
1756     M4OSA_TRACE3_1("M4PTO3GPP_Ready4Processing,M4WRITER_kMaxAUSize: %u",optionValue.value);
1757     err = pC->m_pWriterGlobInt->pFctSetOption(pC->m_p3gpWriterContext,
1758                                 (M4OSA_UInt32)M4WRITER_kMaxAUSize,(M4OSA_DataOption) &optionValue);
1759     if (M4NO_ERROR != err)
1760     {
1761         M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: pWriterGlobInt->pFctSetOption(video,\
1762                        M4WRITER_kMaxAUSize) returns 0x%x", err);
1763         return err;
1764     }
1765 
1766     /**
1767      * Set video max chunck size */
1768     optionValue.value = (M4OSA_UInt32)((M4OSA_Float)optionValue.value
1769                         * M4PTO3GPP_VIDEO_AU_SIZE_TO_CHUNCK_SIZE_RATIO);
1770     M4OSA_TRACE3_1("M4PTO3GPP_Ready4Processing,M4WRITER_kMaxChunckSize: %u",optionValue.value);
1771     err = pC->m_pWriterGlobInt->pFctSetOption(pC->m_p3gpWriterContext,
1772                         (M4OSA_UInt32)M4WRITER_kMaxChunckSize,(M4OSA_DataOption) &optionValue);
1773     if (M4NO_ERROR != err)
1774     {
1775         M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: pWriterGlobInt->pFctSetOption(video,\
1776                        M4WRITER_kMaxChunckSize) returns 0x%x", err);
1777         return err;
1778     }
1779 
1780     if (M4OSA_NULL != pC->m_pReaderAudioStream)
1781     {
1782         err = pC->m_pWriterGlobInt->pFctAddStream(pC->m_p3gpWriterContext, pC->m_pWriterAudioStream);
1783         if (M4NO_ERROR != err)
1784         {
1785             M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: pWriterGlobInt->pFctAddStream(audio) \
1786                            returns 0x%x", err);
1787             return err;
1788         }
1789 
1790         /**
1791          * Set audio max au size */
1792         optionValue.value       = M4PTO3GPP_AUDIO_MAX_AU_SIZE;
1793         optionValue.streamID    = M4PTO3GPP_WRITER_AUDIO_STREAM_ID;
1794         err = pC->m_pWriterGlobInt->pFctSetOption(pC->m_p3gpWriterContext,
1795             (M4OSA_UInt32)M4WRITER_kMaxAUSize,(M4OSA_DataOption) &optionValue);
1796         if (M4NO_ERROR != err)
1797         {
1798             M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: pWriterGlobInt->pFctSetOption(audio,\
1799                            M4WRITER_kMaxAUSize) returns 0x%x", err);
1800             return err;
1801         }
1802 
1803         /**
1804          * Set audio max chunck size */
1805         optionValue.value = M4PTO3GPP_AUDIO_MAX_CHUNK_SIZE; /**< Magical */
1806         err = pC->m_pWriterGlobInt->pFctSetOption(pC->m_p3gpWriterContext,
1807                         (M4OSA_UInt32)M4WRITER_kMaxChunckSize,(M4OSA_DataOption) &optionValue);
1808         if (M4NO_ERROR != err)
1809         {
1810             M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: pWriterGlobInt->pFctSetOption(audio,\
1811                            M4WRITER_kMaxChunckSize) returns 0x%x", err);
1812             return err;
1813         }
1814     }
1815 
1816     /*
1817      * Close the stream registering in order to be ready to write data */
1818     err = pC->m_pWriterGlobInt->pFctStartWriting(pC->m_p3gpWriterContext);
1819     if (M4NO_ERROR != err)
1820     {
1821         M4OSA_TRACE1_1("M4PTO3GPP_Ready4Processing: pWriterGlobInt->pFctStartWriting returns 0x%x",
1822                         err);
1823         return err;
1824     }
1825 
1826 
1827     M4OSA_TRACE3_0("M4PTO3GPP_Ready4Processing: returning M4NO_ERROR");
1828     return M4NO_ERROR;
1829 }
1830 
1831 /**
1832  ******************************************************************************
1833  M4OSA_ERR M4PTO3GPP_writeAmrSilence122Frame(M4WRITER_DataInterface* pWriterDataIntInterface,
1834                             M4WRITER_Context* pWriterContext,
1835                                       M4SYS_AccessUnit* pWriterAudioAU, M4OSA_Time mtIncCts)
1836  * @brief   Write an AMR 12.2kbps silence FRAME into the writer
1837  * @note    Mainly used to fix the 'bzz' bug...
1838  * @param   pWriterDataIntInterface (IN)    writer data interfaces
1839  *          pWriterContext          (IN/OUT)writer context
1840  *          pWriterAudioAU          (OUT)   writer audio access unit
1841  *          mtIncCts                (IN)    writer CTS
1842  * @return  M4NO_ERROR: No error
1843  ******************************************************************************
1844 */
M4PTO3GPP_writeAmrSilence122Frame(M4WRITER_DataInterface * pWriterDataIntInterface,M4WRITER_Context * pWriterContext,M4SYS_AccessUnit * pWriterAudioAU,M4OSA_Time mtIncCts)1845 static M4OSA_ERR M4PTO3GPP_writeAmrSilence122Frame(M4WRITER_DataInterface* pWriterDataIntInterface,
1846                                                    M4WRITER_Context* pWriterContext,
1847                                                     M4SYS_AccessUnit* pWriterAudioAU,
1848                                                     M4OSA_Time mtIncCts)
1849 {
1850     M4OSA_ERR err;
1851 
1852     err = pWriterDataIntInterface->pStartAU(pWriterContext, M4PTO3GPP_WRITER_AUDIO_STREAM_ID,
1853                                         pWriterAudioAU);
1854     if (M4NO_ERROR != err)
1855     {
1856         M4OSA_TRACE1_1("M4PTO3GPP_writeAmrSilence122Frame: pWriterDataInt->pStartAU(audio) returns \
1857                                                     0x%x!", err);
1858         return err;
1859     }
1860 
1861     memcpy((void *)pWriterAudioAU->dataAddress,
1862      (void *)M4PTO3GPP_AMR_AU_SILENCE_122_FRAME, M4PTO3GPP_AMR_AU_SILENCE_FRAME_122_SIZE);
1863     pWriterAudioAU->size    = M4PTO3GPP_AMR_AU_SILENCE_FRAME_122_SIZE;
1864     pWriterAudioAU->CTS     = mtIncCts;
1865     pWriterAudioAU->nbFrag  = 0;
1866 
1867     err = pWriterDataIntInterface->pProcessAU(pWriterContext, M4PTO3GPP_WRITER_AUDIO_STREAM_ID,
1868                                                 pWriterAudioAU);
1869     if (M4NO_ERROR != err)
1870     {
1871         M4OSA_TRACE1_1("M4PTO3GPP_writeAmrSilence122Frame: pWriterDataInt->pProcessAU(silence) \
1872                        returns 0x%x!", err);
1873         return err;
1874     }
1875 
1876     return M4NO_ERROR;
1877 }
1878 
1879 /**
1880  ******************************************************************************
1881  M4OSA_ERR M4PTO3GPP_writeAmrSilence048Frame(M4WRITER_DataInterface* pWriterDataIntInterface,
1882                                         M4WRITER_Context* pWriterContext,
1883                                       M4SYS_AccessUnit* pWriterAudioAU, M4OSA_Time mtIncCts)
1884  * @brief   Write an AMR 12.2kbps silence FRAME into the writer
1885  * @note    Mainly used to fix the 'bzz' bug...
1886  * @param   pWriterDataIntInterface (IN)    writer data interfaces
1887  *          pWriterContext          (IN/OUT)writer context
1888  *          pWriterAudioAU          (OUT)   writer audio access unit
1889  *          mtIncCts                (IN)    writer CTS
1890  * @return  M4NO_ERROR: No error
1891  ******************************************************************************
1892 */
M4PTO3GPP_writeAmrSilence048Frame(M4WRITER_DataInterface * pWriterDataIntInterface,M4WRITER_Context * pWriterContext,M4SYS_AccessUnit * pWriterAudioAU,M4OSA_Time mtIncCts)1893 static M4OSA_ERR M4PTO3GPP_writeAmrSilence048Frame(M4WRITER_DataInterface* pWriterDataIntInterface,
1894                                                    M4WRITER_Context* pWriterContext,
1895                                                 M4SYS_AccessUnit* pWriterAudioAU,
1896                                                 M4OSA_Time mtIncCts)
1897 {
1898     M4OSA_ERR err;
1899 
1900     err = pWriterDataIntInterface->pStartAU(pWriterContext, M4PTO3GPP_WRITER_AUDIO_STREAM_ID,
1901                                                         pWriterAudioAU);
1902     if (M4NO_ERROR != err)
1903     {
1904         M4OSA_TRACE1_1("M4PTO3GPP_writeAmrSilence048Frame: pWriterDataInt->pStartAU(audio)\
1905                        returns 0x%x!", err);
1906         return err;
1907     }
1908 
1909     memcpy((void *)pWriterAudioAU->dataAddress,
1910                 (void *)M4PTO3GPP_AMR_AU_SILENCE_048_FRAME,
1911                 M4PTO3GPP_AMR_AU_SILENCE_FRAME_048_SIZE);
1912     pWriterAudioAU->size    = M4PTO3GPP_AMR_AU_SILENCE_FRAME_048_SIZE;
1913     pWriterAudioAU->CTS     = mtIncCts;
1914     pWriterAudioAU->nbFrag  = 0;
1915 
1916     err = pWriterDataIntInterface->pProcessAU(pWriterContext,
1917                     M4PTO3GPP_WRITER_AUDIO_STREAM_ID, pWriterAudioAU);
1918     if (M4NO_ERROR != err)
1919     {
1920         M4OSA_TRACE1_1("M4PTO3GPP_writeAmrSilence048Frame: \
1921                        pWriterDataInt->pProcessAU(silence) returns 0x%x!", err);
1922         return err;
1923     }
1924 
1925     return M4NO_ERROR;
1926 }
1927 
1928 
1929