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
70const 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
77const 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/***************************/
83static M4OSA_ERR M4PTO3GPP_Ready4Processing(M4PTO3GPP_InternalContext* pC);
84
85/****************************/
86/*** "External" functions ***/
87/****************************/
88extern M4OSA_ERR M4WRITER_3GP_getInterfaces(M4WRITER_OutputFileType* pType,
89                                            M4WRITER_GlobalInterface** SrcGlobalInterface,
90                                            M4WRITER_DataInterface** SrcDataInterface);
91extern M4OSA_ERR M4READER_AMR_getInterfaces(M4READER_MediaType *pMediaType,
92                                            M4READER_GlobalInterface **pRdrGlobalInterface,
93                                            M4READER_DataInterface **pRdrDataInterface);
94extern M4OSA_ERR M4READER_3GP_getInterfaces(M4READER_MediaType *pMediaType,
95                                            M4READER_GlobalInterface **pRdrGlobalInterface,
96                                            M4READER_DataInterface **pRdrDataInterface);
97
98/****************************/
99/*** "Static" functions ***/
100/****************************/
101static M4OSA_ERR M4PTO3GPP_writeAmrSilence122Frame(
102                                    M4WRITER_DataInterface* pWriterDataIntInterface,
103                                    M4WRITER_Context* pWriterContext,
104                                    M4SYS_AccessUnit* pWriterAudioAU,
105                                    M4OSA_Time mtIncCts);
106static 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/*********************************************************/
123M4OSA_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/*********************************************************/
154M4OSA_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/*********************************************************/
279M4OSA_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/*********************************************************/
601M4OSA_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/*********************************************************/
936M4OSA_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/*********************************************************/
1075M4OSA_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/******************************************************/
1218M4OSA_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*/
1845static 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*/
1893static 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