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 /*********************************************************/ 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 /*********************************************************/ 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 /*********************************************************/ 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 /*********************************************************/ 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 /*********************************************************/ 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 /*********************************************************/ 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 /******************************************************/ 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 */ 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 */ 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