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