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