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