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_ClipAnalysis.c 19 * @brief Implementation of functions related to analysis of input clips 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 #include "M4VD_EXTERNAL_Interface.h" 37 38 39 /** 40 * OSAL headers */ 41 #include "M4OSA_Memory.h" /* OSAL memory management */ 42 #include "M4OSA_Debug.h" /* OSAL debug management */ 43 44 /** 45 ****************************************************************************** 46 * M4OSA_ERR M4VSS3GPP_editAnalyseClip() 47 * @brief This function allows checking if a clip is compatible with VSS 3GPP editing 48 * @note It also fills a ClipAnalysis structure, which can be used to check if two 49 * clips are compatible 50 * @param pClip (IN) File descriptor of the input 3GPP/MP3 clip file. 51 * @param pClipProperties (IN) Pointer to a valid ClipProperties structure. 52 * @param FileType (IN) Type of the input file (.3gp, .amr, .mp3) 53 * @return M4NO_ERROR: No error 54 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 55 * @return M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED 56 * @return M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION 57 * @return M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED 58 * @return M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE 59 * @return M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE 60 * @return M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC 61 * @return M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT 62 * @return M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE 63 * @return M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT 64 * @return M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE 65 ****************************************************************************** 66 */ 67 M4OSA_ERR M4VSS3GPP_editAnalyseClip( M4OSA_Void *pClip, 68 M4VIDEOEDITING_FileType FileType, 69 M4VIDEOEDITING_ClipProperties *pClipProperties, 70 M4OSA_FileReadPointer *pFileReadPtrFct ) 71 { 72 M4OSA_ERR err; 73 M4VSS3GPP_ClipContext *pClipContext; 74 M4VSS3GPP_ClipSettings ClipSettings; 75 76 M4OSA_TRACE3_2( 77 "M4VSS3GPP_editAnalyseClip called with pClip=0x%x, pClipProperties=0x%x", 78 pClip, pClipProperties); 79 80 /** 81 * Check input parameter */ 82 M4OSA_DEBUG_IF2((M4OSA_NULL == pClip), M4ERR_PARAMETER, 83 "M4VSS3GPP_editAnalyseClip: pClip is M4OSA_NULL"); 84 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipProperties), M4ERR_PARAMETER, 85 "M4VSS3GPP_editAnalyseClip: pClipProperties is M4OSA_NULL"); 86 87 /** 88 * Build dummy clip settings, in order to use the editClipOpen function */ 89 ClipSettings.pFile = pClip; 90 ClipSettings.FileType = FileType; 91 ClipSettings.uiBeginCutTime = 0; 92 ClipSettings.uiEndCutTime = 0; 93 94 /* Clip properties not build yet, set at least this flag */ 95 ClipSettings.ClipProperties.bAnalysed = M4OSA_FALSE; 96 97 /** 98 * Open the clip in fast open mode */ 99 err = M4VSS3GPP_intClipInit(&pClipContext, pFileReadPtrFct); 100 101 if( M4NO_ERROR != err ) 102 { 103 M4OSA_TRACE1_1( 104 "M4VSS3GPP_editAnalyseClip: M4VSS3GPP_intClipInit() returns 0x%x!", 105 err); 106 107 /** 108 * Free the clip */ 109 if( M4OSA_NULL != pClipContext ) 110 { 111 M4VSS3GPP_intClipCleanUp(pClipContext); 112 } 113 return err; 114 } 115 116 err = M4VSS3GPP_intClipOpen(pClipContext, &ClipSettings, M4OSA_FALSE, 117 M4OSA_TRUE, M4OSA_TRUE); 118 119 if( M4NO_ERROR != err ) 120 { 121 M4OSA_TRACE1_1( 122 "M4VSS3GPP_editAnalyseClip: M4VSS3GPP_intClipOpen() returns 0x%x!", 123 err); 124 125 M4VSS3GPP_intClipCleanUp(pClipContext); 126 127 /** 128 * Here it is better to return the Editing specific error code */ 129 if( ( ((M4OSA_UInt32)M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED) == err) 130 || (((M4OSA_UInt32)M4ERR_DECODER_H263_NOT_BASELINE) == err) ) 131 { 132 M4OSA_TRACE1_0( 133 "M4VSS3GPP_editAnalyseClip:\ 134 M4VSS3GPP_intClipOpen() returns M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED"); 135 return M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED; 136 } 137 return err; 138 } 139 140 /** 141 * Analyse the clip */ 142 if(M4VIDEOEDITING_kFileType_ARGB8888 != pClipContext->pSettings->FileType) { 143 err = M4VSS3GPP_intBuildAnalysis(pClipContext, pClipProperties); 144 145 if( M4NO_ERROR != err ) 146 { 147 M4OSA_TRACE1_1( 148 "M4VSS3GPP_editAnalyseClip: M4VSS3GPP_intBuildAnalysis() returns 0x%x!", 149 err); 150 151 /** 152 * Free the clip */ 153 M4VSS3GPP_intClipCleanUp(pClipContext); 154 return err; 155 } 156 } 157 /** 158 * Free the clip */ 159 err = M4VSS3GPP_intClipClose(pClipContext); 160 161 if( M4NO_ERROR != err ) 162 { 163 M4OSA_TRACE1_1( 164 "M4VSS3GPP_editAnalyseClip: M4VSS_intClipClose() returns 0x%x!", 165 err); 166 M4VSS3GPP_intClipCleanUp(pClipContext); 167 return err; 168 } 169 170 M4VSS3GPP_intClipCleanUp(pClipContext); 171 172 /** 173 * Check the clip is compatible with VSS editing */ 174 if(M4VIDEOEDITING_kFileType_ARGB8888 != ClipSettings.FileType) { 175 err = M4VSS3GPP_intCheckClipCompatibleWithVssEditing(pClipProperties); 176 177 if( M4NO_ERROR != err ) 178 { 179 M4OSA_TRACE1_1( 180 "M4VSS3GPP_editAnalyseClip:\ 181 M4VSS3GPP_intCheckClipCompatibleWithVssEditing() returns 0x%x!", 182 err); 183 return err; 184 } 185 } 186 /** 187 * Return with no error */ 188 M4OSA_TRACE3_0("M4VSS3GPP_editAnalyseClip(): returning M4NO_ERROR"); 189 return M4NO_ERROR; 190 } 191 192 /** 193 ****************************************************************************** 194 * M4OSA_ERR M4VSS3GPP_editCheckClipCompatibility() 195 * @brief This function allows checking if two clips are compatible with each other for 196 * VSS 3GPP editing assembly feature. 197 * @note 198 * @param pClip1Properties (IN) Clip analysis of the first clip 199 * @param pClip2Properties (IN) Clip analysis of the second clip 200 * @return M4NO_ERROR: No error 201 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 202 * @return M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION 203 * @return M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT 204 * @return M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE 205 * @return M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE 206 * @return M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING 207 * @return M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY 208 * @return M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT 209 ****************************************************************************** 210 */ 211 M4OSA_ERR M4VSS3GPP_editCheckClipCompatibility( M4VIDEOEDITING_ClipProperties *pClip1Properties, 212 M4VIDEOEDITING_ClipProperties *pClip2Properties ) 213 { 214 M4OSA_ERR err = M4NO_ERROR; 215 M4OSA_ERR video_err = M4NO_ERROR; 216 M4OSA_ERR audio_err = M4NO_ERROR; 217 218 M4OSA_Bool bClip1IsAAC = M4OSA_FALSE; 219 M4OSA_Bool bClip2IsAAC = M4OSA_FALSE; 220 221 M4OSA_TRACE3_2("M4VSS3GPP_editCheckClipCompatibility called with pClip1Analysis=0x%x,\ 222 pClip2Analysis=0x%x", pClip1Properties, pClip2Properties); 223 224 /** 225 * Check input parameter */ 226 M4OSA_DEBUG_IF2((M4OSA_NULL == pClip1Properties), M4ERR_PARAMETER, 227 "M4VSS3GPP_editCheckClipCompatibility: pClip1Properties is M4OSA_NULL"); 228 M4OSA_DEBUG_IF2((M4OSA_NULL == pClip2Properties), M4ERR_PARAMETER, 229 "M4VSS3GPP_editCheckClipCompatibility: pClip2Properties is M4OSA_NULL"); 230 231 if( ( M4VIDEOEDITING_kFileType_MP3 == pClip1Properties->FileType) 232 || (M4VIDEOEDITING_kFileType_AMR == pClip1Properties->FileType) ) 233 { 234 if( pClip1Properties != pClip2Properties ) 235 { 236 M4OSA_TRACE1_0( 237 "M4VSS3GPP_editCheckClipCompatibility: MP3 CAN ONLY BE CUT,\ 238 returning M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY"); 239 return M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY; 240 } 241 else 242 { 243 /* We are in VSS Splitter mode */ 244 goto audio_analysis; 245 } 246 } 247 248 /********** Audio ************/ 249 250 audio_analysis: 251 if( M4VIDEOEDITING_kNoneAudio != pClip1Properties-> 252 AudioStreamType ) /**< if there is an audio stream */ 253 { 254 /** 255 * Check audio format is AAC */ 256 switch( pClip1Properties->AudioStreamType ) 257 { 258 case M4VIDEOEDITING_kAAC: 259 case M4VIDEOEDITING_kAACplus: 260 case M4VIDEOEDITING_keAACplus: 261 bClip1IsAAC = M4OSA_TRUE; 262 break; 263 default: 264 break; 265 } 266 } 267 268 if( M4VIDEOEDITING_kNoneAudio != pClip2Properties-> 269 AudioStreamType ) /**< if there is an audio stream */ 270 { 271 /** 272 * Check audio format is AAC */ 273 switch( pClip2Properties->AudioStreamType ) 274 { 275 case M4VIDEOEDITING_kAAC: 276 case M4VIDEOEDITING_kAACplus: 277 case M4VIDEOEDITING_keAACplus: 278 bClip2IsAAC = M4OSA_TRUE; 279 break; 280 default: 281 break; 282 } 283 } 284 285 /** 286 * If there is no audio, the clips are compatibles ... */ 287 if( ( pClip1Properties->AudioStreamType != M4VIDEOEDITING_kNoneAudio) 288 && (pClip2Properties->AudioStreamType != M4VIDEOEDITING_kNoneAudio) ) 289 { 290 /** 291 * Check both clips have same audio stream type 292 * And let_s say AAC, AAC+ and eAAC+ are mixable */ 293 if( ( pClip1Properties->AudioStreamType 294 != pClip2Properties->AudioStreamType) 295 && (( M4OSA_FALSE == bClip1IsAAC) || (M4OSA_FALSE == bClip2IsAAC)) ) 296 { 297 M4OSA_TRACE1_0( 298 "M4VSS3GPP_editCheckClipCompatibility:\ 299 Clips don't have the same Audio Stream Type"); 300 301 audio_err = M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_STREAM_TYPE; 302 goto analysis_done; 303 } 304 305 /** 306 * Check both clips have same number of channels */ 307 if( pClip1Properties->uiNbChannels != pClip2Properties->uiNbChannels ) 308 { 309 M4OSA_TRACE1_0( 310 "M4VSS3GPP_editCheckClipCompatibility: Clips don't have the same Nb of Channels"); 311 audio_err = M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS; 312 goto analysis_done; 313 } 314 315 /** 316 * Check both clips have same sampling frequency */ 317 if( pClip1Properties->uiSamplingFrequency 318 != pClip2Properties->uiSamplingFrequency ) 319 { 320 M4OSA_TRACE1_0( 321 "M4VSS3GPP_editCheckClipCompatibility:\ 322 Clips don't have the same Sampling Frequency"); 323 audio_err = M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY; 324 goto analysis_done; 325 } 326 } 327 328 pClip2Properties->bAudioIsCompatibleWithMasterClip = M4OSA_TRUE; 329 330 /** 331 * Return with no error */ 332 333 analysis_done: 334 if( video_err != M4NO_ERROR ) 335 return video_err; 336 337 if( audio_err != M4NO_ERROR ) 338 return audio_err; 339 340 M4OSA_TRACE3_0( 341 "M4VSS3GPP_editCheckClipCompatibility(): returning M4NO_ERROR"); 342 return M4NO_ERROR; 343 } 344 345 /** 346 ****************************************************************************** 347 * M4OSA_ERR M4VSS3GPP_intBuildAnalysis() 348 * @brief Get video and audio properties from the clip streams 349 * @note This function must return fatal errors only (errors that should not happen 350 * in the final integrated product). 351 * @param pClipCtxt (IN) internal clip context 352 * @param pClipProperties (OUT) Pointer to a valid ClipProperties structure. 353 * @return M4NO_ERROR: No error 354 ****************************************************************************** 355 */ 356 M4OSA_ERR M4VSS3GPP_intBuildAnalysis( M4VSS3GPP_ClipContext *pClipCtxt, 357 M4VIDEOEDITING_ClipProperties *pClipProperties ) 358 { 359 M4OSA_ERR err; 360 M4DECODER_MPEG4_DecoderConfigInfo DecConfigInfo; 361 M4DECODER_VideoSize dummySize; 362 M4DECODER_AVCProfileLevel AVCProfle; 363 364 pClipProperties->bAnalysed = M4OSA_FALSE; 365 366 /** 367 * Reset video characteristics */ 368 pClipProperties->VideoStreamType = M4VIDEOEDITING_kNoneVideo; 369 pClipProperties->uiClipVideoDuration = 0; 370 pClipProperties->uiVideoBitrate = 0; 371 pClipProperties->uiVideoMaxAuSize = 0; 372 pClipProperties->uiVideoWidth = 0; 373 pClipProperties->uiVideoHeight = 0; 374 pClipProperties->uiVideoTimeScale = 0; 375 pClipProperties->fAverageFrameRate = 0.0; 376 pClipProperties->uiVideoProfile = 377 M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE; 378 pClipProperties->uiVideoLevel = 379 M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL; 380 pClipProperties->bMPEG4dataPartition = M4OSA_FALSE; 381 pClipProperties->bMPEG4rvlc = M4OSA_FALSE; 382 pClipProperties->bMPEG4resynchMarker = M4OSA_FALSE; 383 384 memset((void *) &pClipProperties->ftyp,0, 385 sizeof(pClipProperties->ftyp)); 386 387 /** 388 * Video Analysis */ 389 if( M4OSA_NULL != pClipCtxt->pVideoStream ) 390 { 391 pClipProperties->uiVideoWidth = pClipCtxt->pVideoStream->m_videoWidth; 392 pClipProperties->uiVideoHeight = pClipCtxt->pVideoStream->m_videoHeight; 393 pClipProperties->fAverageFrameRate = 394 pClipCtxt->pVideoStream->m_averageFrameRate; 395 396 switch( pClipCtxt->pVideoStream->m_basicProperties.m_streamType ) 397 { 398 case M4DA_StreamTypeVideoMpeg4: 399 400 pClipProperties->VideoStreamType = M4VIDEOEDITING_kMPEG4; 401 402 /* This issue is so incredibly stupid that it's depressing. Basically, a file can be analysed 403 outside of any context (besides that of the clip itself), so that for instance two clips can 404 be checked for compatibility before allocating an edit context for editing them. But this 405 means there is no way in heck to pass an external video decoder (to begin with) to this 406 function, as they work by being registered in an existing context; furthermore, it is actually 407 pretty overkill to use a full decoder for that, moreso a HARDWARE decoder just to get the 408 clip config info. In fact, the hardware itself doesn't provide this service, in the case of a 409 HW decoder, the shell builds the config info itself, so we don't need the actual decoder, only 410 a detached functionality of it. So in case HW/external decoders may be present, we instead use 411 directly the DSI parsing function of the shell HW decoder (which we know to be present, since 412 HW decoders are possible) to get the config info. Notice this function is used even if the 413 software decoder is actually present and even if it will end up being actually used: figuring 414 out the config does not involve actual decoding nor the particularities of a specific decoder, 415 it's the fact that it's MPEG4 that matters, so it should not be functionally any different 416 from the way it was done before (and it's light enough for performance not to be any problem 417 whatsoever). */ 418 419 err = M4DECODER_EXTERNAL_ParseVideoDSI(pClipCtxt->pVideoStream-> 420 m_basicProperties.m_pDecoderSpecificInfo, 421 pClipCtxt->pVideoStream->m_basicProperties.m_decoderSpecificInfoSize, 422 &DecConfigInfo, &dummySize); 423 424 if( M4NO_ERROR != err ) 425 { 426 M4OSA_TRACE1_1( 427 "M4VSS3GPP_intBuildAnalysis():\ 428 M4DECODER_EXTERNAL_ParseVideoDSI returns 0x%08X", err); 429 return err; 430 } 431 432 pClipProperties->uiVideoTimeScale = 433 DecConfigInfo.uiTimeScale; 434 pClipProperties->bMPEG4dataPartition = 435 DecConfigInfo.bDataPartition; 436 pClipProperties->bMPEG4rvlc = 437 DecConfigInfo.bUseOfRVLC; 438 pClipProperties->bMPEG4resynchMarker = 439 DecConfigInfo.uiUseOfResynchMarker; 440 err = getMPEG4ProfileAndLevel(DecConfigInfo.uiProfile, 441 &(pClipProperties->uiVideoProfile), 442 &(pClipProperties->uiVideoLevel)); 443 if (M4NO_ERROR != err) { 444 M4OSA_TRACE1_1("M4VSS3GPP_intBuildAnalysis(): \ 445 getMPEG4ProfileAndLevel returns 0x%08X", err); 446 return err; 447 } 448 break; 449 450 case M4DA_StreamTypeVideoH263: 451 452 pClipProperties->VideoStreamType = M4VIDEOEDITING_kH263; 453 /* H263 time scale is always 30000 */ 454 pClipProperties->uiVideoTimeScale = 30000; 455 456 err = getH263ProfileAndLevel(pClipCtxt->pVideoStream-> 457 m_basicProperties.m_pDecoderSpecificInfo, 458 pClipCtxt->pVideoStream->m_basicProperties.m_decoderSpecificInfoSize, 459 &pClipProperties->uiVideoProfile, 460 &pClipProperties->uiVideoLevel); 461 if (M4NO_ERROR != err) { 462 M4OSA_TRACE1_1("M4VSS3GPP_intBuildAnalysis(): \ 463 getH263ProfileAndLevel returns 0x%08X", err); 464 return err; 465 } 466 break; 467 468 case M4DA_StreamTypeVideoMpeg4Avc: 469 470 pClipProperties->VideoStreamType = M4VIDEOEDITING_kH264; 471 err = getAVCProfileAndLevel(pClipCtxt->pVideoStream-> 472 m_basicProperties.m_pDecoderSpecificInfo, 473 pClipCtxt->pVideoStream->m_basicProperties.m_decoderSpecificInfoSize, 474 &pClipProperties->uiVideoProfile, 475 &pClipProperties->uiVideoLevel); 476 if (M4NO_ERROR != err) { 477 M4OSA_TRACE1_1("M4VSS3GPP_intBuildAnalysis(): \ 478 getAVCProfileAndLevel returns 0x%08X", err); 479 return err; 480 } 481 break; 482 483 default: 484 M4OSA_TRACE1_1( 485 "M4VSS3GPP_intBuildAnalysis: unknown input video format (0x%x),\ 486 returning M4NO_ERROR", 487 pClipCtxt->pVideoStream->m_basicProperties.m_streamType); 488 489 /** We do not return error here. 490 * The video format compatibility check will be done latter */ 491 return M4NO_ERROR; 492 } 493 494 pClipProperties->uiClipVideoDuration = 495 (M4OSA_UInt32)pClipCtxt->pVideoStream->m_basicProperties.m_duration; 496 pClipProperties->uiVideoMaxAuSize = 497 pClipCtxt->pVideoStream->m_basicProperties.m_maxAUSize; 498 499 /* if video bitrate not available retrieve an estimation of the overall bitrate */ 500 pClipProperties->uiVideoBitrate = 501 (M4OSA_UInt32)pClipCtxt->pVideoStream-> 502 m_basicProperties.m_averageBitRate; 503 504 if( 0 == pClipProperties->uiVideoBitrate ) 505 { 506 pClipCtxt->ShellAPI.m_pReader->m_pFctGetOption( 507 pClipCtxt->pReaderContext, M4READER_kOptionID_Bitrate, 508 &pClipProperties->uiVideoBitrate); 509 510 if( M4OSA_NULL != pClipCtxt->pAudioStream ) 511 { 512 /* we get the overall bitrate, substract the audio bitrate if any */ 513 pClipProperties->uiVideoBitrate -= 514 pClipCtxt->pAudioStream->m_basicProperties.m_averageBitRate; 515 } 516 } 517 } 518 519 /** 520 * Reset audio characteristics */ 521 pClipProperties->AudioStreamType = M4VIDEOEDITING_kNoneAudio; 522 pClipProperties->uiClipAudioDuration = 0; 523 pClipProperties->uiAudioBitrate = 0; 524 pClipProperties->uiAudioMaxAuSize = 0; 525 pClipProperties->uiNbChannels = 0; 526 pClipProperties->uiSamplingFrequency = 0; 527 pClipProperties->uiExtendedSamplingFrequency = 0; 528 pClipProperties->uiDecodedPcmSize = 0; 529 530 /** 531 * Audio Analysis */ 532 if( M4OSA_NULL != pClipCtxt->pAudioStream ) 533 { 534 switch( pClipCtxt->pAudioStream->m_basicProperties.m_streamType ) 535 { 536 case M4DA_StreamTypeAudioAmrNarrowBand: 537 538 pClipProperties->AudioStreamType = M4VIDEOEDITING_kAMR_NB; 539 break; 540 541 case M4DA_StreamTypeAudioAac: 542 543 pClipProperties->AudioStreamType = M4VIDEOEDITING_kAAC; 544 break; 545 546 case M4DA_StreamTypeAudioMp3: 547 548 pClipProperties->AudioStreamType = M4VIDEOEDITING_kMP3; 549 break; 550 551 case M4DA_StreamTypeAudioEvrc: 552 553 pClipProperties->AudioStreamType = M4VIDEOEDITING_kEVRC; 554 break; 555 556 case M4DA_StreamTypeAudioPcm: 557 558 pClipProperties->AudioStreamType = M4VIDEOEDITING_kPCM; 559 break; 560 561 default: 562 563 M4OSA_TRACE1_1( 564 "M4VSS3GPP_intBuildAnalysis: unknown input audio format (0x%x),\ 565 returning M4NO_ERROR!", 566 pClipCtxt->pAudioStream->m_basicProperties.m_streamType); 567 return 568 M4NO_ERROR; /**< We do not return error here. 569 The audio format compatibility check will be done latter */ 570 } 571 572 pClipProperties->uiAudioMaxAuSize = 573 pClipCtxt->pAudioStream->m_basicProperties.m_maxAUSize; 574 pClipProperties->uiClipAudioDuration = 575 (M4OSA_UInt32)pClipCtxt->pAudioStream->m_basicProperties.m_duration; 576 577 pClipProperties->uiNbChannels = pClipCtxt->pAudioStream->m_nbChannels; 578 pClipProperties->uiSamplingFrequency = 579 pClipCtxt->pAudioStream->m_samplingFrequency; 580 pClipProperties->uiDecodedPcmSize = 581 pClipCtxt->pAudioStream->m_byteFrameLength 582 * pClipCtxt->pAudioStream->m_byteSampleSize 583 * pClipCtxt->pAudioStream->m_nbChannels; 584 585 /** 586 * Bugfix P4ME00001128: With some IMTC files, the AMR bit rate is 0 kbps 587 according the GetProperties function */ 588 pClipProperties->uiAudioBitrate = 589 (M4OSA_UInt32)pClipCtxt->pAudioStream-> 590 m_basicProperties.m_averageBitRate; 591 592 if( 0 == pClipProperties->uiAudioBitrate ) 593 { 594 if( M4VIDEOEDITING_kAMR_NB == pClipProperties->AudioStreamType ) 595 { 596 /** 597 *Better returning a guessed 12.2 kbps value than a sure-to-be-false 0 kbps value!*/ 598 pClipProperties->uiAudioBitrate = M4VSS3GPP_AMR_DEFAULT_BITRATE; 599 } 600 else if( M4VIDEOEDITING_kEVRC == pClipProperties->AudioStreamType ) 601 { 602 /** 603 *Better returning a guessed 9.2 kbps value than a sure-to-be-false 0 kbps value!*/ 604 pClipProperties->uiAudioBitrate = 605 M4VSS3GPP_EVRC_DEFAULT_BITRATE; 606 } 607 else 608 { 609 pClipCtxt->ShellAPI.m_pReader->m_pFctGetOption( 610 pClipCtxt->pReaderContext, M4READER_kOptionID_Bitrate, 611 &pClipProperties->uiAudioBitrate); 612 613 if( M4OSA_NULL != pClipCtxt->pVideoStream ) 614 { 615 /* we get the overall bitrate, substract the video bitrate if any */ 616 pClipProperties->uiAudioBitrate -= pClipCtxt->pVideoStream-> 617 m_basicProperties.m_averageBitRate; 618 } 619 } 620 } 621 622 /* New aac properties */ 623 if( M4DA_StreamTypeAudioAac 624 == pClipCtxt->pAudioStream->m_basicProperties.m_streamType ) 625 { 626 pClipProperties->uiNbChannels = pClipCtxt->AacProperties.aNumChan; 627 pClipProperties->uiSamplingFrequency = 628 pClipCtxt->AacProperties.aSampFreq; 629 630 if( pClipCtxt->AacProperties.aSBRPresent ) 631 { 632 pClipProperties->AudioStreamType = M4VIDEOEDITING_kAACplus; 633 pClipProperties->uiExtendedSamplingFrequency = 634 pClipCtxt->AacProperties.aExtensionSampFreq; 635 } 636 637 if( pClipCtxt->AacProperties.aPSPresent ) 638 { 639 pClipProperties->AudioStreamType = M4VIDEOEDITING_keAACplus; 640 } 641 } 642 } 643 644 /* Get 'ftyp' atom */ 645 err = pClipCtxt->ShellAPI.m_pReader->m_pFctGetOption( 646 pClipCtxt->pReaderContext, 647 M4READER_kOptionID_3gpFtypBox, &pClipProperties->ftyp); 648 649 /** 650 * We write the VSS 3GPP version in the clip analysis to be sure the integrator doesn't 651 * mix older analysis results with newer libraries */ 652 pClipProperties->Version[0] = M4VIDEOEDITING_VERSION_MAJOR; 653 pClipProperties->Version[1] = M4VIDEOEDITING_VERSION_MINOR; 654 pClipProperties->Version[2] = M4VIDEOEDITING_VERSION_REVISION; 655 656 pClipProperties->FileType = pClipCtxt->pSettings->FileType; 657 658 if( pClipProperties->uiClipVideoDuration 659 > pClipProperties->uiClipAudioDuration ) 660 pClipProperties->uiClipDuration = pClipProperties->uiClipVideoDuration; 661 else 662 pClipProperties->uiClipDuration = pClipProperties->uiClipAudioDuration; 663 664 /* Reset compatibility chart */ 665 pClipProperties->bVideoIsEditable = M4OSA_FALSE; 666 pClipProperties->bAudioIsEditable = M4OSA_FALSE; 667 pClipProperties->bVideoIsCompatibleWithMasterClip = M4OSA_FALSE; 668 pClipProperties->bAudioIsCompatibleWithMasterClip = M4OSA_FALSE; 669 670 /* Analysis successfully completed */ 671 pClipProperties->bAnalysed = M4OSA_TRUE; 672 673 /** 674 * Return with no error */ 675 M4OSA_TRACE3_0("M4VSS3GPP_intBuildAnalysis(): returning M4NO_ERROR"); 676 return M4NO_ERROR; 677 } 678 679 /** 680 ****************************************************************************** 681 * M4OSA_ERR M4VSS3GPP_intCheckClipCompatibleWithVssEditing() 682 * @brief Check if the clip is compatible with VSS editing 683 * @note 684 * @param pClipCtxt (IN) internal clip context 685 * @param pClipProperties (OUT) Pointer to a valid ClipProperties structure. 686 * @return M4NO_ERROR: No error 687 ****************************************************************************** 688 */ 689 M4OSA_ERR M4VSS3GPP_intCheckClipCompatibleWithVssEditing( 690 M4VIDEOEDITING_ClipProperties *pClipProperties ) 691 { 692 M4OSA_UInt32 uiNbOfValidStreams = 0; 693 M4OSA_ERR video_err = M4NO_ERROR; 694 M4OSA_ERR audio_err = M4NO_ERROR; 695 /********* file type *********/ 696 697 if( M4VIDEOEDITING_kFileType_AMR == pClipProperties->FileType ) 698 { 699 M4OSA_TRACE1_0( 700 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing:\ 701 returning M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED"); 702 return M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED; 703 } 704 705 if( M4VIDEOEDITING_kFileType_MP3 == pClipProperties->FileType ) 706 { 707 M4OSA_TRACE3_0( 708 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): returning M4NO_ERROR"); 709 return M4NO_ERROR; 710 } 711 712 /********* Video *********/ 713 714 if( M4VIDEOEDITING_kNoneVideo 715 != pClipProperties->VideoStreamType ) /**< if there is a video stream */ 716 { 717 /* Check video format is MPEG-4, H263 or H264 */ 718 switch( pClipProperties->VideoStreamType ) 719 { 720 case M4VIDEOEDITING_kH263: 721 case M4VIDEOEDITING_kMPEG4: 722 case M4VIDEOEDITING_kH264: 723 uiNbOfValidStreams++; 724 pClipProperties->bVideoIsEditable = M4OSA_TRUE; 725 break; 726 727 default: /*< KO, we return error */ 728 M4OSA_TRACE1_0( 729 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): unsupported video format"); 730 video_err = M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT; 731 break; 732 } 733 } 734 else 735 { 736 /** 737 * Audio only stream are currently not supported by the VSS editing feature 738 (unless in the MP3 case) */ 739 M4OSA_TRACE1_0( 740 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): No video stream in clip"); 741 video_err = M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE; 742 } 743 744 /********* Audio *********/ 745 if( M4VIDEOEDITING_kNoneAudio != pClipProperties-> 746 AudioStreamType ) /**< if there is an audio stream */ 747 { 748 /** 749 * Check audio format is AMR-NB, EVRC or AAC */ 750 switch( pClipProperties->AudioStreamType ) 751 { 752 case M4VIDEOEDITING_kAMR_NB: 753 pClipProperties->bAudioIsEditable = M4OSA_TRUE; 754 uiNbOfValidStreams++; 755 break; 756 757 case M4VIDEOEDITING_kAAC: 758 case M4VIDEOEDITING_kAACplus: 759 case M4VIDEOEDITING_keAACplus: 760 switch( pClipProperties->uiSamplingFrequency ) 761 { 762 case 8000: 763 case 16000: 764 case 22050: 765 case 24000: 766 case 32000: 767 case 44100: 768 case 48000: 769 pClipProperties->bAudioIsEditable = M4OSA_TRUE; 770 break; 771 772 default: 773 break; 774 } 775 uiNbOfValidStreams++; 776 break; 777 778 case M4VIDEOEDITING_kEVRC: 779 /*< OK, we proceed, no return */ 780 uiNbOfValidStreams++; 781 break; 782 783 default: /*< KO, we return error */ 784 M4OSA_TRACE1_0( 785 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): unsupported audio format"); 786 audio_err = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT; 787 break; 788 } 789 } 790 else 791 { 792 /* Silence is always editable */ 793 pClipProperties->bAudioIsEditable = M4OSA_TRUE; 794 } 795 796 /** 797 * Check there is at least one valid stream in the file... */ 798 if( video_err != M4NO_ERROR ) 799 return video_err; 800 801 if( audio_err != M4NO_ERROR ) 802 return audio_err; 803 804 if( 0 == uiNbOfValidStreams ) 805 { 806 M4OSA_TRACE1_0( 807 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): File contains no supported stream,\ 808 returning M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE"); 809 return M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE; 810 } 811 812 /** 813 * Return with no error */ 814 M4OSA_TRACE3_0( 815 "M4VSS3GPP_intCheckClipCompatibleWithVssEditing(): returning M4NO_ERROR"); 816 return M4NO_ERROR; 817 } 818 819 /** 820 ****************************************************************************** 821 * M4OSA_ERR M4VSS3GPP_intAudioMixingCompatibility() 822 * @brief This function allows checking if two clips are compatible with each other for 823 * VSS 3GPP audio mixing feature. 824 * @note 825 * @param pC (IN) Context of the audio mixer 826 * @param pInputClipProperties (IN) Clip analysis of the first clip 827 * @param pAddedClipProperties (IN) Clip analysis of the second clip 828 * @return M4NO_ERROR: No error 829 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 830 * @return M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION 831 * @return M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP 832 * @return M4NO_ERROR 833 ****************************************************************************** 834 */ 835 M4OSA_ERR 836 M4VSS3GPP_intAudioMixingCompatibility( M4VSS3GPP_InternalAudioMixingContext 837 *pC, M4VIDEOEDITING_ClipProperties *pInputClipProperties, 838 M4VIDEOEDITING_ClipProperties *pAddedClipProperties ) 839 { 840 M4OSA_Bool bClip1IsAAC = M4OSA_FALSE; 841 M4OSA_Bool bClip2IsAAC = M4OSA_FALSE; 842 843 /** 844 * Reset settings */ 845 pInputClipProperties->bAudioIsEditable = M4OSA_FALSE; 846 pAddedClipProperties->bAudioIsEditable = M4OSA_FALSE; 847 pInputClipProperties->bAudioIsCompatibleWithMasterClip = M4OSA_FALSE; 848 pAddedClipProperties->bAudioIsCompatibleWithMasterClip = M4OSA_FALSE; 849 850 /** 851 * Check that analysis has been generated by this version of the VSS3GPP library */ 852 if( ( pInputClipProperties->Version[0] != M4VIDEOEDITING_VERSION_MAJOR) 853 || (pInputClipProperties->Version[1] != M4VIDEOEDITING_VERSION_MINOR) 854 || (pInputClipProperties->Version[2] 855 != M4VIDEOEDITING_VERSION_REVISION) ) 856 { 857 M4OSA_TRACE1_0( 858 "M4VSS3GPP_intAudioMixingCompatibility: The clip analysis has been generated\ 859 by another version, returning M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION"); 860 return M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION; 861 } 862 863 if( ( pAddedClipProperties->Version[0] != M4VIDEOEDITING_VERSION_MAJOR) 864 || (pAddedClipProperties->Version[1] != M4VIDEOEDITING_VERSION_MINOR) 865 || (pAddedClipProperties->Version[2] 866 != M4VIDEOEDITING_VERSION_REVISION) ) 867 { 868 M4OSA_TRACE1_0( 869 "M4VSS3GPP_intAudioMixingCompatibility: The clip analysis has been generated\ 870 by another version, returning M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION"); 871 return M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION; 872 } 873 874 /********* input file type *********/ 875 876 if( M4VIDEOEDITING_kFileType_3GPP != pInputClipProperties->FileType ) 877 { 878 M4OSA_TRACE1_0( 879 "M4VSS3GPP_intAudioMixingCompatibility:\ 880 returning M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP"); 881 return M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP; 882 } 883 884 /********* input audio *********/ 885 886 if( M4VIDEOEDITING_kNoneAudio != pInputClipProperties-> 887 AudioStreamType ) /**< if there is an audio stream */ 888 { 889 /** 890 * Check audio format is AMR-NB or AAC */ 891 switch( pInputClipProperties->AudioStreamType ) 892 { 893 case M4VIDEOEDITING_kAMR_NB: 894 pInputClipProperties->bAudioIsEditable = M4OSA_TRUE; 895 break; 896 897 case M4VIDEOEDITING_kAAC: 898 case M4VIDEOEDITING_kAACplus: 899 case M4VIDEOEDITING_keAACplus: 900 switch( pInputClipProperties->uiSamplingFrequency ) 901 { 902 case 8000: 903 case 16000: 904 case 22050: 905 case 24000: 906 case 32000: 907 case 44100: 908 case 48000: 909 pInputClipProperties->bAudioIsEditable = M4OSA_TRUE; 910 break; 911 912 default: 913 break; 914 } 915 bClip1IsAAC = M4OSA_TRUE; 916 break; 917 default: 918 break; 919 } 920 } 921 else 922 { 923 /* Silence is always editable */ 924 pInputClipProperties->bAudioIsEditable = M4OSA_TRUE; 925 } 926 927 /********* added audio *********/ 928 929 if( M4VIDEOEDITING_kNoneAudio != pAddedClipProperties-> 930 AudioStreamType ) /**< if there is an audio stream */ 931 { 932 /** 933 * Check audio format is AMR-NB or AAC */ 934 switch( pAddedClipProperties->AudioStreamType ) 935 { 936 case M4VIDEOEDITING_kAMR_NB: 937 pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE; 938 pAddedClipProperties->bAudioIsCompatibleWithMasterClip = 939 M4OSA_TRUE; /* I use this field to know if silence supported */ 940 break; 941 942 case M4VIDEOEDITING_kAAC: 943 case M4VIDEOEDITING_kAACplus: 944 case M4VIDEOEDITING_keAACplus: 945 switch( pAddedClipProperties->uiSamplingFrequency ) 946 { 947 case 8000: 948 case 16000: 949 case 22050: 950 case 24000: 951 case 32000: 952 case 44100: 953 case 48000: 954 pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE; 955 break; 956 957 default: 958 break; 959 } 960 pAddedClipProperties->bAudioIsCompatibleWithMasterClip = 961 M4OSA_TRUE; /* I use this field to know if silence supported */ 962 bClip2IsAAC = M4OSA_TRUE; 963 break; 964 965 case M4VIDEOEDITING_kEVRC: 966 break; 967 968 case M4VIDEOEDITING_kPCM: 969 pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE; 970 pAddedClipProperties->bAudioIsCompatibleWithMasterClip = 971 M4OSA_TRUE; /* I use this field to know if silence supported */ 972 973 if( pAddedClipProperties->uiSamplingFrequency == 16000 ) 974 { 975 bClip2IsAAC = M4OSA_TRUE; 976 } 977 break; 978 979 case M4VIDEOEDITING_kMP3: /*RC*/ 980 pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE; 981 pAddedClipProperties->bAudioIsCompatibleWithMasterClip = 982 M4OSA_TRUE; /* I use this field to know if silence supported */ 983 break; 984 985 default: 986 /* The writer cannot write this into a 3gpp */ 987 M4OSA_TRACE1_0( 988 "M4VSS3GPP_intAudioMixingCompatibility:\ 989 returning M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM"); 990 return M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM; 991 } 992 } 993 else 994 { 995 /* Silence is always editable */ 996 pAddedClipProperties->bAudioIsEditable = M4OSA_TRUE; 997 pAddedClipProperties->bAudioIsCompatibleWithMasterClip = 998 M4OSA_TRUE; /* I use this field to know if silence supported */ 999 } 1000 1001 if( pC->bRemoveOriginal == M4OSA_FALSE ) 1002 { 1003 if( pInputClipProperties->uiSamplingFrequency 1004 != pAddedClipProperties->uiSamplingFrequency ) 1005 { 1006 /* We need to call SSRC in order to align ASF and/or nb of channels */ 1007 /* Moreover, audio encoder may be needed in case of audio replacing... */ 1008 pC->b_SSRCneeded = M4OSA_TRUE; 1009 } 1010 1011 if( pInputClipProperties->uiNbChannels 1012 < pAddedClipProperties->uiNbChannels ) 1013 { 1014 /* Stereo to Mono */ 1015 pC->ChannelConversion = 1; 1016 } 1017 else if( pInputClipProperties->uiNbChannels 1018 > pAddedClipProperties->uiNbChannels ) 1019 { 1020 /* Mono to Stereo */ 1021 pC->ChannelConversion = 2; 1022 } 1023 } 1024 1025 pInputClipProperties->bAudioIsCompatibleWithMasterClip = M4OSA_TRUE; 1026 1027 /** 1028 * Return with no error */ 1029 M4OSA_TRACE3_0( 1030 "M4VSS3GPP_intAudioMixingCompatibility(): returning M4NO_ERROR"); 1031 return M4NO_ERROR; 1032 } 1033