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