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