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