M4VSS3GPP_Clip.c revision 01158eac3464fc6e7837be594d6a8d14172154bc
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 pClipCtxt->AudioDecBufferIn.m_timeStampUs = 1419 (int64_t) (pClipCtxt->iAudioFrameCts * 1000LL); 1420 1421 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec( 1422 pClipCtxt->pAudioDecCtxt, 1423 &pClipCtxt->AudioDecBufferIn, &pClipCtxt->AudioDecBufferOut, 1424 M4OSA_FALSE); 1425 1426 if( M4NO_ERROR != err ) 1427 { 1428 M4OSA_TRACE1_1( 1429 "M4VSS3GPP_intClipDecodeCurrentAudioFrame():\ 1430 m_pAudioDecoder->m_pFctStepAudio returns 0x%x", 1431 err); 1432 return err; 1433 } 1434 } 1435 1436 /** 1437 * Return with no error */ 1438 M4OSA_TRACE3_0( 1439 "M4VSS3GPP_intClipDecodeCurrentAudioFrame(): returning M4NO_ERROR"); 1440 return M4NO_ERROR; 1441} 1442 1443/** 1444 ****************************************************************************** 1445 * M4OSA_ERR M4VSS3GPP_intClipJumpAudioAt() 1446 * @brief Jump in the audio track of the clip. 1447 * @note 1448 * @param pClipCtxt (IN) internal clip context 1449 * @param pJumpCts (IN/OUT) in:target CTS, out: reached CTS 1450 * @return M4NO_ERROR: No error 1451 ****************************************************************************** 1452 */ 1453M4OSA_ERR M4VSS3GPP_intClipJumpAudioAt( M4VSS3GPP_ClipContext *pClipCtxt, 1454 M4OSA_Int32 *pJumpCts ) 1455{ 1456 M4OSA_ERR err; 1457 M4OSA_Int32 iTargetCts; 1458 M4OSA_Int32 iJumpCtsMs; 1459 1460 /** 1461 * Check input parameters */ 1462 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER, 1463 "M4VSS3GPP_intClipJumpAudioAt: pClipCtxt is M4OSA_NULL"); 1464 M4OSA_DEBUG_IF2((M4OSA_NULL == pJumpCts), M4ERR_PARAMETER, 1465 "M4VSS3GPP_intClipJumpAudioAt: pJumpCts is M4OSA_NULL"); 1466 1467 iTargetCts = *pJumpCts; 1468 1469 /** 1470 * If there is no audio stream, we simulate a jump at the target jump CTS */ 1471 if( M4OSA_NULL == pClipCtxt->pAudioStream ) 1472 { 1473 /** 1474 * the target CTS will be reached at next ReadFrame call (thus the -20) */ 1475 *pJumpCts = iTargetCts - pClipCtxt->iSilenceFrameDuration; 1476 1477 /* Patch because m_CTS is unfortunately rounded in 3gp reader shell */ 1478 /* (cts is not an integer with frequency 24 kHz for example) */ 1479 *pJumpCts = ( ( *pJumpCts + pClipCtxt->iSilenceFrameDuration / 2) 1480 / pClipCtxt->iSilenceFrameDuration) 1481 * pClipCtxt->iSilenceFrameDuration; 1482 pClipCtxt->iAudioFrameCts = 1483 * 1484 pJumpCts; /* simulate a read at jump position for later silence AUs */ 1485 } 1486 else 1487 { 1488 M4OSA_Int32 current_time = 0; 1489 M4OSA_Int32 loop_counter = 0; 1490 1491 if( (M4DA_StreamTypeAudioMp3 1492 == pClipCtxt->pAudioStream->m_basicProperties.m_streamType) ) 1493 { 1494 while( ( loop_counter < M4VSS3GPP_MP3_JUMPED_AU_NUMBER_MAX) 1495 && (current_time < iTargetCts) ) 1496 { 1497 err = pClipCtxt->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu( 1498 pClipCtxt->pReaderContext, 1499 (M4_StreamHandler *)pClipCtxt->pAudioStream, 1500 &pClipCtxt->AudioAU); 1501 1502 if( M4NO_ERROR != err ) 1503 { 1504 M4OSA_TRACE3_1( 1505 "M4VSS3GPP_intClipJumpAudioAt: m_pFctGetNextAu() returns 0x%x", 1506 err); 1507 return err; 1508 } 1509 1510 current_time = (M4OSA_Int32)pClipCtxt->AudioAU.m_CTS; 1511 loop_counter++; 1512 } 1513 1514 /** 1515 * The current AU is stored */ 1516 pClipCtxt->pAudioFramePtr = pClipCtxt->AudioAU.m_dataAddress; 1517 pClipCtxt->uiAudioFrameSize = 1518 (M4OSA_UInt16)pClipCtxt->AudioAU.m_size; 1519 pClipCtxt->iAudioFrameCts = 1520 (M4OSA_Int32)(pClipCtxt->AudioAU.m_CTS * pClipCtxt->scale_audio 1521 + 0.5); 1522 1523 *pJumpCts = pClipCtxt->iAudioFrameCts; 1524 } 1525 else 1526 { 1527 /** 1528 * Jump in the audio stream */ 1529 iJumpCtsMs = 1530 (M4OSA_Int32)(*pJumpCts / pClipCtxt->scale_audio + 0.5); 1531 1532 err = pClipCtxt->ShellAPI.m_pReader->m_pFctJump( 1533 pClipCtxt->pReaderContext, 1534 (M4_StreamHandler *)pClipCtxt->pAudioStream, 1535 &iJumpCtsMs); 1536 1537 if( M4NO_ERROR != err ) 1538 { 1539 M4OSA_TRACE1_1( 1540 "M4VSS3GPP_intClipJumpAudioAt(): m_pFctJump() returns 0x%x", 1541 err); 1542 return err; 1543 } 1544 1545 *pJumpCts = 1546 (M4OSA_Int32)(iJumpCtsMs * pClipCtxt->scale_audio + 0.5); 1547 1548 /* Patch because m_CTS is unfortunately rounded in 3gp reader shell */ 1549 /* (cts is not an integer with frequency 24 kHz for example) */ 1550 *pJumpCts = ( ( *pJumpCts + pClipCtxt->iSilenceFrameDuration / 2) 1551 / pClipCtxt->iSilenceFrameDuration) 1552 * pClipCtxt->iSilenceFrameDuration; 1553 pClipCtxt->iAudioFrameCts = 0; /* No frame read yet */ 1554 1555 /** 1556 * To detect some may-be bugs, I prefer to reset all these after a jump */ 1557 pClipCtxt->bAudioFrameAvailable = M4OSA_FALSE; 1558 pClipCtxt->pAudioFramePtr = M4OSA_NULL; 1559 1560 /** 1561 * In AMR, we have to manage multi-framed AUs, 1562 but also in AAC the jump can be 1 AU too much backward */ 1563 if( *pJumpCts < iTargetCts ) 1564 { 1565 /** 1566 * Jump doesn't read any AU, we must read at least one */ 1567 err = M4VSS3GPP_intClipReadNextAudioFrame(pClipCtxt); 1568 1569 if( M4OSA_ERR_IS_ERROR(err) ) 1570 { 1571 M4OSA_TRACE1_1( 1572 "M4VSS3GPP_intClipJumpAudioAt():\ 1573 M4VSS3GPP_intClipReadNextAudioFrame(a) returns 0x%x", 1574 err); 1575 return err; 1576 } 1577 1578 /** 1579 * Read AU frames as long as we reach the AU before the target CTS 1580 * (so the target will be reached when the user call ReadNextAudioFrame). */ 1581 while( pClipCtxt->iAudioFrameCts 1582 < (iTargetCts - pClipCtxt->iSilenceFrameDuration) ) 1583 { 1584 err = M4VSS3GPP_intClipReadNextAudioFrame(pClipCtxt); 1585 1586 if( M4OSA_ERR_IS_ERROR(err) ) 1587 { 1588 M4OSA_TRACE1_1( 1589 "M4VSS3GPP_intClipJumpAudioAt():\ 1590 M4VSS3GPP_intClipReadNextAudioFrame(b) returns 0x%x", 1591 err); 1592 return err; 1593 } 1594 } 1595 1596 /** 1597 * Return the CTS that will be reached at next ReadFrame */ 1598 *pJumpCts = pClipCtxt->iAudioFrameCts 1599 + pClipCtxt->iSilenceFrameDuration; 1600 } 1601 } 1602 } 1603 1604 /** 1605 * Return with no error */ 1606 M4OSA_TRACE3_0("M4VSS3GPP_intClipJumpAudioAt(): returning M4NO_ERROR"); 1607 return M4NO_ERROR; 1608} 1609 1610/** 1611 ****************************************************************************** 1612 * M4OSA_ERR M4VSS3GPP_intClipClose() 1613 * @brief Close a clip. Destroy the context. 1614 * @note 1615 * @param pClipCtxt (IN) Internal clip context 1616 * @return M4NO_ERROR: No error 1617 ****************************************************************************** 1618 */ 1619M4OSA_ERR M4VSS3GPP_intClipClose( M4VSS3GPP_ClipContext *pClipCtxt ) 1620{ 1621 M4OSA_ERR err; 1622 1623 /** 1624 * Check input parameters */ 1625 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER, 1626 "M4VSS3GPP_intClipClose: pClipCtxt is M4OSA_NULL"); 1627 1628 /** 1629 * Free the video decoder context */ 1630 if( M4OSA_NULL != pClipCtxt->pViDecCtxt ) 1631 { 1632 pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctDestroy( 1633 pClipCtxt->pViDecCtxt); 1634 pClipCtxt->pViDecCtxt = M4OSA_NULL; 1635 } 1636 1637 /** 1638 * Free the audio decoder context */ 1639 if( M4OSA_NULL != pClipCtxt->pAudioDecCtxt ) 1640 { 1641 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctDestroyAudioDec( 1642 pClipCtxt->pAudioDecCtxt); 1643 1644 if( M4NO_ERROR != err ) 1645 { 1646 M4OSA_TRACE1_1( 1647 "M4VSS3GPP_intClipClose: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x", 1648 err); 1649 /**< don't return, we still have stuff to free */ 1650 } 1651 1652 pClipCtxt->pAudioDecCtxt = M4OSA_NULL; 1653 } 1654 1655 /** 1656 * Free the decoded audio buffer */ 1657 if( M4OSA_NULL != pClipCtxt->AudioDecBufferOut.m_dataAddress ) 1658 { 1659 free(pClipCtxt->AudioDecBufferOut.m_dataAddress); 1660 pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL; 1661 } 1662 1663 /** 1664 * Audio AU is allocated by reader. 1665 * If no audio track, audio AU is set at 'silent' (SID) by VSS. 1666 * As a consequence, if audio AU is set to 'silent' (static) 1667 it can't be free unless it is set to NULL */ 1668 if( ( (M4OSA_MemAddr8)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048 1669 == pClipCtxt->AudioAU.m_dataAddress) 1670 || ((M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData 1671 == pClipCtxt->AudioAU.m_dataAddress) ) 1672 { 1673 pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL; 1674 } 1675 1676 if( M4OSA_NULL != pClipCtxt->pReaderContext ) 1677 { 1678 /** 1679 * Close the 3GPP or MP3 reader */ 1680 err = pClipCtxt->ShellAPI.m_pReader->m_pFctClose( 1681 pClipCtxt->pReaderContext); 1682 1683 if( M4NO_ERROR != err ) 1684 { 1685 M4OSA_TRACE1_1( 1686 "M4VSS3GPP_intClipClose(): m_pReader->m_pFctClose returns 0x%x", 1687 err); 1688 } 1689 1690 /** 1691 * Destroy the 3GPP or MP3 reader context */ 1692 err = pClipCtxt->ShellAPI.m_pReader->m_pFctDestroy( 1693 pClipCtxt->pReaderContext); 1694 1695 if( M4NO_ERROR != err ) 1696 { 1697 M4OSA_TRACE1_1( 1698 "M4VSS3GPP_intClipClose(): m_pReader->m_pFctDestroy returns 0x%x", 1699 err); 1700 } 1701 1702 pClipCtxt->pReaderContext = M4OSA_NULL; 1703 } 1704 1705 /** 1706 * Return with no error */ 1707 M4OSA_TRACE3_1("M4VSS3GPP_intClipClose(Ctxt=0x%x): returning M4NO_ERROR", 1708 pClipCtxt); 1709 return M4NO_ERROR; 1710} 1711 1712M4OSA_ERR M4VSS3GPP_intClipCleanUp( M4VSS3GPP_ClipContext *pClipCtxt ) 1713{ 1714 M4OSA_ERR err = M4NO_ERROR, err2; 1715 1716 /** 1717 * Check input parameters */ 1718 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER, 1719 "M4VSS3GPP_intClipCleanUp: pClipCtxt is M4OSA_NULL"); 1720 1721 /** 1722 * Free the video decoder context */ 1723 if( M4OSA_NULL != pClipCtxt->pViDecCtxt ) 1724 { 1725 pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctDestroy( 1726 pClipCtxt->pViDecCtxt); 1727 pClipCtxt->pViDecCtxt = M4OSA_NULL; 1728 } 1729 1730 /** 1731 * Free the audio decoder context */ 1732 if( M4OSA_NULL != pClipCtxt->pAudioDecCtxt ) 1733 { 1734 err2 = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctDestroyAudioDec( 1735 pClipCtxt->pAudioDecCtxt); 1736 1737 if( M4NO_ERROR != err2 ) 1738 { 1739 M4OSA_TRACE1_1( 1740 "M4VSS3GPP_intClipCleanUp: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x", 1741 err); 1742 /**< don't return, we still have stuff to free */ 1743 if( M4NO_ERROR != err ) 1744 err = err2; 1745 } 1746 1747 pClipCtxt->pAudioDecCtxt = M4OSA_NULL; 1748 } 1749 1750 /** 1751 * Free the decoded audio buffer */ 1752 if( M4OSA_NULL != pClipCtxt->AudioDecBufferOut.m_dataAddress ) 1753 { 1754 free(pClipCtxt->AudioDecBufferOut.m_dataAddress); 1755 pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL; 1756 } 1757 1758 /** 1759 * Audio AU is allocated by reader. 1760 * If no audio track, audio AU is set at 'silent' (SID) by VSS. 1761 * As a consequence, if audio AU is set to 'silent' (static) 1762 it can't be free unless it is set to NULL */ 1763 if( ( (M4OSA_MemAddr8)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048 1764 == pClipCtxt->AudioAU.m_dataAddress) 1765 || ((M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData 1766 == pClipCtxt->AudioAU.m_dataAddress) ) 1767 { 1768 pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL; 1769 } 1770 1771 if( M4OSA_NULL != pClipCtxt->pReaderContext ) 1772 { 1773 /** 1774 * Close the 3GPP or MP3 reader */ 1775 err2 = pClipCtxt->ShellAPI.m_pReader->m_pFctClose( 1776 pClipCtxt->pReaderContext); 1777 1778 if( M4NO_ERROR != err2 ) 1779 { 1780 M4OSA_TRACE1_1( 1781 "M4VSS3GPP_intClipCleanUp(): m_pReader->m_pFctClose returns 0x%x", 1782 err); 1783 1784 if( M4NO_ERROR != err ) 1785 err = err2; 1786 } 1787 1788 /** 1789 * Destroy the 3GPP or MP3 reader context */ 1790 err2 = pClipCtxt->ShellAPI.m_pReader->m_pFctDestroy( 1791 pClipCtxt->pReaderContext); 1792 1793 if( M4NO_ERROR != err2 ) 1794 { 1795 M4OSA_TRACE1_1( 1796 "M4VSS3GPP_intClipCleanUp(): m_pReader->m_pFctDestroy returns 0x%x", 1797 err); 1798 1799 if( M4NO_ERROR != err ) 1800 err = err2; 1801 } 1802 1803 pClipCtxt->pReaderContext = M4OSA_NULL; 1804 } 1805 1806 /** 1807 * Free the shells interfaces */ 1808 M4VSS3GPP_unRegisterAllWriters(&pClipCtxt->ShellAPI); 1809 M4VSS3GPP_unRegisterAllEncoders(&pClipCtxt->ShellAPI); 1810 M4VSS3GPP_unRegisterAllReaders(&pClipCtxt->ShellAPI); 1811 M4VSS3GPP_unRegisterAllDecoders(&pClipCtxt->ShellAPI); 1812 1813 M4OSA_TRACE3_1("M4VSS3GPP_intClipCleanUp: pClipCtxt=0x%x", pClipCtxt); 1814 /** 1815 * Free the clip context */ 1816 free(pClipCtxt); 1817 1818 return err; 1819} 1820 1821/** 1822 ****************************************************************************** 1823 * M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_AMRNB() 1824 * @brief Return the length, in bytes, of the AMR Narrow-Band frame contained in the given buffer 1825 * @note 1826 * @param pAudioFrame (IN) AMRNB frame 1827 * @return M4NO_ERROR: No error 1828 ****************************************************************************** 1829 */ 1830 1831M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_AMRNB( M4OSA_MemAddr8 pAudioFrame ) 1832{ 1833 M4OSA_UInt32 frameSize = 0; 1834 M4OSA_UInt32 frameType = ( ( *pAudioFrame) &(0xF << 3)) >> 3; 1835 1836 switch( frameType ) 1837 { 1838 case 0: 1839 frameSize = 95; 1840 break; /* 4750 bps */ 1841 1842 case 1: 1843 frameSize = 103; 1844 break; /* 5150 bps */ 1845 1846 case 2: 1847 frameSize = 118; 1848 break; /* 5900 bps */ 1849 1850 case 3: 1851 frameSize = 134; 1852 break; /* 6700 bps */ 1853 1854 case 4: 1855 frameSize = 148; 1856 break; /* 7400 bps */ 1857 1858 case 5: 1859 frameSize = 159; 1860 break; /* 7950 bps */ 1861 1862 case 6: 1863 frameSize = 204; 1864 break; /* 10200 bps */ 1865 1866 case 7: 1867 frameSize = 244; 1868 break; /* 12000 bps */ 1869 1870 case 8: 1871 frameSize = 39; 1872 break; /* SID (Silence) */ 1873 1874 case 15: 1875 frameSize = 0; 1876 break; /* No data */ 1877 1878 default: 1879 M4OSA_TRACE3_0( 1880 "M4VSS3GPP_intGetFrameSize_AMRNB(): Corrupted AMR frame! returning 0."); 1881 return 0; 1882 } 1883 1884 return (1 + (( frameSize + 7) / 8)); 1885} 1886 1887/** 1888 ****************************************************************************** 1889 * M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_EVRC() 1890 * @brief Return the length, in bytes, of the EVRC frame contained in the given buffer 1891 * @note 1892 * 0 1 2 3 1893 * +-+-+-+-+ 1894 * |fr type| RFC 3558 1895 * +-+-+-+-+ 1896 * 1897 * Frame Type: 4 bits 1898 * The frame type indicates the type of the corresponding codec data 1899 * frame in the RTP packet. 1900 * 1901 * For EVRC and SMV codecs, the frame type values and size of the 1902 * associated codec data frame are described in the table below: 1903 * 1904 * Value Rate Total codec data frame size (in octets) 1905 * --------------------------------------------------------- 1906 * 0 Blank 0 (0 bit) 1907 * 1 1/8 2 (16 bits) 1908 * 2 1/4 5 (40 bits; not valid for EVRC) 1909 * 3 1/2 10 (80 bits) 1910 * 4 1 22 (171 bits; 5 padded at end with zeros) 1911 * 5 Erasure 0 (SHOULD NOT be transmitted by sender) 1912 * 1913 * @param pCpAudioFrame (IN) EVRC frame 1914 * @return M4NO_ERROR: No error 1915 ****************************************************************************** 1916 */ 1917M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_EVRC( M4OSA_MemAddr8 pAudioFrame ) 1918{ 1919 M4OSA_UInt32 frameSize = 0; 1920 M4OSA_UInt32 frameType = ( *pAudioFrame) &0x0F; 1921 1922 switch( frameType ) 1923 { 1924 case 0: 1925 frameSize = 0; 1926 break; /* blank */ 1927 1928 case 1: 1929 frameSize = 16; 1930 break; /* 1/8 */ 1931 1932 case 2: 1933 frameSize = 40; 1934 break; /* 1/4 */ 1935 1936 case 3: 1937 frameSize = 80; 1938 break; /* 1/2 */ 1939 1940 case 4: 1941 frameSize = 171; 1942 break; /* 1 */ 1943 1944 case 5: 1945 frameSize = 0; 1946 break; /* erasure */ 1947 1948 default: 1949 M4OSA_TRACE3_0( 1950 "M4VSS3GPP_intGetFrameSize_EVRC(): Corrupted EVRC frame! returning 0."); 1951 return 0; 1952 } 1953 1954 return (1 + (( frameSize + 7) / 8)); 1955} 1956