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