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