1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 /** 17 ****************************************************************************** 18 * @file M4VSS3GPP_Clip.c 19 * @brief Implementation of functions related to input clip management. 20 * @note All functions in this file are static, i.e. non public 21 ****************************************************************************** 22 */ 23 24 /****************/ 25 /*** Includes ***/ 26 /****************/ 27 28 #include "NXPSW_CompilerSwitches.h" 29 /** 30 * Our headers */ 31 #include "M4VSS3GPP_API.h" 32 #include "M4VSS3GPP_ErrorCodes.h" 33 #include "M4VSS3GPP_InternalTypes.h" 34 #include "M4VSS3GPP_InternalFunctions.h" 35 #include "M4VSS3GPP_InternalConfig.h" 36 37 /** 38 * OSAL headers */ 39 #include "M4OSA_Memory.h" /* OSAL memory management */ 40 #include "M4OSA_Debug.h" /* OSAL debug management */ 41 42 43 /** 44 * Common headers (for aac) */ 45 #include "M4_Common.h" 46 47 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS 48 #include "M4VD_EXTERNAL_Interface.h" 49 50 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */ 51 52 /* Osal header fileno */ 53 #include "M4OSA_CharStar.h" 54 55 /** 56 ****************************************************************************** 57 * define Static function prototypes 58 ****************************************************************************** 59 */ 60 61 static M4OSA_ERR M4VSS3GPP_intClipPrepareAudioDecoder( 62 M4VSS3GPP_ClipContext *pClipCtxt ); 63 64 static M4OSA_ERR M4VSS3GPP_intCheckAndGetCodecAacProperties( 65 M4VSS3GPP_ClipContext *pClipCtxt); 66 67 /** 68 ****************************************************************************** 69 * M4OSA_ERR M4VSS3GPP_intClipOpen() 70 * @brief Open a clip. Creates a clip context. 71 * @note 72 * @param hClipCtxt (OUT) Return the internal clip context 73 * @param pClipSettings (IN) Edit settings of this clip. The module will keep a 74 * reference to this pointer 75 * @param pFileReadPtrFct (IN) Pointer to OSAL file reader functions 76 * @param bSkipAudioTrack (IN) If true, do not open the audio 77 * @param bFastOpenMode (IN) If true, use the fast mode of the 3gpp reader 78 * (only the first AU is read) 79 * @return M4NO_ERROR: No error 80 * @return M4ERR_ALLOC: There is no more available memory 81 ****************************************************************************** 82 */ 83 84 M4OSA_ERR M4VSS3GPP_intClipInit( M4VSS3GPP_ClipContext ** hClipCtxt, 85 M4OSA_FileReadPointer *pFileReadPtrFct ) 86 { 87 M4VSS3GPP_ClipContext *pClipCtxt; 88 M4OSA_ERR err; 89 90 M4OSA_DEBUG_IF2((M4OSA_NULL == hClipCtxt), M4ERR_PARAMETER, 91 "M4VSS3GPP_intClipInit: hClipCtxt is M4OSA_NULL"); 92 M4OSA_DEBUG_IF2((M4OSA_NULL == pFileReadPtrFct), M4ERR_PARAMETER, 93 "M4VSS3GPP_intClipInit: pFileReadPtrFct is M4OSA_NULL"); 94 95 /** 96 * Allocate the clip context */ 97 *hClipCtxt = 98 (M4VSS3GPP_ClipContext *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_ClipContext), 99 M4VSS3GPP, (M4OSA_Char *)"M4VSS3GPP_ClipContext"); 100 101 if( M4OSA_NULL == *hClipCtxt ) 102 { 103 M4OSA_TRACE1_0( 104 "M4VSS3GPP_intClipInit(): unable to allocate M4VSS3GPP_ClipContext,\ 105 returning M4ERR_ALLOC"); 106 return M4ERR_ALLOC; 107 } 108 M4OSA_TRACE3_1("M4VSS3GPP_intClipInit(): clipCtxt=0x%x", *hClipCtxt); 109 110 111 /** 112 * Use this shortcut to simplify the code */ 113 pClipCtxt = *hClipCtxt; 114 115 /* Inialization of context Variables */ 116 memset((void *)pClipCtxt, 0,sizeof(M4VSS3GPP_ClipContext)); 117 118 pClipCtxt->pSettings = M4OSA_NULL; 119 120 /** 121 * Init the clip context */ 122 pClipCtxt->iVoffset = 0; 123 pClipCtxt->iAoffset = 0; 124 pClipCtxt->Vstatus = M4VSS3GPP_kClipStatus_READ; 125 pClipCtxt->Astatus = M4VSS3GPP_kClipStatus_READ; 126 127 pClipCtxt->pReaderContext = M4OSA_NULL; 128 pClipCtxt->pVideoStream = M4OSA_NULL; 129 pClipCtxt->pAudioStream = M4OSA_NULL; 130 pClipCtxt->VideoAU.m_dataAddress = M4OSA_NULL; 131 pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL; 132 133 pClipCtxt->pViDecCtxt = M4OSA_NULL; 134 pClipCtxt->iVideoDecCts = 0; 135 pClipCtxt->iVideoRenderCts = 0; 136 pClipCtxt->lastDecodedPlane = M4OSA_NULL; 137 pClipCtxt->iActualVideoBeginCut = 0; 138 pClipCtxt->iActualAudioBeginCut = 0; 139 pClipCtxt->bVideoAuAvailable = M4OSA_FALSE; 140 pClipCtxt->bFirstAuWritten = M4OSA_FALSE; 141 142 pClipCtxt->bMpeg4GovState = M4OSA_FALSE; 143 144 pClipCtxt->bAudioFrameAvailable = M4OSA_FALSE; 145 pClipCtxt->pAudioFramePtr = M4OSA_NULL; 146 pClipCtxt->iAudioFrameCts = 0; 147 pClipCtxt->pAudioDecCtxt = 0; 148 pClipCtxt->AudioDecBufferOut.m_bufferSize = 0; 149 pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL; 150 151 pClipCtxt->pFileReadPtrFct = pFileReadPtrFct; 152 pClipCtxt->pPlaneYuv = M4OSA_NULL; 153 pClipCtxt->pPlaneYuvWithEffect = M4OSA_NULL; 154 pClipCtxt->m_pPreResizeFrame = M4OSA_NULL; 155 pClipCtxt->bGetYuvDataFromDecoder = M4OSA_TRUE; 156 157 /* 158 * Reset pointers for media and codecs interfaces */ 159 err = M4VSS3GPP_clearInterfaceTables(&pClipCtxt->ShellAPI); 160 M4ERR_CHECK_RETURN(err); 161 162 /* 163 * Call the media and codecs subscription module */ 164 err = M4VSS3GPP_subscribeMediaAndCodec(&pClipCtxt->ShellAPI); 165 M4ERR_CHECK_RETURN(err); 166 167 return M4NO_ERROR; 168 } 169 170 /* Note: if the clip is opened in fast mode, it can only be used for analysis and nothing else. */ 171 M4OSA_ERR M4VSS3GPP_intClipOpen( M4VSS3GPP_ClipContext *pClipCtxt, 172 M4VSS3GPP_ClipSettings *pClipSettings, M4OSA_Bool bSkipAudioTrack, 173 M4OSA_Bool bFastOpenMode, M4OSA_Bool bAvoidOpeningVideoDec ) 174 { 175 M4OSA_ERR err; 176 M4READER_MediaFamily mediaFamily; 177 M4_StreamHandler *pStreamHandler; 178 M4_StreamHandler dummyStreamHandler; 179 M4OSA_Int32 iDuration; 180 M4OSA_Void *decoderUserData; 181 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS 182 183 M4DECODER_MPEG4_DecoderConfigInfo dummy; 184 M4DECODER_VideoSize videoSizeFromDSI; 185 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */ 186 187 M4DECODER_OutputFilter FilterOption; 188 M4OSA_Char pTempFile[100]; 189 190 /** 191 * Check input parameters */ 192 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER, 193 "M4VSS3GPP_intClipOpen: pClipCtxt is M4OSA_NULL"); 194 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettings), M4ERR_PARAMETER, 195 "M4VSS3GPP_intClipOpen: pClipSettings is M4OSA_NULL"); 196 197 M4OSA_TRACE3_2( 198 "M4VSS3GPP_intClipOpen: called with pClipCtxt: 0x%x, bAvoidOpeningVideoDec=0x%x", 199 pClipCtxt, bAvoidOpeningVideoDec); 200 /** 201 * Keep a pointer to the clip settings. Remember that we don't possess it! */ 202 pClipCtxt->pSettings = pClipSettings; 203 if(M4VIDEOEDITING_kFileType_ARGB8888 == pClipCtxt->pSettings->FileType) { 204 M4OSA_TRACE3_0("M4VSS3GPP_intClipOpen: Image stream; set current vid dec"); 205 err = M4VSS3GPP_setCurrentVideoDecoder( 206 &pClipCtxt->ShellAPI, M4DA_StreamTypeVideoARGB8888); 207 M4ERR_CHECK_RETURN(err); 208 209 decoderUserData = M4OSA_NULL; 210 211 err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctCreate( 212 &pClipCtxt->pViDecCtxt, 213 &dummyStreamHandler, 214 pClipCtxt->ShellAPI.m_pReader, 215 pClipCtxt->ShellAPI.m_pReaderDataIt, 216 &pClipCtxt->VideoAU, 217 decoderUserData); 218 219 if (M4NO_ERROR != err) { 220 M4OSA_TRACE1_1("M4VSS3GPP_intClipOpen: \ 221 m_pVideoDecoder->m_pFctCreate returns 0x%x", err); 222 return err; 223 } 224 M4OSA_TRACE3_1("M4VSS3GPP_intClipOpen: \ 225 Vid dec started; pViDecCtxt=0x%x", pClipCtxt->pViDecCtxt); 226 227 return M4NO_ERROR; 228 } 229 230 /** 231 * Get the correct reader interface */ 232 err = M4VSS3GPP_setCurrentReader(&pClipCtxt->ShellAPI, 233 pClipCtxt->pSettings->FileType); 234 M4ERR_CHECK_RETURN(err); 235 236 /** 237 * Init the 3GPP or MP3 reader */ 238 err = 239 pClipCtxt->ShellAPI.m_pReader->m_pFctCreate(&pClipCtxt->pReaderContext); 240 241 if( M4NO_ERROR != err ) 242 { 243 M4OSA_TRACE1_1( 244 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctCreate returns 0x%x", 245 err); 246 return err; 247 } 248 249 /** 250 * Link the reader interface to the reader context (used by the decoder to know the reader) */ 251 pClipCtxt->ShellAPI.m_pReaderDataIt->m_readerContext = 252 pClipCtxt->pReaderContext; 253 254 /** 255 * Set the OSAL read function set */ 256 err = pClipCtxt->ShellAPI.m_pReader->m_pFctSetOption( 257 pClipCtxt->pReaderContext, 258 M4READER_kOptionID_SetOsaFileReaderFctsPtr, 259 (M4OSA_DataOption)(pClipCtxt->pFileReadPtrFct)); 260 261 if( M4NO_ERROR != err ) 262 { 263 M4OSA_TRACE1_1( 264 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctSetOption returns 0x%x", 265 err); 266 return err; 267 } 268 269 /** 270 * Set the fast open mode if asked (3GPP only) */ 271 if( M4VIDEOEDITING_kFileType_3GPP == pClipCtxt->pSettings->FileType ) 272 { 273 if( M4OSA_TRUE == bFastOpenMode ) 274 { 275 err = pClipCtxt->ShellAPI.m_pReader->m_pFctSetOption( 276 pClipCtxt->pReaderContext, 277 M4READER_3GP_kOptionID_FastOpenMode, M4OSA_NULL); 278 279 if( M4NO_ERROR != err ) 280 { 281 M4OSA_TRACE1_1( 282 "M4VSS3GPP_intClipOpen():\ 283 m_pReader->m_pFctSetOption(FastOpenMode) returns 0x%x", 284 err); 285 return err; 286 } 287 } 288 289 /** 290 * Set the skip audio option if asked */ 291 if( M4OSA_TRUE == bSkipAudioTrack ) 292 { 293 err = pClipCtxt->ShellAPI.m_pReader->m_pFctSetOption( 294 pClipCtxt->pReaderContext, 295 M4READER_3GP_kOptionID_VideoOnly, M4OSA_NULL); 296 297 if( M4NO_ERROR != err ) 298 { 299 M4OSA_TRACE1_1( 300 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctSetOption(VideoOnly) returns 0x%x", 301 err); 302 return err; 303 } 304 } 305 } 306 if(pClipCtxt->pSettings->FileType == M4VIDEOEDITING_kFileType_PCM) 307 { 308 309 310 311 312 M4OSA_chrNCopy(pTempFile,pClipSettings->pFile,strlen(pClipSettings->pFile)); 313 314 315 switch (pClipCtxt->pSettings->ClipProperties.uiSamplingFrequency) 316 { 317 case 8000: 318 strncat((char *)pTempFile,(const char *)"_8000",6); 319 break; 320 case 11025: 321 strncat((char *)pTempFile,(const char *)"_11025",6); 322 break; 323 case 12000: 324 strncat((char *)pTempFile,(const char *)"_12000",6); 325 break; 326 case 16000: 327 strncat((char *)pTempFile,(const char *)"_16000",6); 328 break; 329 case 22050: 330 strncat((char *)pTempFile,(const char *)"_22050",6); 331 break; 332 case 24000: 333 strncat((char *)pTempFile,(const char *)"_24000",6); 334 break; 335 case 32000: 336 strncat((char *)pTempFile,(const char *)"_32000",6); 337 break; 338 case 44100: 339 strncat((char *)pTempFile,(const char *)"_44100",6); 340 break; 341 case 48000: 342 strncat((char *)pTempFile,(const char *)"_48000",6); 343 break; 344 default: 345 M4OSA_TRACE1_1("M4VSS3GPP_intClipOpen: invalid input for BG tracksampling \ 346 frequency (%d Hz), returning M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY"\ 347 ,pClipCtxt->pSettings->ClipProperties.uiSamplingFrequency ); 348 return M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY; 349 } 350 351 352 353 //M4OSA_chrNCat(pTempFile, 354 // itoa(pClipCtxt->pSettings->ClipProperties.uiSamplingFrequency),5); 355 switch(pClipCtxt->pSettings->ClipProperties.uiNbChannels) 356 { 357 case 1: 358 strncat((char *)pTempFile,(const char *)"_1.pcm",6); 359 break; 360 case 2: 361 strncat((char *)pTempFile,(const char *)"_2.pcm",6); 362 break; 363 default: 364 M4OSA_TRACE1_1("M4VSS3GPP_intClipOpen: invalid input for BG track no.\ 365 of channels (%d ), returning M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS",\ 366 pClipCtxt->pSettings->ClipProperties.uiNbChannels); 367 return M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS; 368 } 369 //M4OSA_chrNCat(pTempFile,itoa(pClipCtxt->pSettings->ClipProperties.uiNbChannels),1); 370 371 err = pClipCtxt->ShellAPI.m_pReader->m_pFctOpen( pClipCtxt->pReaderContext, pTempFile); 372 373 } 374 else 375 { 376 /** 377 * Open the 3GPP/MP3 clip file */ 378 err = pClipCtxt->ShellAPI.m_pReader->m_pFctOpen( pClipCtxt->pReaderContext, 379 pClipSettings->pFile); 380 } 381 if( M4NO_ERROR != err ) 382 { 383 M4OSA_UInt32 uiDummy, uiCoreId; 384 M4OSA_TRACE1_1( 385 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctOpen returns 0x%x", err); 386 387 /** 388 * If the error is from the core reader, we change it to a public VSS3GPP error */ 389 M4OSA_ERR_SPLIT(err, uiDummy, uiCoreId, uiDummy); 390 391 if( M4MP4_READER == uiCoreId ) 392 { 393 M4OSA_TRACE1_0( 394 "M4VSS3GPP_intClipOpen(): returning M4VSS3GPP_ERR_INVALID_3GPP_FILE"); 395 return M4VSS3GPP_ERR_INVALID_3GPP_FILE; 396 } 397 return err; 398 } 399 400 /** 401 * Get the audio and video streams */ 402 while( err == M4NO_ERROR ) 403 { 404 err = pClipCtxt->ShellAPI.m_pReader->m_pFctGetNextStream( 405 pClipCtxt->pReaderContext, &mediaFamily, &pStreamHandler); 406 407 /*in case we found a BIFS stream or something else...*/ 408 if( ( err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE)) 409 || (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS)) ) 410 { 411 err = M4NO_ERROR; 412 continue; 413 } 414 415 if( M4NO_ERROR == err ) /**< One stream found */ 416 { 417 /** 418 * Found a video stream */ 419 if( ( mediaFamily == M4READER_kMediaFamilyVideo) 420 && (M4OSA_NULL == pClipCtxt->pVideoStream) ) 421 { 422 if( ( M4DA_StreamTypeVideoH263 == pStreamHandler->m_streamType) 423 || (M4DA_StreamTypeVideoMpeg4 424 == pStreamHandler->m_streamType) 425 || (M4DA_StreamTypeVideoMpeg4Avc 426 == pStreamHandler->m_streamType) ) 427 { 428 M4OSA_TRACE3_1( 429 "M4VSS3GPP_intClipOpen():\ 430 Found a H263 or MPEG-4 or H264 video stream in input 3gpp clip; %d", 431 pStreamHandler->m_streamType); 432 433 /** 434 * Keep pointer to the video stream */ 435 pClipCtxt->pVideoStream = 436 (M4_VideoStreamHandler *)pStreamHandler; 437 pStreamHandler->m_bStreamIsOK = M4OSA_TRUE; 438 439 /** 440 * Reset the stream reader */ 441 err = pClipCtxt->ShellAPI.m_pReader->m_pFctReset( 442 pClipCtxt->pReaderContext, 443 (M4_StreamHandler *)pClipCtxt->pVideoStream); 444 445 if( M4NO_ERROR != err ) 446 { 447 M4OSA_TRACE1_1( 448 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctReset(video) returns 0x%x", 449 err); 450 return err; 451 } 452 453 /** 454 * Initializes an access Unit */ 455 err = pClipCtxt->ShellAPI.m_pReader->m_pFctFillAuStruct( 456 pClipCtxt->pReaderContext, 457 (M4_StreamHandler *)pClipCtxt->pVideoStream, 458 &pClipCtxt->VideoAU); 459 460 if( M4NO_ERROR != err ) 461 { 462 M4OSA_TRACE1_1( 463 "M4VSS3GPP_intClipOpen():\ 464 m_pReader->m_pFctFillAuStruct(video) returns 0x%x", 465 err); 466 return err; 467 } 468 } 469 else /**< Not H263 or MPEG-4 (H264, etc.) */ 470 { 471 M4OSA_TRACE1_1( 472 "M4VSS_editClipOpen():\ 473 Found an unsupported video stream (0x%x) in input 3gpp clip", 474 pStreamHandler->m_streamType); 475 476 pStreamHandler->m_bStreamIsOK = M4OSA_FALSE; 477 } 478 } 479 /** 480 * Found an audio stream */ 481 else if( ( mediaFamily == M4READER_kMediaFamilyAudio) 482 && (M4OSA_NULL == pClipCtxt->pAudioStream) ) 483 { 484 if( ( M4DA_StreamTypeAudioAmrNarrowBand 485 == pStreamHandler->m_streamType) 486 || (M4DA_StreamTypeAudioAac == pStreamHandler->m_streamType) 487 || (M4DA_StreamTypeAudioMp3 488 == pStreamHandler->m_streamType) 489 || (M4DA_StreamTypeAudioEvrc 490 == pStreamHandler->m_streamType) 491 || (M4DA_StreamTypeAudioPcm 492 == pStreamHandler->m_streamType) ) 493 { 494 M4OSA_TRACE3_1( 495 "M4VSS3GPP_intClipOpen(): \ 496 Found an AMR-NB or AAC or MP3 audio stream in input clip; %d", 497 pStreamHandler->m_streamType); 498 499 /** 500 * Keep pointer to the audio stream */ 501 pClipCtxt->pAudioStream = 502 (M4_AudioStreamHandler *)pStreamHandler; 503 pStreamHandler->m_bStreamIsOK = M4OSA_TRUE; 504 505 /** 506 * Reset the stream reader */ 507 err = pClipCtxt->ShellAPI.m_pReader->m_pFctReset( 508 pClipCtxt->pReaderContext, 509 (M4_StreamHandler *)pClipCtxt->pAudioStream); 510 511 if( M4NO_ERROR != err ) 512 { 513 M4OSA_TRACE1_1( 514 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctReset(audio) returns 0x%x", 515 err); 516 return err; 517 } 518 519 /** 520 * Initializes an access Unit */ 521 err = pClipCtxt->ShellAPI.m_pReader->m_pFctFillAuStruct( 522 pClipCtxt->pReaderContext, 523 (M4_StreamHandler *)pClipCtxt->pAudioStream, 524 &pClipCtxt->AudioAU); 525 526 if( M4NO_ERROR != err ) 527 { 528 M4OSA_TRACE1_1( 529 "M4VSS3GPP_intClipOpen():\ 530 m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", 531 err); 532 return err; 533 } 534 } 535 else /**< Not AMR-NB or AAC (AMR-WB...) */ 536 { 537 M4OSA_TRACE1_1( 538 "M4VSS3GPP_intClipOpen():\ 539 Found an unsupported audio stream (0x%x) in input 3gpp/mp3 clip", 540 pStreamHandler->m_streamType); 541 542 pStreamHandler->m_bStreamIsOK = M4OSA_FALSE; 543 } 544 } 545 } 546 else if( M4OSA_ERR_IS_ERROR(err) ) 547 { 548 M4OSA_TRACE1_1( 549 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctGetNextStream() returns 0x%x!", 550 err); 551 return err; 552 } 553 } 554 555 /** 556 * Init Video decoder */ 557 if( M4OSA_NULL != pClipCtxt->pVideoStream ) 558 { 559 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS 560 /* If external decoders are possible, it's best to avoid opening the decoder if the clip is only 561 going to be used for analysis, as we're not going to use it for the analysis in the case of a 562 possible external decoder anyway, and either there could be no decoder at this point or the HW 563 decoder could be present, which we want to avoid opening for that. See comments in 564 intBuildAnalysis for more details. */ 565 566 /* CHANGEME Temporarily only do this for MPEG4, since for now only MPEG4 external decoders are 567 supported, and the following wouldn't work for H263 so a release where external decoders are 568 possible, but not used, wouldn't work with H263 stuff. */ 569 570 if( bAvoidOpeningVideoDec && M4DA_StreamTypeVideoMpeg4 571 == pClipCtxt->pVideoStream->m_basicProperties.m_streamType ) 572 { 573 /* Oops! The mere act of opening the decoder also results in the image size being 574 filled in the video stream! Compensate for this by using ParseVideoDSI to fill 575 this info. */ 576 M4OSA_TRACE3_0( 577 "M4VSS3GPP_intClipOpen: Mpeg4 stream; vid dec not started"); 578 err = M4DECODER_EXTERNAL_ParseVideoDSI(pClipCtxt->pVideoStream-> 579 m_basicProperties.m_pDecoderSpecificInfo, 580 pClipCtxt->pVideoStream-> 581 m_basicProperties.m_decoderSpecificInfoSize, 582 &dummy, &videoSizeFromDSI); 583 584 pClipCtxt->pVideoStream->m_videoWidth = videoSizeFromDSI.m_uiWidth; 585 pClipCtxt->pVideoStream->m_videoHeight = 586 videoSizeFromDSI.m_uiHeight; 587 } 588 else 589 { 590 591 #endif 592 593 M4OSA_TRACE3_0( 594 "M4VSS3GPP_intClipOpen: Mp4/H263/H264 stream; set current vid dec"); 595 err = M4VSS3GPP_setCurrentVideoDecoder(&pClipCtxt->ShellAPI, 596 pClipCtxt->pVideoStream->m_basicProperties.m_streamType); 597 M4ERR_CHECK_RETURN(err); 598 599 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS 600 601 decoderUserData = 602 pClipCtxt->ShellAPI.m_pCurrentVideoDecoderUserData; 603 604 #else 605 606 decoderUserData = M4OSA_NULL; 607 608 #endif 609 610 err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctCreate( 611 &pClipCtxt->pViDecCtxt, 612 &pClipCtxt->pVideoStream->m_basicProperties, 613 pClipCtxt->ShellAPI.m_pReader, 614 pClipCtxt->ShellAPI.m_pReaderDataIt, 615 &pClipCtxt->VideoAU, decoderUserData); 616 617 if( ( ((M4OSA_UInt32)M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED) == err) 618 || (((M4OSA_UInt32)M4ERR_DECODER_H263_NOT_BASELINE) == err) ) 619 { 620 /** 621 * Our decoder is not compatible with H263 profile other than 0. 622 * So it returns this internal error code. 623 * We translate it to our own error code */ 624 return M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED; 625 } 626 else if( M4NO_ERROR != err ) 627 { 628 M4OSA_TRACE1_1( 629 "M4VSS3GPP_intClipOpen: m_pVideoDecoder->m_pFctCreate returns 0x%x", 630 err); 631 return err; 632 } 633 M4OSA_TRACE3_1( 634 "M4VSS3GPP_intClipOpen: Vid dec started; pViDecCtxt=0x%x", 635 pClipCtxt->pViDecCtxt); 636 637 if( M4DA_StreamTypeVideoMpeg4Avc 638 == pClipCtxt->pVideoStream->m_basicProperties.m_streamType ) 639 { 640 FilterOption.m_pFilterFunction = 641 (M4OSA_Void *) &M4VIFI_ResizeBilinearYUV420toYUV420; 642 FilterOption.m_pFilterUserData = M4OSA_NULL; 643 err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctSetOption( 644 pClipCtxt->pViDecCtxt, M4DECODER_kOptionID_OutputFilter, 645 (M4OSA_DataOption) &FilterOption); 646 647 if( M4NO_ERROR != err ) 648 { 649 M4OSA_TRACE1_1( 650 "M4VSS3GPP_intClipOpen: m_pVideoDecoder->m_pFctSetOption returns 0x%x", 651 err); 652 return err; 653 } 654 else 655 { 656 M4OSA_TRACE3_0( 657 "M4VSS3GPP_intClipOpen: m_pVideoDecoder->m_pFctSetOption\ 658 M4DECODER_kOptionID_OutputFilter OK"); 659 } 660 } 661 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS 662 663 } 664 665 #endif 666 667 } 668 669 /** 670 * Init Audio decoder */ 671 if( M4OSA_NULL != pClipCtxt->pAudioStream ) 672 { 673 err = M4VSS3GPP_intClipPrepareAudioDecoder(pClipCtxt); 674 M4ERR_CHECK_RETURN(err); 675 M4OSA_TRACE3_1("M4VSS3GPP_intClipOpen: Audio dec started; context=0x%x", 676 pClipCtxt->pAudioDecCtxt); 677 } 678 else 679 { 680 pClipCtxt->AudioAU.m_streamID = 0; 681 pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL; 682 pClipCtxt->AudioAU.m_size = 0; 683 pClipCtxt->AudioAU.m_CTS = 0; 684 pClipCtxt->AudioAU.m_DTS = 0; 685 pClipCtxt->AudioAU.m_attribute = 0; 686 pClipCtxt->AudioAU.m_maxsize = 0; 687 pClipCtxt->AudioAU.m_structSize = sizeof(pClipCtxt->AudioAU); 688 } 689 690 /** 691 * Get the duration of the longest stream */ 692 if( M4OSA_TRUE == pClipCtxt->pSettings->ClipProperties.bAnalysed ) 693 { 694 /* If already calculated set it to previous value */ 695 /* Because fast open and full open can return a different value, 696 it can mismatch user settings */ 697 /* Video track is more important than audio track (if video track is shorter than 698 audio track, it can led to cut larger than expected) */ 699 iDuration = pClipCtxt->pSettings->ClipProperties.uiClipVideoDuration; 700 701 if( iDuration == 0 ) 702 { 703 iDuration = pClipCtxt->pSettings->ClipProperties.uiClipDuration; 704 } 705 } 706 else 707 { 708 /* Else compute it from streams */ 709 iDuration = 0; 710 711 if( M4OSA_NULL != pClipCtxt->pVideoStream ) 712 { 713 iDuration = (M4OSA_Int32)( 714 pClipCtxt->pVideoStream->m_basicProperties.m_duration); 715 } 716 717 if( ( M4OSA_NULL != pClipCtxt->pAudioStream) && ((M4OSA_Int32)( 718 pClipCtxt->pAudioStream->m_basicProperties.m_duration) 719 > iDuration) && iDuration == 0 ) 720 { 721 iDuration = (M4OSA_Int32)( 722 pClipCtxt->pAudioStream->m_basicProperties.m_duration); 723 } 724 } 725 726 /** 727 * If end time is not used, we set it to the video track duration */ 728 if( 0 == pClipCtxt->pSettings->uiEndCutTime ) 729 { 730 pClipCtxt->pSettings->uiEndCutTime = (M4OSA_UInt32)iDuration; 731 } 732 733 pClipCtxt->iEndTime = (M4OSA_Int32)pClipCtxt->pSettings->uiEndCutTime; 734 735 /** 736 * Return with no error */ 737 M4OSA_TRACE3_0("M4VSS3GPP_intClipOpen(): returning M4NO_ERROR"); 738 return M4NO_ERROR; 739 } 740 741 /** 742 ****************************************************************************** 743 * M4OSA_Void M4VSS3GPP_intClipDeleteAudioTrack() 744 * @brief Delete the audio track. Clip will be like if it had no audio track 745 * @note 746 * @param pClipCtxt (IN) Internal clip context 747 ****************************************************************************** 748 */ 749 M4OSA_Void M4VSS3GPP_intClipDeleteAudioTrack( M4VSS3GPP_ClipContext *pClipCtxt ) 750 { 751 /** 752 * But we don't have to free the audio stream. It will be freed by the reader when closing it*/ 753 pClipCtxt->pAudioStream = M4OSA_NULL; 754 755 /** 756 * We will return a constant silence AMR AU. 757 * We set it here once, instead of at each read audio step. */ 758 pClipCtxt->pAudioFramePtr = (M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData; 759 pClipCtxt->uiAudioFrameSize = pClipCtxt->uiSilenceFrameSize; 760 761 /** 762 * Free the decoded audio buffer (it needs to be re-allocated to store silence 763 frame eventually)*/ 764 if( M4OSA_NULL != pClipCtxt->AudioDecBufferOut.m_dataAddress ) 765 { 766 free(pClipCtxt->AudioDecBufferOut.m_dataAddress); 767 pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL; 768 } 769 770 return; 771 } 772 773 /** 774 ****************************************************************************** 775 * M4OSA_ERR M4VSS3GPP_intClipDecodeVideoUpToCurrentTime() 776 * @brief Jump to the previous RAP and decode up to the current video time 777 * @param pClipCtxt (IN) Internal clip context 778 * @param iCts (IN) Target CTS 779 ****************************************************************************** 780 */ 781 M4OSA_ERR M4VSS3GPP_intClipDecodeVideoUpToCts( M4VSS3GPP_ClipContext *pClipCtxt, 782 M4OSA_Int32 iCts ) 783 { 784 M4OSA_Int32 iRapCts, iClipCts; 785 M4_MediaTime dDecodeTime; 786 M4OSA_Bool bClipJump = M4OSA_FALSE; 787 M4OSA_ERR err; 788 789 /** 790 * Compute the time in the clip base */ 791 iClipCts = iCts - pClipCtxt->iVoffset; 792 793 /** 794 * If we were reading the clip, we must jump to the previous RAP 795 * to decode from that point. */ 796 if( M4VSS3GPP_kClipStatus_READ == pClipCtxt->Vstatus ) 797 { 798 /** 799 * The decoder must be told to jump */ 800 bClipJump = M4OSA_TRUE; 801 pClipCtxt->iVideoDecCts = iClipCts; 802 803 /** 804 * Remember the clip reading state */ 805 pClipCtxt->Vstatus = M4VSS3GPP_kClipStatus_DECODE_UP_TO; 806 } 807 808 /** 809 * If we are in decodeUpTo() process, check if we need to do 810 one more step or if decoding is finished */ 811 if( M4VSS3GPP_kClipStatus_DECODE_UP_TO == pClipCtxt->Vstatus ) 812 { 813 /* Do a step of 500 ms decoding */ 814 pClipCtxt->iVideoDecCts += 500; 815 816 if( pClipCtxt->iVideoDecCts > iClipCts ) 817 { 818 /* Target time reached, we switch back to DECODE mode */ 819 pClipCtxt->iVideoDecCts = iClipCts; 820 pClipCtxt->Vstatus = M4VSS3GPP_kClipStatus_DECODE; 821 } 822 823 M4OSA_TRACE2_1("c ,,,, decode up to : %ld", pClipCtxt->iVideoDecCts); 824 } 825 else 826 { 827 /* Just decode at current clip cts */ 828 pClipCtxt->iVideoDecCts = iClipCts; 829 830 M4OSA_TRACE2_1("d ,,,, decode up to : %ld", pClipCtxt->iVideoDecCts); 831 } 832 833 /** 834 * Decode up to the target */ 835 M4OSA_TRACE3_2( 836 "M4VSS3GPP_intClipDecodeVideoUpToCts: Decoding upTo CTS %.3f, pClipCtxt=0x%x", 837 dDecodeTime, pClipCtxt); 838 839 dDecodeTime = (M4OSA_Double)pClipCtxt->iVideoDecCts; 840 pClipCtxt->isRenderDup = M4OSA_FALSE; 841 err = 842 pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctDecode(pClipCtxt->pViDecCtxt, 843 &dDecodeTime, bClipJump, 0); 844 845 if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) 846 && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) ) 847 { 848 M4OSA_TRACE1_1( 849 "M4VSS3GPP_intClipDecodeVideoUpToCts: m_pFctDecode returns 0x%x!", 850 err); 851 return err; 852 } 853 854 if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME ) 855 { 856 pClipCtxt->isRenderDup = M4OSA_TRUE; 857 } 858 859 /** 860 * Return */ 861 M4OSA_TRACE3_0("M4VSS3GPP_intClipDecodeVideoUpToCts: returning M4NO_ERROR"); 862 return M4NO_ERROR; 863 } 864 865 /** 866 ****************************************************************************** 867 * M4OSA_ERR M4VSS3GPP_intClipReadNextAudioFrame() 868 * @brief Read one AU frame in the clip 869 * @note 870 * @param pClipCtxt (IN) Internal clip context 871 * @return M4NO_ERROR: No error 872 ****************************************************************************** 873 */ 874 M4OSA_ERR M4VSS3GPP_intClipReadNextAudioFrame( 875 M4VSS3GPP_ClipContext *pClipCtxt ) 876 { 877 M4OSA_ERR err; 878 879 /* ------------------------------ */ 880 /* ---------- NO AUDIO ---------- */ 881 /* ------------------------------ */ 882 883 if( M4OSA_NULL == pClipCtxt->pAudioStream ) 884 { 885 /* If there is no audio track, we return silence AUs */ 886 pClipCtxt->pAudioFramePtr = 887 (M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData; 888 pClipCtxt->uiAudioFrameSize = pClipCtxt->uiSilenceFrameSize; 889 pClipCtxt->iAudioFrameCts += pClipCtxt->iSilenceFrameDuration; 890 891 M4OSA_TRACE2_0("b #### blank track"); 892 } 893 894 /* ---------------------------------- */ 895 /* ---------- AMR-NB, EVRC ---------- */ 896 /* ---------------------------------- */ 897 898 else if( ( M4VIDEOEDITING_kAMR_NB 899 == pClipCtxt->pSettings->ClipProperties.AudioStreamType) 900 || (M4VIDEOEDITING_kEVRC 901 == pClipCtxt->pSettings->ClipProperties.AudioStreamType) ) 902 { 903 if( M4OSA_FALSE == pClipCtxt->bAudioFrameAvailable ) 904 { 905 /** 906 * No AU available, so we must must read one from the original track reader */ 907 err = pClipCtxt->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu( 908 pClipCtxt->pReaderContext, 909 (M4_StreamHandler *)pClipCtxt->pAudioStream, 910 &pClipCtxt->AudioAU); 911 912 if( M4NO_ERROR == err ) 913 { 914 /** 915 * Set the current AMR frame position at the beginning of the read AU */ 916 pClipCtxt->pAudioFramePtr = pClipCtxt->AudioAU.m_dataAddress; 917 918 /** 919 * Set the AMR frame CTS */ 920 pClipCtxt->iAudioFrameCts = 921 (M4OSA_Int32)(pClipCtxt->AudioAU.m_CTS 922 * pClipCtxt->scale_audio + 0.5); 923 } 924 else if( ( M4WAR_NO_MORE_AU == err) && (M4VIDEOEDITING_kAMR_NB 925 == pClipCtxt->pSettings->ClipProperties.AudioStreamType) ) 926 { 927 /** 928 * If there is less audio than the stream duration indicated, 929 * we return silence at the end of the stream. */ 930 pClipCtxt->pAudioFramePtr = 931 (M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData; 932 pClipCtxt->uiAudioFrameSize = pClipCtxt->uiSilenceFrameSize; 933 pClipCtxt->iAudioFrameCts += pClipCtxt->iSilenceFrameDuration; 934 935 M4OSA_TRACE2_0("a #### silence AU"); 936 937 /** 938 * Return with M4WAR_NO_MORE_AU */ 939 M4OSA_TRACE3_0( 940 "M4VSS3GPP_intClipReadNextAudioFrame()-AMR: \ 941 returning M4WAR_NO_MORE_AU (silence)"); 942 return M4WAR_NO_MORE_AU; 943 } 944 else /**< fatal error (or no silence in EVRC) */ 945 { 946 M4OSA_TRACE3_1( 947 "M4VSS3GPP_intClipReadNextAudioFrame()-AMR: m_pFctGetNextAu() returns 0x%x", 948 err); 949 return err; 950 } 951 } 952 else /* bAudioFrameAvailable */ 953 { 954 /** 955 * Go to the next AMR frame in the AU */ 956 pClipCtxt->pAudioFramePtr += pClipCtxt->uiAudioFrameSize; 957 958 /** 959 * Increment CTS: one AMR frame is 20 ms long */ 960 pClipCtxt->iAudioFrameCts += pClipCtxt->iSilenceFrameDuration; 961 } 962 963 /** 964 * Get the size of the pointed AMR frame */ 965 switch( pClipCtxt->pSettings->ClipProperties.AudioStreamType ) 966 { 967 case M4VIDEOEDITING_kAMR_NB: 968 pClipCtxt->uiAudioFrameSize = 969 (M4OSA_UInt16)M4VSS3GPP_intGetFrameSize_AMRNB( 970 pClipCtxt->pAudioFramePtr); 971 break; 972 973 case M4VIDEOEDITING_kEVRC: 974 pClipCtxt->uiAudioFrameSize = 975 (M4OSA_UInt16)M4VSS3GPP_intGetFrameSize_EVRC( 976 pClipCtxt->pAudioFramePtr); 977 break; 978 default: 979 break; 980 } 981 982 if( 0 == pClipCtxt->uiAudioFrameSize ) 983 { 984 M4OSA_TRACE3_0( 985 "M4VSS3GPP_intClipReadNextAudioFrame()-AMR: AU frame size == 0,\ 986 returning M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU"); 987 return M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU; 988 } 989 else if( pClipCtxt->uiAudioFrameSize > pClipCtxt->AudioAU.m_size ) 990 { 991 M4OSA_TRACE3_0( 992 "M4VSS3GPP_intClipReadNextAudioFrame()-AMR: AU frame size greater than AU size!,\ 993 returning M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU"); 994 return M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU; 995 } 996 997 /** 998 * Check if the end of the current AU has been reached or not */ 999 if( ( pClipCtxt->pAudioFramePtr + pClipCtxt->uiAudioFrameSize) 1000 < (pClipCtxt->AudioAU.m_dataAddress + pClipCtxt->AudioAU.m_size) ) 1001 { 1002 pClipCtxt->bAudioFrameAvailable = M4OSA_TRUE; 1003 } 1004 else 1005 { 1006 pClipCtxt->bAudioFrameAvailable = 1007 M4OSA_FALSE; /**< will be used for next call */ 1008 } 1009 } 1010 1011 /* ------------------------- */ 1012 /* ---------- AAC ---------- */ 1013 /* ------------------------- */ 1014 1015 else if( ( M4VIDEOEDITING_kAAC 1016 == pClipCtxt->pSettings->ClipProperties.AudioStreamType) 1017 || (M4VIDEOEDITING_kAACplus 1018 == pClipCtxt->pSettings->ClipProperties.AudioStreamType) 1019 || (M4VIDEOEDITING_keAACplus 1020 == pClipCtxt->pSettings->ClipProperties.AudioStreamType) ) 1021 { 1022 err = pClipCtxt->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu( 1023 pClipCtxt->pReaderContext, 1024 (M4_StreamHandler *)pClipCtxt->pAudioStream, 1025 &pClipCtxt->AudioAU); 1026 1027 if( M4NO_ERROR == err ) 1028 { 1029 pClipCtxt->pAudioFramePtr = pClipCtxt->AudioAU.m_dataAddress; 1030 pClipCtxt->uiAudioFrameSize = 1031 (M4OSA_UInt16)pClipCtxt->AudioAU.m_size; 1032 pClipCtxt->iAudioFrameCts = 1033 (M4OSA_Int32)(pClipCtxt->AudioAU.m_CTS * pClipCtxt->scale_audio 1034 + 0.5); 1035 1036 /* Patch because m_CTS is unfortunately rounded in 3gp reader shell */ 1037 /* (cts is not an integer with frequency 24 kHz for example) */ 1038 pClipCtxt->iAudioFrameCts = ( ( pClipCtxt->iAudioFrameCts 1039 + pClipCtxt->iSilenceFrameDuration / 2) 1040 / pClipCtxt->iSilenceFrameDuration) 1041 * pClipCtxt->iSilenceFrameDuration; 1042 } 1043 else if( M4WAR_NO_MORE_AU == err ) 1044 { 1045 /** 1046 * If there is less audio than the stream duration indicated, 1047 * we return silence at the end of the stream. */ 1048 pClipCtxt->pAudioFramePtr = 1049 (M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData; 1050 pClipCtxt->uiAudioFrameSize = pClipCtxt->uiSilenceFrameSize; 1051 pClipCtxt->iAudioFrameCts += pClipCtxt->iSilenceFrameDuration; 1052 1053 M4OSA_TRACE2_0("a #### silence AU"); 1054 1055 /** 1056 * Return with M4WAR_NO_MORE_AU */ 1057 M4OSA_TRACE3_0( 1058 "M4VSS3GPP_intClipReadNextAudioFrame()-AAC:\ 1059 returning M4WAR_NO_MORE_AU (silence)"); 1060 return M4WAR_NO_MORE_AU; 1061 } 1062 else /**< fatal error */ 1063 { 1064 M4OSA_TRACE3_1( 1065 "M4VSS3GPP_intClipReadNextAudioFrame()-AAC: m_pFctGetNextAu() returns 0x%x", 1066 err); 1067 return err; 1068 } 1069 } 1070 1071 /* --------------------------------- */ 1072 /* ---------- MP3, others ---------- */ 1073 /* --------------------------------- */ 1074 1075 else 1076 { 1077 err = pClipCtxt->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu( 1078 pClipCtxt->pReaderContext, 1079 (M4_StreamHandler *)pClipCtxt->pAudioStream, 1080 &pClipCtxt->AudioAU); 1081 1082 if( M4NO_ERROR != err ) 1083 { 1084 M4OSA_TRACE3_1( 1085 "M4VSS3GPP_intClipReadNextAudioFrame()-MP3: m_pFctGetNextAu() returns 0x%x", 1086 err); 1087 return err; 1088 } 1089 1090 pClipCtxt->pAudioFramePtr = pClipCtxt->AudioAU.m_dataAddress; 1091 pClipCtxt->uiAudioFrameSize = (M4OSA_UInt16)pClipCtxt->AudioAU.m_size; 1092 pClipCtxt->iAudioFrameCts = 1093 (M4OSA_Int32)(pClipCtxt->AudioAU.m_CTS * pClipCtxt->scale_audio 1094 + 0.5); 1095 } 1096 1097 /** 1098 * Return with no error */ 1099 M4OSA_TRACE3_0( 1100 "M4VSS3GPP_intClipReadNextAudioFrame(): returning M4NO_ERROR"); 1101 1102 return M4NO_ERROR; 1103 } 1104 1105 /** 1106 ****************************************************************************** 1107 * M4OSA_ERR M4VSS3GPP_intClipPrepareAudioDecoder() 1108 * @brief Creates and initialize the audio decoder for the clip. 1109 * @note 1110 * @param pClipCtxt (IN) internal clip context 1111 * @return M4NO_ERROR: No error 1112 ****************************************************************************** 1113 */ 1114 static M4OSA_ERR M4VSS3GPP_intClipPrepareAudioDecoder( 1115 M4VSS3GPP_ClipContext *pClipCtxt ) 1116 { 1117 M4OSA_ERR err = M4NO_ERROR; 1118 M4_StreamType audiotype; 1119 #ifdef M4VSS_SUPPORT_OMX_CODECS 1120 1121 M4_AACType iAacType = 0; 1122 1123 #endif 1124 1125 /** 1126 * Set the proper audio decoder */ 1127 1128 audiotype = pClipCtxt->pAudioStream->m_basicProperties.m_streamType; 1129 1130 //EVRC 1131 if( M4DA_StreamTypeAudioEvrc 1132 != audiotype ) /* decoder not supported yet, but allow to do null encoding */ 1133 1134 err = M4VSS3GPP_setCurrentAudioDecoder(&pClipCtxt->ShellAPI, audiotype); 1135 M4ERR_CHECK_RETURN(err); 1136 1137 /** 1138 * Creates the audio decoder */ 1139 if( M4OSA_NULL == pClipCtxt->ShellAPI.m_pAudioDecoder ) 1140 { 1141 M4OSA_TRACE1_0( 1142 "M4VSS3GPP_intClipPrepareAudioDecoder(): Fails to initiate the audio decoder."); 1143 return M4VSS3GPP_ERR_AUDIO_DECODER_INIT_FAILED; 1144 } 1145 1146 if( M4OSA_NULL == pClipCtxt->pAudioDecCtxt ) 1147 { 1148 #ifdef M4VSS_SUPPORT_OMX_CODECS 1149 1150 if( M4OSA_TRUE == pClipCtxt->ShellAPI.bAllowFreeingOMXCodecInterface ) 1151 { 1152 if( M4DA_StreamTypeAudioAac == audiotype ) { 1153 err = M4VSS3GPP_intCheckAndGetCodecAacProperties( 1154 pClipCtxt); 1155 } else if (M4DA_StreamTypeAudioPcm != audiotype) { 1156 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec( 1157 &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream, 1158 M4OSA_NULL); 1159 } else { 1160 err = M4NO_ERROR; 1161 } 1162 if( M4NO_ERROR != err ) 1163 { 1164 M4OSA_TRACE1_1( 1165 "M4VSS3GPP_intClipPrepareAudioDecoder: m_pAudioDecoder->m_pFctCreateAudioDec\ 1166 returns 0x%x", err); 1167 return err; 1168 } 1169 } 1170 else 1171 { 1172 M4OSA_TRACE3_1( 1173 "M4VSS3GPP_intClipPrepareAudioDecoder:\ 1174 Creating external audio decoder of type 0x%x", audiotype); 1175 /* External OMX codecs are used*/ 1176 if( M4DA_StreamTypeAudioAac == audiotype ) 1177 { 1178 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec( 1179 &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream, 1180 pClipCtxt->ShellAPI.pCurrentAudioDecoderUserData); 1181 1182 if( M4NO_ERROR == err ) 1183 { 1184 /* AAC properties*/ 1185 /*get from Reader; temporary, till Audio decoder shell API 1186 available to get the AAC properties*/ 1187 pClipCtxt->AacProperties.aNumChan = 1188 pClipCtxt->pAudioStream->m_nbChannels; 1189 pClipCtxt->AacProperties.aSampFreq = 1190 pClipCtxt->pAudioStream->m_samplingFrequency; 1191 1192 err = pClipCtxt->ShellAPI.m_pAudioDecoder-> 1193 m_pFctGetOptionAudioDec(pClipCtxt->pAudioDecCtxt, 1194 M4AD_kOptionID_StreamType, 1195 (M4OSA_DataOption) &iAacType); 1196 1197 if( M4NO_ERROR != err ) 1198 { 1199 M4OSA_TRACE1_1( 1200 "M4VSS3GPP_intClipPrepareAudioDecoder:\ 1201 m_pAudioDecoder->m_pFctGetOptionAudioDec returns err 0x%x", err); 1202 iAacType = M4_kAAC; //set to default 1203 err = M4NO_ERROR; 1204 } 1205 else { 1206 M4OSA_TRACE3_1( 1207 "M4VSS3GPP_intClipPrepareAudioDecoder: \ 1208 m_pAudioDecoder->m_pFctGetOptionAudioDec returns streamType %d", 1209 iAacType); 1210 } 1211 switch( iAacType ) 1212 { 1213 case M4_kAAC: 1214 pClipCtxt->AacProperties.aSBRPresent = 0; 1215 pClipCtxt->AacProperties.aPSPresent = 0; 1216 break; 1217 1218 case M4_kAACplus: 1219 pClipCtxt->AacProperties.aSBRPresent = 1; 1220 pClipCtxt->AacProperties.aPSPresent = 0; 1221 pClipCtxt->AacProperties.aExtensionSampFreq = 1222 pClipCtxt->pAudioStream->m_samplingFrequency; 1223 break; 1224 1225 case M4_keAACplus: 1226 pClipCtxt->AacProperties.aSBRPresent = 1; 1227 pClipCtxt->AacProperties.aPSPresent = 1; 1228 pClipCtxt->AacProperties.aExtensionSampFreq = 1229 pClipCtxt->pAudioStream->m_samplingFrequency; 1230 break; 1231 default: 1232 break; 1233 } 1234 M4OSA_TRACE3_2( 1235 "M4VSS3GPP_intClipPrepareAudioDecoder: AAC NBChans=%d, SamplFreq=%d", 1236 pClipCtxt->AacProperties.aNumChan, 1237 pClipCtxt->AacProperties.aSampFreq); 1238 } 1239 } 1240 else 1241 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec( 1242 &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream, 1243 pClipCtxt->ShellAPI.pCurrentAudioDecoderUserData); 1244 1245 if( M4NO_ERROR != err ) 1246 { 1247 M4OSA_TRACE1_1( 1248 "M4VSS3GPP_intClipPrepareAudioDecoder:\ 1249 m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x", 1250 err); 1251 return err; 1252 } 1253 } 1254 1255 #else 1256 /* Trick, I use pUserData to retrieve aac properties, 1257 waiting for some better implementation... */ 1258 1259 if( M4DA_StreamTypeAudioAac == audiotype ) 1260 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec( 1261 &pClipCtxt->pAudioDecCtxt, 1262 pClipCtxt->pAudioStream, &(pClipCtxt->AacProperties)); 1263 else 1264 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec( 1265 &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream, 1266 M4OSA_NULL /* to be changed with HW interfaces */); 1267 1268 if( M4NO_ERROR != err ) 1269 { 1270 M4OSA_TRACE1_1( 1271 "M4VSS3GPP_intClipPrepareAudioDecoder:\ 1272 m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x", 1273 err); 1274 return err; 1275 } 1276 1277 #endif 1278 1279 } 1280 1281 if( M4DA_StreamTypeAudioAmrNarrowBand == audiotype ) { 1282 /* AMR DECODER CONFIGURATION */ 1283 1284 /* nothing specific to do */ 1285 } 1286 else if( M4DA_StreamTypeAudioEvrc == audiotype ) { 1287 /* EVRC DECODER CONFIGURATION */ 1288 1289 /* nothing specific to do */ 1290 } 1291 else if( M4DA_StreamTypeAudioMp3 == audiotype ) { 1292 /* MP3 DECODER CONFIGURATION */ 1293 1294 /* nothing specific to do */ 1295 } 1296 else if( M4DA_StreamTypeAudioAac == audiotype ) 1297 { 1298 /* AAC DECODER CONFIGURATION */ 1299 1300 /* Decode high quality aac but disable PS and SBR */ 1301 /* Because we have to mix different kind of AAC so we must take the lowest capability */ 1302 /* In MCS it was not needed because there is only one stream */ 1303 M4_AacDecoderConfig AacDecParam; 1304 1305 AacDecParam.m_AACDecoderProfile = AAC_kAAC; 1306 AacDecParam.m_DownSamplingMode = AAC_kDS_OFF; 1307 1308 if( M4ENCODER_kMono == pClipCtxt->pAudioStream->m_nbChannels ) 1309 { 1310 AacDecParam.m_OutputMode = AAC_kMono; 1311 } 1312 else 1313 { 1314 AacDecParam.m_OutputMode = AAC_kStereo; 1315 } 1316 1317 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec( 1318 pClipCtxt->pAudioDecCtxt, 1319 M4AD_kOptionID_UserParam, (M4OSA_DataOption) &AacDecParam); 1320 } 1321 1322 if( M4OSA_NULL != pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec ) { 1323 pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec( 1324 pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_3gpReaderInterface, 1325 (M4OSA_DataOption) pClipCtxt->ShellAPI.m_pReaderDataIt); 1326 1327 pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec( 1328 pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_AudioAU, 1329 (M4OSA_DataOption) &pClipCtxt->AudioAU); 1330 } 1331 1332 if( M4OSA_NULL != pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec ) 1333 { 1334 /* Not implemented in all decoders */ 1335 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec( 1336 pClipCtxt->pAudioDecCtxt); 1337 1338 if( M4NO_ERROR != err ) 1339 { 1340 M4OSA_TRACE1_1( 1341 "M4VSS3GPP_intClipPrepareAudioDecoder:\ 1342 m_pAudioDecoder->m_pFctStartAudioDec returns 0x%x", 1343 err); 1344 return err; 1345 } 1346 } 1347 1348 /** 1349 * Allocate output buffer for the audio decoder */ 1350 pClipCtxt->AudioDecBufferOut.m_bufferSize = 1351 pClipCtxt->pAudioStream->m_byteFrameLength 1352 * pClipCtxt->pAudioStream->m_byteSampleSize 1353 * pClipCtxt->pAudioStream->m_nbChannels; 1354 pClipCtxt->AudioDecBufferOut.m_dataAddress = 1355 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pClipCtxt->AudioDecBufferOut.m_bufferSize 1356 * sizeof(M4OSA_Int16), 1357 M4VSS3GPP, (M4OSA_Char *)"AudioDecBufferOut.m_bufferSize"); 1358 1359 if( M4OSA_NULL == pClipCtxt->AudioDecBufferOut.m_dataAddress ) 1360 { 1361 M4OSA_TRACE1_0( 1362 "M4VSS3GPP_intClipPrepareAudioDecoder():\ 1363 unable to allocate AudioDecBufferOut.m_dataAddress, returning M4ERR_ALLOC"); 1364 return M4ERR_ALLOC; 1365 } 1366 1367 return M4NO_ERROR; 1368 } 1369 1370 /** 1371 ****************************************************************************** 1372 * M4OSA_ERR M4VSS3GPP_intClipDecodeCurrentAudioFrame() 1373 * @brief Decode the current AUDIO frame. 1374 * @note 1375 * @param pClipCtxt (IN) internal clip context 1376 * @return M4NO_ERROR: No error 1377 ****************************************************************************** 1378 */ 1379 M4OSA_ERR M4VSS3GPP_intClipDecodeCurrentAudioFrame( 1380 M4VSS3GPP_ClipContext *pClipCtxt ) 1381 { 1382 M4OSA_ERR err; 1383 1384 /** 1385 * Silence mode */ 1386 if( pClipCtxt->pSilenceFrameData 1387 == (M4OSA_UInt8 *)pClipCtxt->pAudioFramePtr ) 1388 { 1389 if( pClipCtxt->AudioDecBufferOut.m_dataAddress == M4OSA_NULL ) 1390 { 1391 /** 1392 * Allocate output buffer for the audio decoder */ 1393 pClipCtxt->AudioDecBufferOut.m_bufferSize = 1394 pClipCtxt->uiSilencePcmSize; 1395 pClipCtxt->AudioDecBufferOut.m_dataAddress = 1396 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc( 1397 pClipCtxt->AudioDecBufferOut.m_bufferSize 1398 * sizeof(M4OSA_Int16), 1399 M4VSS3GPP,(M4OSA_Char *) "AudioDecBufferOut.m_bufferSize"); 1400 1401 if( M4OSA_NULL == pClipCtxt->AudioDecBufferOut.m_dataAddress ) 1402 { 1403 M4OSA_TRACE1_0( 1404 "M4VSS3GPP_intClipDecodeCurrentAudioFrame():\ 1405 unable to allocate AudioDecBufferOut.m_dataAddress, returning M4ERR_ALLOC"); 1406 return M4ERR_ALLOC; 1407 } 1408 } 1409 1410 /* Fill it with 0 (= pcm silence) */ 1411 memset(pClipCtxt->AudioDecBufferOut.m_dataAddress,0, 1412 pClipCtxt->AudioDecBufferOut.m_bufferSize * sizeof(M4OSA_Int16)); 1413 } 1414 else if (pClipCtxt->pSettings->FileType == M4VIDEOEDITING_kFileType_PCM) 1415 { 1416 pClipCtxt->AudioDecBufferIn.m_dataAddress = (M4OSA_MemAddr8) pClipCtxt->pAudioFramePtr; 1417 pClipCtxt->AudioDecBufferIn.m_bufferSize = pClipCtxt->uiAudioFrameSize; 1418 1419 memcpy((void *)pClipCtxt->AudioDecBufferOut.m_dataAddress, 1420 (void *)pClipCtxt->AudioDecBufferIn.m_dataAddress, pClipCtxt->AudioDecBufferIn.m_bufferSize); 1421 pClipCtxt->AudioDecBufferOut.m_bufferSize = pClipCtxt->AudioDecBufferIn.m_bufferSize; 1422 /** 1423 * Return with no error */ 1424 1425 M4OSA_TRACE3_0("M4VSS3GPP_intClipDecodeCurrentAudioFrame(): returning M4NO_ERROR"); 1426 return M4NO_ERROR; 1427 } 1428 /** 1429 * Standard decoding mode */ 1430 else 1431 { 1432 /** 1433 * Decode current AMR frame */ 1434 if ( pClipCtxt->pAudioFramePtr != M4OSA_NULL ) { 1435 pClipCtxt->AudioDecBufferIn.m_dataAddress = 1436 (M4OSA_MemAddr8)pClipCtxt->pAudioFramePtr; 1437 pClipCtxt->AudioDecBufferIn.m_bufferSize = 1438 pClipCtxt->uiAudioFrameSize; 1439 pClipCtxt->AudioDecBufferIn.m_timeStampUs = 1440 (int64_t) (pClipCtxt->iAudioFrameCts * 1000LL); 1441 1442 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec( 1443 pClipCtxt->pAudioDecCtxt, 1444 &pClipCtxt->AudioDecBufferIn, &pClipCtxt->AudioDecBufferOut, 1445 M4OSA_FALSE); 1446 } else { 1447 // Pass Null input buffer 1448 // Reader invoked from Audio decoder source 1449 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec( 1450 pClipCtxt->pAudioDecCtxt, 1451 M4OSA_NULL, &pClipCtxt->AudioDecBufferOut, 1452 M4OSA_FALSE); 1453 } 1454 1455 if( M4NO_ERROR != err ) 1456 { 1457 M4OSA_TRACE1_1( 1458 "M4VSS3GPP_intClipDecodeCurrentAudioFrame():\ 1459 m_pAudioDecoder->m_pFctStepAudio returns 0x%x", 1460 err); 1461 return err; 1462 } 1463 } 1464 1465 /** 1466 * Return with no error */ 1467 M4OSA_TRACE3_0( 1468 "M4VSS3GPP_intClipDecodeCurrentAudioFrame(): returning M4NO_ERROR"); 1469 return M4NO_ERROR; 1470 } 1471 1472 /** 1473 ****************************************************************************** 1474 * M4OSA_ERR M4VSS3GPP_intClipJumpAudioAt() 1475 * @brief Jump in the audio track of the clip. 1476 * @note 1477 * @param pClipCtxt (IN) internal clip context 1478 * @param pJumpCts (IN/OUT) in:target CTS, out: reached CTS 1479 * @return M4NO_ERROR: No error 1480 ****************************************************************************** 1481 */ 1482 M4OSA_ERR M4VSS3GPP_intClipJumpAudioAt( M4VSS3GPP_ClipContext *pClipCtxt, 1483 M4OSA_Int32 *pJumpCts ) 1484 { 1485 M4OSA_ERR err; 1486 M4OSA_Int32 iTargetCts; 1487 M4OSA_Int32 iJumpCtsMs; 1488 1489 /** 1490 * Check input parameters */ 1491 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER, 1492 "M4VSS3GPP_intClipJumpAudioAt: pClipCtxt is M4OSA_NULL"); 1493 M4OSA_DEBUG_IF2((M4OSA_NULL == pJumpCts), M4ERR_PARAMETER, 1494 "M4VSS3GPP_intClipJumpAudioAt: pJumpCts is M4OSA_NULL"); 1495 1496 iTargetCts = *pJumpCts; 1497 1498 /** 1499 * If there is no audio stream, we simulate a jump at the target jump CTS */ 1500 if( M4OSA_NULL == pClipCtxt->pAudioStream ) 1501 { 1502 /** 1503 * the target CTS will be reached at next ReadFrame call (thus the -20) */ 1504 *pJumpCts = iTargetCts - pClipCtxt->iSilenceFrameDuration; 1505 1506 /* Patch because m_CTS is unfortunately rounded in 3gp reader shell */ 1507 /* (cts is not an integer with frequency 24 kHz for example) */ 1508 *pJumpCts = ( ( *pJumpCts + pClipCtxt->iSilenceFrameDuration / 2) 1509 / pClipCtxt->iSilenceFrameDuration) 1510 * pClipCtxt->iSilenceFrameDuration; 1511 pClipCtxt->iAudioFrameCts = 1512 * 1513 pJumpCts; /* simulate a read at jump position for later silence AUs */ 1514 } 1515 else 1516 { 1517 M4OSA_Int32 current_time = 0; 1518 M4OSA_Int32 loop_counter = 0; 1519 1520 if( (M4DA_StreamTypeAudioMp3 1521 == pClipCtxt->pAudioStream->m_basicProperties.m_streamType) ) 1522 { 1523 while( ( loop_counter < M4VSS3GPP_MP3_JUMPED_AU_NUMBER_MAX) 1524 && (current_time < iTargetCts) ) 1525 { 1526 err = pClipCtxt->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu( 1527 pClipCtxt->pReaderContext, 1528 (M4_StreamHandler *)pClipCtxt->pAudioStream, 1529 &pClipCtxt->AudioAU); 1530 1531 if( M4NO_ERROR != err ) 1532 { 1533 M4OSA_TRACE3_1( 1534 "M4VSS3GPP_intClipJumpAudioAt: m_pFctGetNextAu() returns 0x%x", 1535 err); 1536 return err; 1537 } 1538 1539 current_time = (M4OSA_Int32)pClipCtxt->AudioAU.m_CTS; 1540 loop_counter++; 1541 } 1542 1543 /** 1544 * The current AU is stored */ 1545 pClipCtxt->pAudioFramePtr = pClipCtxt->AudioAU.m_dataAddress; 1546 pClipCtxt->uiAudioFrameSize = 1547 (M4OSA_UInt16)pClipCtxt->AudioAU.m_size; 1548 pClipCtxt->iAudioFrameCts = 1549 (M4OSA_Int32)(pClipCtxt->AudioAU.m_CTS * pClipCtxt->scale_audio 1550 + 0.5); 1551 1552 *pJumpCts = pClipCtxt->iAudioFrameCts; 1553 } 1554 else 1555 { 1556 /** 1557 * Jump in the audio stream */ 1558 iJumpCtsMs = 1559 (M4OSA_Int32)(*pJumpCts / pClipCtxt->scale_audio + 0.5); 1560 1561 err = pClipCtxt->ShellAPI.m_pReader->m_pFctJump( 1562 pClipCtxt->pReaderContext, 1563 (M4_StreamHandler *)pClipCtxt->pAudioStream, 1564 &iJumpCtsMs); 1565 1566 if( M4NO_ERROR != err ) 1567 { 1568 M4OSA_TRACE1_1( 1569 "M4VSS3GPP_intClipJumpAudioAt(): m_pFctJump() returns 0x%x", 1570 err); 1571 return err; 1572 } 1573 1574 *pJumpCts = 1575 (M4OSA_Int32)(iJumpCtsMs * pClipCtxt->scale_audio + 0.5); 1576 1577 /* Patch because m_CTS is unfortunately rounded in 3gp reader shell */ 1578 /* (cts is not an integer with frequency 24 kHz for example) */ 1579 *pJumpCts = ( ( *pJumpCts + pClipCtxt->iSilenceFrameDuration / 2) 1580 / pClipCtxt->iSilenceFrameDuration) 1581 * pClipCtxt->iSilenceFrameDuration; 1582 pClipCtxt->iAudioFrameCts = 0; /* No frame read yet */ 1583 1584 /** 1585 * To detect some may-be bugs, I prefer to reset all these after a jump */ 1586 pClipCtxt->bAudioFrameAvailable = M4OSA_FALSE; 1587 pClipCtxt->pAudioFramePtr = M4OSA_NULL; 1588 1589 /** 1590 * In AMR, we have to manage multi-framed AUs, 1591 but also in AAC the jump can be 1 AU too much backward */ 1592 if( *pJumpCts < iTargetCts ) 1593 { 1594 /** 1595 * Jump doesn't read any AU, we must read at least one */ 1596 err = M4VSS3GPP_intClipReadNextAudioFrame(pClipCtxt); 1597 1598 if( M4OSA_ERR_IS_ERROR(err) ) 1599 { 1600 M4OSA_TRACE1_1( 1601 "M4VSS3GPP_intClipJumpAudioAt():\ 1602 M4VSS3GPP_intClipReadNextAudioFrame(a) returns 0x%x", 1603 err); 1604 return err; 1605 } 1606 1607 /** 1608 * Read AU frames as long as we reach the AU before the target CTS 1609 * (so the target will be reached when the user call ReadNextAudioFrame). */ 1610 while( pClipCtxt->iAudioFrameCts 1611 < (iTargetCts - pClipCtxt->iSilenceFrameDuration) ) 1612 { 1613 err = M4VSS3GPP_intClipReadNextAudioFrame(pClipCtxt); 1614 1615 if( M4OSA_ERR_IS_ERROR(err) ) 1616 { 1617 M4OSA_TRACE1_1( 1618 "M4VSS3GPP_intClipJumpAudioAt():\ 1619 M4VSS3GPP_intClipReadNextAudioFrame(b) returns 0x%x", 1620 err); 1621 return err; 1622 } 1623 } 1624 1625 /** 1626 * Return the CTS that will be reached at next ReadFrame */ 1627 *pJumpCts = pClipCtxt->iAudioFrameCts 1628 + pClipCtxt->iSilenceFrameDuration; 1629 } 1630 } 1631 } 1632 1633 /** 1634 * Return with no error */ 1635 M4OSA_TRACE3_0("M4VSS3GPP_intClipJumpAudioAt(): returning M4NO_ERROR"); 1636 return M4NO_ERROR; 1637 } 1638 1639 /** 1640 ****************************************************************************** 1641 * M4OSA_ERR M4VSS3GPP_intClipClose() 1642 * @brief Close a clip. Destroy the context. 1643 * @note 1644 * @param pClipCtxt (IN) Internal clip context 1645 * @return M4NO_ERROR: No error 1646 ****************************************************************************** 1647 */ 1648 M4OSA_ERR M4VSS3GPP_intClipClose( M4VSS3GPP_ClipContext *pClipCtxt ) 1649 { 1650 M4OSA_ERR err; 1651 1652 /** 1653 * Check input parameters */ 1654 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER, 1655 "M4VSS3GPP_intClipClose: pClipCtxt is M4OSA_NULL"); 1656 1657 /** 1658 * Free the video decoder context */ 1659 if( M4OSA_NULL != pClipCtxt->pViDecCtxt ) 1660 { 1661 pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctDestroy( 1662 pClipCtxt->pViDecCtxt); 1663 pClipCtxt->pViDecCtxt = M4OSA_NULL; 1664 } 1665 1666 /** 1667 * Free the audio decoder context */ 1668 if( M4OSA_NULL != pClipCtxt->pAudioDecCtxt ) 1669 { 1670 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctDestroyAudioDec( 1671 pClipCtxt->pAudioDecCtxt); 1672 1673 if( M4NO_ERROR != err ) 1674 { 1675 M4OSA_TRACE1_1( 1676 "M4VSS3GPP_intClipClose: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x", 1677 err); 1678 /**< don't return, we still have stuff to free */ 1679 } 1680 1681 pClipCtxt->pAudioDecCtxt = M4OSA_NULL; 1682 } 1683 1684 /** 1685 * Free the decoded audio buffer */ 1686 if( M4OSA_NULL != pClipCtxt->AudioDecBufferOut.m_dataAddress ) 1687 { 1688 free(pClipCtxt->AudioDecBufferOut.m_dataAddress); 1689 pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL; 1690 } 1691 1692 /** 1693 * Audio AU is allocated by reader. 1694 * If no audio track, audio AU is set at 'silent' (SID) by VSS. 1695 * As a consequence, if audio AU is set to 'silent' (static) 1696 it can't be free unless it is set to NULL */ 1697 if( ( (M4OSA_MemAddr8)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048 1698 == pClipCtxt->AudioAU.m_dataAddress) 1699 || ((M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData 1700 == pClipCtxt->AudioAU.m_dataAddress) ) 1701 { 1702 pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL; 1703 } 1704 1705 if( M4OSA_NULL != pClipCtxt->pReaderContext ) 1706 { 1707 /** 1708 * Close the 3GPP or MP3 reader */ 1709 err = pClipCtxt->ShellAPI.m_pReader->m_pFctClose( 1710 pClipCtxt->pReaderContext); 1711 1712 if( M4NO_ERROR != err ) 1713 { 1714 M4OSA_TRACE1_1( 1715 "M4VSS3GPP_intClipClose(): m_pReader->m_pFctClose returns 0x%x", 1716 err); 1717 } 1718 1719 /** 1720 * Destroy the 3GPP or MP3 reader context */ 1721 err = pClipCtxt->ShellAPI.m_pReader->m_pFctDestroy( 1722 pClipCtxt->pReaderContext); 1723 1724 if( M4NO_ERROR != err ) 1725 { 1726 M4OSA_TRACE1_1( 1727 "M4VSS3GPP_intClipClose(): m_pReader->m_pFctDestroy returns 0x%x", 1728 err); 1729 } 1730 1731 pClipCtxt->pReaderContext = M4OSA_NULL; 1732 } 1733 1734 /** 1735 * Return with no error */ 1736 M4OSA_TRACE3_1("M4VSS3GPP_intClipClose(Ctxt=0x%x): returning M4NO_ERROR", 1737 pClipCtxt); 1738 return M4NO_ERROR; 1739 } 1740 1741 M4OSA_ERR M4VSS3GPP_intClipCleanUp( M4VSS3GPP_ClipContext *pClipCtxt ) 1742 { 1743 M4OSA_ERR err = M4NO_ERROR, err2; 1744 1745 /** 1746 * Check input parameters */ 1747 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER, 1748 "M4VSS3GPP_intClipCleanUp: pClipCtxt is M4OSA_NULL"); 1749 1750 /** 1751 * Free the video decoder context */ 1752 if( M4OSA_NULL != pClipCtxt->pViDecCtxt ) 1753 { 1754 pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctDestroy( 1755 pClipCtxt->pViDecCtxt); 1756 pClipCtxt->pViDecCtxt = M4OSA_NULL; 1757 } 1758 1759 /** 1760 * Free the audio decoder context */ 1761 if( M4OSA_NULL != pClipCtxt->pAudioDecCtxt ) 1762 { 1763 err2 = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctDestroyAudioDec( 1764 pClipCtxt->pAudioDecCtxt); 1765 1766 if( M4NO_ERROR != err2 ) 1767 { 1768 M4OSA_TRACE1_1( 1769 "M4VSS3GPP_intClipCleanUp: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x", 1770 err); 1771 /**< don't return, we still have stuff to free */ 1772 if( M4NO_ERROR != err ) 1773 err = err2; 1774 } 1775 1776 pClipCtxt->pAudioDecCtxt = M4OSA_NULL; 1777 } 1778 1779 /** 1780 * Free the decoded audio buffer */ 1781 if( M4OSA_NULL != pClipCtxt->AudioDecBufferOut.m_dataAddress ) 1782 { 1783 free(pClipCtxt->AudioDecBufferOut.m_dataAddress); 1784 pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL; 1785 } 1786 1787 /** 1788 * Audio AU is allocated by reader. 1789 * If no audio track, audio AU is set at 'silent' (SID) by VSS. 1790 * As a consequence, if audio AU is set to 'silent' (static) 1791 it can't be free unless it is set to NULL */ 1792 if( ( (M4OSA_MemAddr8)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048 1793 == pClipCtxt->AudioAU.m_dataAddress) 1794 || ((M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData 1795 == pClipCtxt->AudioAU.m_dataAddress) ) 1796 { 1797 pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL; 1798 } 1799 1800 if( M4OSA_NULL != pClipCtxt->pReaderContext ) 1801 { 1802 /** 1803 * Close the 3GPP or MP3 reader */ 1804 err2 = pClipCtxt->ShellAPI.m_pReader->m_pFctClose( 1805 pClipCtxt->pReaderContext); 1806 1807 if( M4NO_ERROR != err2 ) 1808 { 1809 M4OSA_TRACE1_1( 1810 "M4VSS3GPP_intClipCleanUp(): m_pReader->m_pFctClose returns 0x%x", 1811 err); 1812 1813 if( M4NO_ERROR != err ) 1814 err = err2; 1815 } 1816 1817 /** 1818 * Destroy the 3GPP or MP3 reader context */ 1819 err2 = pClipCtxt->ShellAPI.m_pReader->m_pFctDestroy( 1820 pClipCtxt->pReaderContext); 1821 1822 if( M4NO_ERROR != err2 ) 1823 { 1824 M4OSA_TRACE1_1( 1825 "M4VSS3GPP_intClipCleanUp(): m_pReader->m_pFctDestroy returns 0x%x", 1826 err); 1827 1828 if( M4NO_ERROR != err ) 1829 err = err2; 1830 } 1831 1832 pClipCtxt->pReaderContext = M4OSA_NULL; 1833 } 1834 1835 if(pClipCtxt->pPlaneYuv != M4OSA_NULL) { 1836 if(pClipCtxt->pPlaneYuv[0].pac_data != M4OSA_NULL) { 1837 free(pClipCtxt->pPlaneYuv[0].pac_data); 1838 pClipCtxt->pPlaneYuv[0].pac_data = M4OSA_NULL; 1839 } 1840 free(pClipCtxt->pPlaneYuv); 1841 pClipCtxt->pPlaneYuv = M4OSA_NULL; 1842 } 1843 1844 if(pClipCtxt->pPlaneYuvWithEffect != M4OSA_NULL) { 1845 if(pClipCtxt->pPlaneYuvWithEffect[0].pac_data != M4OSA_NULL) { 1846 free(pClipCtxt->pPlaneYuvWithEffect[0].pac_data); 1847 pClipCtxt->pPlaneYuvWithEffect[0].pac_data = M4OSA_NULL; 1848 } 1849 free(pClipCtxt->pPlaneYuvWithEffect); 1850 pClipCtxt->pPlaneYuvWithEffect = M4OSA_NULL; 1851 } 1852 /** 1853 * Free the shells interfaces */ 1854 M4VSS3GPP_unRegisterAllWriters(&pClipCtxt->ShellAPI); 1855 M4VSS3GPP_unRegisterAllEncoders(&pClipCtxt->ShellAPI); 1856 M4VSS3GPP_unRegisterAllReaders(&pClipCtxt->ShellAPI); 1857 M4VSS3GPP_unRegisterAllDecoders(&pClipCtxt->ShellAPI); 1858 1859 M4OSA_TRACE3_1("M4VSS3GPP_intClipCleanUp: pClipCtxt=0x%x", pClipCtxt); 1860 /** 1861 * Free the clip context */ 1862 free(pClipCtxt); 1863 1864 return err; 1865 } 1866 1867 /** 1868 ****************************************************************************** 1869 * M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_AMRNB() 1870 * @brief Return the length, in bytes, of the AMR Narrow-Band frame contained in the given buffer 1871 * @note 1872 * @param pAudioFrame (IN) AMRNB frame 1873 * @return M4NO_ERROR: No error 1874 ****************************************************************************** 1875 */ 1876 1877 M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_AMRNB( M4OSA_MemAddr8 pAudioFrame ) 1878 { 1879 M4OSA_UInt32 frameSize = 0; 1880 M4OSA_UInt32 frameType = ( ( *pAudioFrame) &(0xF << 3)) >> 3; 1881 1882 switch( frameType ) 1883 { 1884 case 0: 1885 frameSize = 95; 1886 break; /* 4750 bps */ 1887 1888 case 1: 1889 frameSize = 103; 1890 break; /* 5150 bps */ 1891 1892 case 2: 1893 frameSize = 118; 1894 break; /* 5900 bps */ 1895 1896 case 3: 1897 frameSize = 134; 1898 break; /* 6700 bps */ 1899 1900 case 4: 1901 frameSize = 148; 1902 break; /* 7400 bps */ 1903 1904 case 5: 1905 frameSize = 159; 1906 break; /* 7950 bps */ 1907 1908 case 6: 1909 frameSize = 204; 1910 break; /* 10200 bps */ 1911 1912 case 7: 1913 frameSize = 244; 1914 break; /* 12000 bps */ 1915 1916 case 8: 1917 frameSize = 39; 1918 break; /* SID (Silence) */ 1919 1920 case 15: 1921 frameSize = 0; 1922 break; /* No data */ 1923 1924 default: 1925 M4OSA_TRACE3_0( 1926 "M4VSS3GPP_intGetFrameSize_AMRNB(): Corrupted AMR frame! returning 0."); 1927 return 0; 1928 } 1929 1930 return (1 + (( frameSize + 7) / 8)); 1931 } 1932 1933 /** 1934 ****************************************************************************** 1935 * M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_EVRC() 1936 * @brief Return the length, in bytes, of the EVRC frame contained in the given buffer 1937 * @note 1938 * 0 1 2 3 1939 * +-+-+-+-+ 1940 * |fr type| RFC 3558 1941 * +-+-+-+-+ 1942 * 1943 * Frame Type: 4 bits 1944 * The frame type indicates the type of the corresponding codec data 1945 * frame in the RTP packet. 1946 * 1947 * For EVRC and SMV codecs, the frame type values and size of the 1948 * associated codec data frame are described in the table below: 1949 * 1950 * Value Rate Total codec data frame size (in octets) 1951 * --------------------------------------------------------- 1952 * 0 Blank 0 (0 bit) 1953 * 1 1/8 2 (16 bits) 1954 * 2 1/4 5 (40 bits; not valid for EVRC) 1955 * 3 1/2 10 (80 bits) 1956 * 4 1 22 (171 bits; 5 padded at end with zeros) 1957 * 5 Erasure 0 (SHOULD NOT be transmitted by sender) 1958 * 1959 * @param pCpAudioFrame (IN) EVRC frame 1960 * @return M4NO_ERROR: No error 1961 ****************************************************************************** 1962 */ 1963 M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_EVRC( M4OSA_MemAddr8 pAudioFrame ) 1964 { 1965 M4OSA_UInt32 frameSize = 0; 1966 M4OSA_UInt32 frameType = ( *pAudioFrame) &0x0F; 1967 1968 switch( frameType ) 1969 { 1970 case 0: 1971 frameSize = 0; 1972 break; /* blank */ 1973 1974 case 1: 1975 frameSize = 16; 1976 break; /* 1/8 */ 1977 1978 case 2: 1979 frameSize = 40; 1980 break; /* 1/4 */ 1981 1982 case 3: 1983 frameSize = 80; 1984 break; /* 1/2 */ 1985 1986 case 4: 1987 frameSize = 171; 1988 break; /* 1 */ 1989 1990 case 5: 1991 frameSize = 0; 1992 break; /* erasure */ 1993 1994 default: 1995 M4OSA_TRACE3_0( 1996 "M4VSS3GPP_intGetFrameSize_EVRC(): Corrupted EVRC frame! returning 0."); 1997 return 0; 1998 } 1999 2000 return (1 + (( frameSize + 7) / 8)); 2001 } 2002 2003 M4OSA_ERR M4VSS3GPP_intCheckAndGetCodecAacProperties( 2004 M4VSS3GPP_ClipContext *pClipCtxt) { 2005 2006 M4OSA_ERR err = M4NO_ERROR; 2007 M4AD_Buffer outputBuffer; 2008 uint32_t optionValue =0; 2009 2010 // Decode first audio frame from clip to get properties from codec 2011 2012 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec( 2013 &pClipCtxt->pAudioDecCtxt, 2014 pClipCtxt->pAudioStream, &(pClipCtxt->AacProperties)); 2015 2016 pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec( 2017 pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_3gpReaderInterface, 2018 (M4OSA_DataOption) pClipCtxt->ShellAPI.m_pReaderDataIt); 2019 2020 pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec( 2021 pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_AudioAU, 2022 (M4OSA_DataOption) &pClipCtxt->AudioAU); 2023 2024 if( pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) { 2025 2026 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec( 2027 pClipCtxt->pAudioDecCtxt); 2028 if( M4NO_ERROR != err ) { 2029 2030 M4OSA_TRACE1_1( 2031 "M4VSS3GPP_intCheckAndGetCodecAacProperties: \ 2032 m_pFctStartAudioDec returns 0x%x", err); 2033 return err; 2034 } 2035 } 2036 2037 /** 2038 * Allocate output buffer for the audio decoder */ 2039 outputBuffer.m_bufferSize = 2040 pClipCtxt->pAudioStream->m_byteFrameLength 2041 * pClipCtxt->pAudioStream->m_byteSampleSize 2042 * pClipCtxt->pAudioStream->m_nbChannels; 2043 2044 if( outputBuffer.m_bufferSize > 0 ) { 2045 2046 outputBuffer.m_dataAddress = 2047 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(outputBuffer.m_bufferSize \ 2048 *sizeof(short), M4VSS3GPP, (M4OSA_Char *)"outputBuffer.m_bufferSize"); 2049 2050 if( M4OSA_NULL == outputBuffer.m_dataAddress ) { 2051 2052 M4OSA_TRACE1_0( 2053 "M4VSS3GPP_intCheckAndGetCodecAacProperties():\ 2054 unable to allocate outputBuffer.m_dataAddress"); 2055 return M4ERR_ALLOC; 2056 } 2057 } 2058 2059 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec( 2060 pClipCtxt->pAudioDecCtxt, M4OSA_NULL, &outputBuffer, M4OSA_FALSE); 2061 2062 if ( err == M4WAR_INFO_FORMAT_CHANGE ) { 2063 2064 // Get the properties from codec node 2065 pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctGetOptionAudioDec( 2066 pClipCtxt->pAudioDecCtxt, 2067 M4AD_kOptionID_AudioNbChannels, (M4OSA_DataOption) &optionValue); 2068 2069 pClipCtxt->AacProperties.aNumChan = optionValue; 2070 // Reset Reader structure value also 2071 pClipCtxt->pAudioStream->m_nbChannels = optionValue; 2072 2073 pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctGetOptionAudioDec( 2074 pClipCtxt->pAudioDecCtxt, 2075 M4AD_kOptionID_AudioSampFrequency, (M4OSA_DataOption) &optionValue); 2076 2077 pClipCtxt->AacProperties.aSampFreq = optionValue; 2078 // Reset Reader structure value also 2079 pClipCtxt->pAudioStream->m_samplingFrequency = optionValue; 2080 2081 } else if( err != M4NO_ERROR) { 2082 M4OSA_TRACE1_1("M4VSS3GPP_intCheckAndGetCodecAacProperties:\ 2083 m_pFctStepAudioDec returns err = 0x%x", err); 2084 } 2085 2086 free(outputBuffer.m_dataAddress); 2087 2088 // Reset the stream reader 2089 err = pClipCtxt->ShellAPI.m_pReader->m_pFctReset( 2090 pClipCtxt->pReaderContext, 2091 (M4_StreamHandler *)pClipCtxt->pAudioStream); 2092 2093 if (M4NO_ERROR != err) { 2094 M4OSA_TRACE1_1("M4VSS3GPP_intCheckAndGetCodecAacProperties\ 2095 Error in reseting reader: 0x%x", err); 2096 } 2097 2098 return err; 2099 2100 } 2101