M4VSS3GPP_Edit.c revision 0a25bd5bacf5408ca205b15e53cfb6dc2fc1d171
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_Edit.c 19 * @brief Video Studio Service 3GPP edit API implementation. 20 * @note 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_InternalTypes.h" 33#include "M4VSS3GPP_InternalFunctions.h" 34#include "M4VSS3GPP_InternalConfig.h" 35#include "M4VSS3GPP_ErrorCodes.h" 36 37 38/** 39 * OSAL headers */ 40#include "M4OSA_Memory.h" /**< OSAL memory management */ 41#include "M4OSA_Debug.h" /**< OSAL debug management */ 42#include "M4OSA_CharStar.h" /**< OSAL string management */ 43 44#ifdef WIN32 45#include "string.h" /**< for strcpy (Don't want to get dependencies 46 with M4OSA_String...) */ 47 48#endif /* WIN32 */ 49#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS 50#include "M4VD_EXTERNAL_Interface.h" 51#endif 52 53/************************************************************************/ 54/* Static local functions */ 55/************************************************************************/ 56static M4OSA_ERR M4VSS3GPP_intClipSettingsSanityCheck( 57 M4VSS3GPP_ClipSettings *pClip ); 58static M4OSA_ERR M4VSS3GPP_intTransitionSettingsSanityCheck( 59 M4VSS3GPP_TransitionSettings *pTransition ); 60static M4OSA_Void M4VSS3GPP_intFreeSettingsList( 61 M4VSS3GPP_InternalEditContext *pC ); 62static M4OSA_ERR 63M4VSS3GPP_intCreateMP3OutputFile( M4VSS3GPP_InternalEditContext *pC, 64 M4OSA_Void *pOutputFile ); 65static M4OSA_ERR M4VSS3GPP_intSwitchToNextClip( 66 M4VSS3GPP_InternalEditContext *pC ); 67static M4OSA_ERR 68M4VSS3GPP_intComputeOutputVideoAndAudioDsi( M4VSS3GPP_InternalEditContext *pC, 69 M4OSA_UInt8 uiMasterClip ); 70static M4OSA_Void M4VSS3GPP_intComputeOutputAverageVideoBitrate( 71 M4VSS3GPP_InternalEditContext *pC ); 72 73/** 74 ****************************************************************************** 75 * M4OSA_ERR M4VSS3GPP_GetVersion() 76 * @brief Get the VSS 3GPP version. 77 * @note Can be called anytime. Do not need any context. 78 * @param pVersionInfo (OUT) Pointer to a version info structure 79 * @return M4NO_ERROR: No error 80 * @return M4ERR_PARAMETER: pVersionInfo is M4OSA_NULL (If Debug Level >= 2) 81 ****************************************************************************** 82 */ 83M4OSA_ERR M4VSS3GPP_GetVersion( M4_VersionInfo *pVersionInfo ) 84{ 85 M4OSA_TRACE3_1("M4VSS3GPP_GetVersion called with pVersionInfo=0x%x", 86 pVersionInfo); 87 88 /** 89 * Check input parameters */ 90 M4OSA_DEBUG_IF2((M4OSA_NULL == pVersionInfo), M4ERR_PARAMETER, 91 "M4VSS3GPP_GetVersion: pVersionInfo is M4OSA_NULL"); 92 93 pVersionInfo->m_major = M4VSS_VERSION_MAJOR; 94 pVersionInfo->m_minor = M4VSS_VERSION_MINOR; 95 pVersionInfo->m_revision = M4VSS_VERSION_REVISION; 96 97 return M4NO_ERROR; 98} 99 100/** 101 ****************************************************************************** 102 * M4OSA_ERR M4VSS3GPP_editInit() 103 * @brief Initializes the VSS 3GPP edit operation (allocates an execution context). 104 * @note 105 * @param pContext (OUT) Pointer on the VSS 3GPP edit context to allocate 106 * @param pFileReadPtrFct (IN) Pointer to OSAL file reader functions 107 * @param pFileWritePtrFct (IN) Pointer to OSAL file writer functions 108 * @return M4NO_ERROR: No error 109 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL 110 * @return M4ERR_ALLOC: There is no more available memory 111 ****************************************************************************** 112 */ 113M4OSA_ERR M4VSS3GPP_editInit( M4VSS3GPP_EditContext *pContext, 114 M4OSA_FileReadPointer *pFileReadPtrFct, 115 M4OSA_FileWriterPointer *pFileWritePtrFct ) 116{ 117 M4VSS3GPP_InternalEditContext *pC; 118 M4OSA_ERR err; 119 M4OSA_UInt32 i; 120 121 M4OSA_TRACE3_3( 122 "M4VSS3GPP_editInit called with pContext=0x%x, \ 123 pFileReadPtrFct=0x%x, pFileWritePtrFct=0x%x", 124 pContext, pFileReadPtrFct, pFileWritePtrFct); 125 126 /** 127 * Check input parameters */ 128 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 129 "M4VSS3GPP_editInit: pContext is M4OSA_NULL"); 130 M4OSA_DEBUG_IF2((M4OSA_NULL == pFileReadPtrFct), M4ERR_PARAMETER, 131 "M4VSS3GPP_editInit: pFileReadPtrFct is M4OSA_NULL"); 132 M4OSA_DEBUG_IF2((M4OSA_NULL == pFileWritePtrFct), M4ERR_PARAMETER, 133 "M4VSS3GPP_editInit: pFileWritePtrFct is M4OSA_NULL"); 134 135 /** 136 * Allocate the VSS context and return it to the user */ 137 pC = (M4VSS3GPP_InternalEditContext 138 *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_InternalEditContext), 139 M4VSS3GPP, (M4OSA_Char *)"M4VSS3GPP_InternalContext"); 140 *pContext = pC; 141 /* Inialization of context Variables */ 142 memset((void *)pC, 0,sizeof(M4VSS3GPP_InternalEditContext)); 143 144 if( M4OSA_NULL == pC ) 145 { 146 M4OSA_TRACE1_0( 147 "M4VSS3GPP_editInit(): unable to allocate M4VSS3GPP_InternalContext,\ 148 returning M4ERR_ALLOC"); 149 return M4ERR_ALLOC; 150 } 151 152 153 /* Init the context. */ 154 pC->uiClipNumber = 0; 155 pC->pClipList = M4OSA_NULL; 156 pC->pTransitionList = M4OSA_NULL; 157 pC->pEffectsList = M4OSA_NULL; 158 pC->pActiveEffectsList = M4OSA_NULL; 159 pC->pActiveEffectsList1 = M4OSA_NULL; 160 pC->uiCurrentClip = 0; 161 pC->pC1 = M4OSA_NULL; 162 pC->pC2 = M4OSA_NULL; 163 pC->yuv1[0].pac_data = pC->yuv1[1].pac_data = pC-> 164 yuv1[2].pac_data = M4OSA_NULL; 165 pC->yuv2[0].pac_data = pC->yuv2[1].pac_data = pC-> 166 yuv2[2].pac_data = M4OSA_NULL; 167 pC->yuv3[0].pac_data = pC->yuv3[1].pac_data = pC-> 168 yuv3[2].pac_data = M4OSA_NULL; 169 pC->yuv4[0].pac_data = pC->yuv4[1].pac_data = pC-> 170 yuv4[2].pac_data = M4OSA_NULL; 171 pC->bClip1AtBeginCut = M4OSA_FALSE; 172 pC->iClip1ActiveEffect = 0; 173 pC->iClip2ActiveEffect = 0; 174 pC->bTransitionEffect = M4OSA_FALSE; 175 pC->bSupportSilence = M4OSA_FALSE; 176 177 /** 178 * Init PC->ewc members */ 179 // Decorrelate input and output encoding timestamp to handle encoder prefetch 180 pC->ewc.dInputVidCts = 0.0; 181 pC->ewc.dOutputVidCts = 0.0; 182 pC->ewc.dATo = 0.0; 183 pC->ewc.iOutputDuration = 0; 184 pC->ewc.VideoStreamType = M4SYS_kVideoUnknown; 185 pC->ewc.uiVideoBitrate = 0; 186 pC->ewc.uiVideoWidth = 0; 187 pC->ewc.uiVideoHeight = 0; 188 pC->ewc.uiVideoTimeScale = 0; 189 pC->ewc.bVideoDataPartitioning = M4OSA_FALSE; 190 pC->ewc.pVideoOutputDsi = M4OSA_NULL; 191 pC->ewc.uiVideoOutputDsiSize = 0; 192 pC->ewc.AudioStreamType = M4SYS_kAudioUnknown; 193 pC->ewc.uiNbChannels = 1; 194 pC->ewc.uiAudioBitrate = 0; 195 pC->ewc.uiSamplingFrequency = 0; 196 pC->ewc.pAudioOutputDsi = M4OSA_NULL; 197 pC->ewc.uiAudioOutputDsiSize = 0; 198 pC->ewc.pAudioEncCtxt = M4OSA_NULL; 199 pC->ewc.pAudioEncDSI.infoSize = 0; 200 pC->ewc.pAudioEncDSI.pInfo = M4OSA_NULL; 201 pC->ewc.uiSilencePcmSize = 0; 202 pC->ewc.pSilenceFrameData = M4OSA_NULL; 203 pC->ewc.uiSilenceFrameSize = 0; 204 pC->ewc.iSilenceFrameDuration = 0; 205 pC->ewc.scale_audio = 0.0; 206 pC->ewc.pEncContext = M4OSA_NULL; 207 pC->ewc.pDummyAuBuffer = M4OSA_NULL; 208 pC->ewc.iMpeg4GovOffset = 0; 209 pC->ewc.VppError = 0; 210 pC->ewc.encoderState = M4VSS3GPP_kNoEncoder; 211 pC->ewc.p3gpWriterContext = M4OSA_NULL; 212 pC->ewc.uiVideoMaxAuSize = 0; 213 pC->ewc.uiAudioMaxAuSize = 0; 214 /** 215 * Keep the OSAL file functions pointer set in our context */ 216 pC->pOsaFileReadPtr = pFileReadPtrFct; 217 pC->pOsaFileWritPtr = pFileWritePtrFct; 218 219 /* 220 * Reset pointers for media and codecs interfaces */ 221 222 err = M4VSS3GPP_clearInterfaceTables(&pC->ShellAPI); 223 M4ERR_CHECK_RETURN(err); 224 225 /* 226 * Call the media and codecs subscription module */ 227 err = M4VSS3GPP_subscribeMediaAndCodec(&pC->ShellAPI); 228 M4ERR_CHECK_RETURN(err); 229 230 /** 231 * Update main state automaton */ 232 pC->State = M4VSS3GPP_kEditState_CREATED; 233 pC->Vstate = M4VSS3GPP_kEditVideoState_READ_WRITE; 234 pC->Astate = M4VSS3GPP_kEditAudioState_READ_WRITE; 235 /* The flag is set to false at the beginning of every clip */ 236 pC->m_bClipExternalHasStarted = M4OSA_FALSE; 237 238 pC->bIsMMS = M4OSA_FALSE; 239 240 pC->iInOutTimeOffset = 0; 241 pC->bEncodeTillEoF = M4OSA_FALSE; 242 pC->nbActiveEffects = 0; 243 pC->nbActiveEffects1 = 0; 244 pC->bIssecondClip = M4OSA_FALSE; 245 pC->m_air_context = M4OSA_NULL; 246 /** 247 * Return with no error */ 248 M4OSA_TRACE3_0("M4VSS3GPP_editInit(): returning M4NO_ERROR"); 249 return M4NO_ERROR; 250} 251 252/** 253 ****************************************************************************** 254 * M4OSA_ERR M4VSS3GPP_editCreateClipSettings() 255 * @brief Allows filling a clip settings structure with default values 256 * 257 * @note WARNING: pClipSettings->Effects[ ] will be allocated in this function. 258 * pClipSettings->pFile will be allocated in this function. 259 * 260 * @param pClipSettings (IN) Pointer to a valid M4VSS3GPP_ClipSettings structure 261 * @param pFile (IN) Clip file name 262 * @param filePathSize (IN) Clip path size (needed for UTF 16 conversion) 263 * @param nbEffects (IN) Nb of effect settings to allocate 264 * @return M4NO_ERROR: No error 265 * @return M4ERR_PARAMETER: pClipSettings is M4OSA_NULL (debug only) 266 ****************************************************************************** 267 */ 268M4OSA_ERR 269M4VSS3GPP_editCreateClipSettings( M4VSS3GPP_ClipSettings *pClipSettings, 270 M4OSA_Void *pFile, M4OSA_UInt32 filePathSize, 271 M4OSA_UInt8 nbEffects ) 272{ 273 M4OSA_UInt8 uiFx; 274 275 M4OSA_TRACE3_1( 276 "M4VSS3GPP_editCreateClipSettings called with pClipSettings=0x%p", 277 pClipSettings); 278 279 /** 280 * Check input parameter */ 281 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettings), M4ERR_PARAMETER, 282 "M4VSS3GPP_editCreateClipSettings: pClipSettings is NULL"); 283 284 /** 285 * Set the clip settings to default */ 286 pClipSettings->pFile = M4OSA_NULL; /**< no file */ 287 pClipSettings->FileType = 288 M4VIDEOEDITING_kFileType_Unsupported; /**< undefined */ 289 290 if( M4OSA_NULL != pFile ) 291 { 292 //pClipSettings->pFile = (M4OSA_Char*) M4OSA_32bitAlignedMalloc(strlen(pFile)+1, M4VSS3GPP, 293 // "pClipSettings->pFile"); 294 /*FB: add clip path size because of utf 16 conversion*/ 295 pClipSettings->pFile = 296 (M4OSA_Void *)M4OSA_32bitAlignedMalloc(filePathSize + 1, M4VSS3GPP, 297 (M4OSA_Char *)"pClipSettings->pFile"); 298 299 if( M4OSA_NULL == pClipSettings->pFile ) 300 { 301 M4OSA_TRACE1_0( 302 "M4VSS3GPP_editCreateClipSettings : ERROR allocating filename"); 303 return M4ERR_ALLOC; 304 } 305 //memcpy(pClipSettings->pFile, pFile, strlen(pFile)+1); 306 /*FB: add clip path size because of utf 16 conversion*/ 307 memcpy((void *)pClipSettings->pFile, (void *)pFile, filePathSize + 1); 308 } 309 310 /*FB: add file path size to support UTF16 conversion*/ 311 pClipSettings->filePathSize = filePathSize + 1; 312 /**/ 313 pClipSettings->ClipProperties.bAnalysed = M4OSA_FALSE; 314 pClipSettings->ClipProperties.FileType = 0; 315 pClipSettings->ClipProperties.Version[0] = 0; 316 pClipSettings->ClipProperties.Version[1] = 0; 317 pClipSettings->ClipProperties.Version[2] = 0; 318 pClipSettings->ClipProperties.uiClipDuration = 0; 319 320 pClipSettings->uiBeginCutTime = 0; /**< no begin cut */ 321 pClipSettings->uiEndCutTime = 0; /**< no end cut */ 322 pClipSettings->ClipProperties.bSetImageData = M4OSA_FALSE; 323 324 /** 325 * Reset video characteristics */ 326 pClipSettings->ClipProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo; 327 pClipSettings->ClipProperties.uiClipVideoDuration = 0; 328 pClipSettings->ClipProperties.uiVideoBitrate = 0; 329 pClipSettings->ClipProperties.uiVideoMaxAuSize = 0; 330 pClipSettings->ClipProperties.uiVideoWidth = 0; 331 pClipSettings->ClipProperties.uiVideoHeight = 0; 332 pClipSettings->ClipProperties.uiVideoTimeScale = 0; 333 pClipSettings->ClipProperties.fAverageFrameRate = 0.0; 334 pClipSettings->ClipProperties.uiVideoProfile = 335 M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE; 336 pClipSettings->ClipProperties.uiVideoLevel = 337 M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL; 338 pClipSettings->ClipProperties.bMPEG4dataPartition = M4OSA_FALSE; 339 pClipSettings->ClipProperties.bMPEG4rvlc = M4OSA_FALSE; 340 pClipSettings->ClipProperties.bMPEG4resynchMarker = M4OSA_FALSE; 341 342 /** 343 * Reset audio characteristics */ 344 pClipSettings->ClipProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio; 345 pClipSettings->ClipProperties.uiClipAudioDuration = 0; 346 pClipSettings->ClipProperties.uiAudioBitrate = 0; 347 pClipSettings->ClipProperties.uiAudioMaxAuSize = 0; 348 pClipSettings->ClipProperties.uiNbChannels = 0; 349 pClipSettings->ClipProperties.uiSamplingFrequency = 0; 350 pClipSettings->ClipProperties.uiExtendedSamplingFrequency = 0; 351 pClipSettings->ClipProperties.uiDecodedPcmSize = 0; 352 353 /** 354 * Return with no error */ 355 M4OSA_TRACE3_0("M4VSS3GPP_editSetDefaultSettings(): returning M4NO_ERROR"); 356 357 return M4NO_ERROR; 358} 359 360/** 361 ****************************************************************************** 362 * M4OSA_ERR M4VSS3GPP_editDuplicateClipSettings() 363 * @brief Duplicates a clip settings structure, performing allocations if required 364 * 365 * @param pClipSettingsDest (IN) Pointer to a valid M4VSS3GPP_ClipSettings structure 366 * @param pClipSettingsOrig (IN) Pointer to a valid M4VSS3GPP_ClipSettings structure 367 * @param bCopyEffects (IN) Flag to know if we have to duplicate effects 368 * @return M4NO_ERROR: No error 369 * @return M4ERR_PARAMETER: pClipSettings is M4OSA_NULL (debug only) 370 ****************************************************************************** 371 */ 372M4OSA_ERR 373M4VSS3GPP_editDuplicateClipSettings( M4VSS3GPP_ClipSettings *pClipSettingsDest, 374 M4VSS3GPP_ClipSettings *pClipSettingsOrig, 375 M4OSA_Bool bCopyEffects ) 376{ 377 M4OSA_UInt8 uiFx; 378 379 M4OSA_TRACE3_2( 380 "M4VSS3GPP_editDuplicateClipSettings called with dest=0x%p src=0x%p", 381 pClipSettingsDest, pClipSettingsOrig); 382 383 /* Check input parameter */ 384 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettingsDest), M4ERR_PARAMETER, 385 "M4VSS3GPP_editDuplicateClipSettings: pClipSettingsDest is NULL"); 386 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettingsOrig), M4ERR_PARAMETER, 387 "M4VSS3GPP_editDuplicateClipSettings: pClipSettingsOrig is NULL"); 388 389 /* Copy plain structure */ 390 memcpy((void *)pClipSettingsDest, 391 (void *)pClipSettingsOrig, sizeof(M4VSS3GPP_ClipSettings)); 392 393 /* Duplicate filename */ 394 if( M4OSA_NULL != pClipSettingsOrig->pFile ) 395 { 396 //pClipSettingsDest->pFile = 397 // (M4OSA_Char*) M4OSA_32bitAlignedMalloc(strlen(pClipSettingsOrig->pFile)+1, M4VSS3GPP, 398 // "pClipSettingsDest->pFile"); 399 /*FB: clip path size is needed for utf 16 conversion*/ 400 /*FB 2008/10/16: bad allocation size which raises a crash*/ 401 pClipSettingsDest->pFile = 402 (M4OSA_Char *)M4OSA_32bitAlignedMalloc(pClipSettingsOrig->filePathSize + 1, 403 M4VSS3GPP, (M4OSA_Char *)"pClipSettingsDest->pFile"); 404 405 if( M4OSA_NULL == pClipSettingsDest->pFile ) 406 { 407 M4OSA_TRACE1_0( 408 "M4VSS3GPP_editDuplicateClipSettings : ERROR allocating filename"); 409 return M4ERR_ALLOC; 410 } 411 /*FB: clip path size is needed for utf 16 conversion*/ 412 //memcpy(pClipSettingsDest->pFile, pClipSettingsOrig->pFile, 413 // strlen(pClipSettingsOrig->pFile)+1); 414 /*FB 2008/10/16: bad allocation size which raises a crash*/ 415 memcpy((void *)pClipSettingsDest->pFile, (void *)pClipSettingsOrig->pFile, 416 pClipSettingsOrig->filePathSize/*+1*/); 417 ( (M4OSA_Char 418 *)pClipSettingsDest->pFile)[pClipSettingsOrig->filePathSize] = '\0'; 419 } 420 421 /* Duplicate effects */ 422 /* Return with no error */ 423 424 M4OSA_TRACE3_0( 425 "M4VSS3GPP_editDuplicateClipSettings(): returning M4NO_ERROR"); 426 427 return M4NO_ERROR; 428} 429 430/** 431 ****************************************************************************** 432 * M4OSA_ERR M4VSS3GPP_editFreeClipSettings() 433 * @brief Free the pointers allocated in the ClipSetting structure (pFile, Effects). 434 * 435 * @param pClipSettings (IN) Pointer to a valid M4VSS3GPP_ClipSettings structure 436 * @return M4NO_ERROR: No error 437 * @return M4ERR_PARAMETER: pClipSettings is M4OSA_NULL (debug only) 438 ****************************************************************************** 439 */ 440M4OSA_ERR M4VSS3GPP_editFreeClipSettings( 441 M4VSS3GPP_ClipSettings *pClipSettings ) 442{ 443 /** 444 * Check input parameter */ 445 M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettings), M4ERR_PARAMETER, 446 "M4VSS3GPP_editFreeClipSettings: pClipSettings is NULL"); 447 448 /* free filename */ 449 if( M4OSA_NULL != pClipSettings->pFile ) 450 { 451 free(pClipSettings->pFile); 452 pClipSettings->pFile = M4OSA_NULL; 453 } 454 455 /* free effects settings */ 456 /* if(M4OSA_NULL != pClipSettings->Effects) 457 { 458 free(pClipSettings->Effects); 459 pClipSettings->Effects = M4OSA_NULL; 460 pClipSettings->nbEffects = 0; 461 } RC */ 462 463 return M4NO_ERROR; 464} 465 466/** 467 ****************************************************************************** 468 * M4OSA_ERR M4VSS3GPP_editOpen() 469 * @brief Set the VSS input and output files. 470 * @note It opens the input file, but the output file may not be created yet. 471 * @param pContext (IN) VSS edit context 472 * @param pSettings (IN) Edit settings 473 * @return M4NO_ERROR: No error 474 * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) 475 * @return M4ERR_STATE: VSS is not in an appropriate state for this function to be called 476 * @return M4ERR_ALLOC: There is no more available memory 477 ****************************************************************************** 478 */ 479M4OSA_ERR M4VSS3GPP_editOpen( M4VSS3GPP_EditContext pContext, 480 M4VSS3GPP_EditSettings *pSettings ) 481{ 482 M4VSS3GPP_InternalEditContext *pC = 483 (M4VSS3GPP_InternalEditContext *)pContext; 484 485 M4OSA_ERR err; 486 M4OSA_Int32 i; 487 M4VIDEOEDITING_FileType outputFileType = 488 M4VIDEOEDITING_kFileType_Unsupported; /**< 3GPP or MP3 (we don't do AMR output) */ 489 M4OSA_UInt32 uiC1duration, uiC2duration; 490 491 M4OSA_TRACE3_2( 492 "M4VSS3GPP_editOpen called with pContext=0x%x, pSettings=0x%x", 493 pContext, pSettings); 494 495 /** 496 * Check input parameters */ 497 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 498 "M4VSS3GPP_editOpen: pContext is M4OSA_NULL"); 499 M4OSA_DEBUG_IF2((M4OSA_NULL == pSettings), M4ERR_PARAMETER, 500 "M4VSS3GPP_editOpen: pSettings is M4OSA_NULL"); 501 M4OSA_DEBUG_IF2((M4OSA_NULL == pSettings->pClipList), M4ERR_PARAMETER, 502 "M4VSS3GPP_editOpen: pSettings->pClipList is M4OSA_NULL"); 503 M4OSA_DEBUG_IF2(( pSettings->uiClipNumber > 1) 504 && (M4OSA_NULL == pSettings->pTransitionList), M4ERR_PARAMETER, 505 "M4VSS3GPP_editOpen: pSettings->pTransitionList is M4OSA_NULL"); 506 507 /** 508 * Check state automaton */ 509 if( ( pC->State != M4VSS3GPP_kEditState_CREATED) 510 && (pC->State != M4VSS3GPP_kEditState_CLOSED) ) 511 { 512 M4OSA_TRACE1_1( 513 "M4VSS3GPP_editOpen: State error (0x%x)! Returning M4ERR_STATE", 514 pC->State); 515 return M4ERR_STATE; 516 } 517 518 /** 519 * Free any previously allocated internal settings list */ 520 M4VSS3GPP_intFreeSettingsList(pC); 521 522 /** 523 * Copy the user settings in our context */ 524 pC->uiClipNumber = pSettings->uiClipNumber; 525 526 /** 527 * Copy the clip list */ 528 pC->pClipList = 529 (M4VSS3GPP_ClipSettings *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_ClipSettings) 530 * pC->uiClipNumber, M4VSS3GPP, (M4OSA_Char *)"pC->pClipList"); 531 532 if( M4OSA_NULL == pC->pClipList ) 533 { 534 M4OSA_TRACE1_0( 535 "M4VSS3GPP_editOpen: unable to allocate pC->Settings.pClipList,\ 536 returning M4ERR_ALLOC"); 537 return M4ERR_ALLOC; 538 } 539 540 for ( i = 0; i < pSettings->uiClipNumber; i++ ) 541 { 542 M4VSS3GPP_editDuplicateClipSettings(&(pC->pClipList[i]), 543 pSettings->pClipList[i], M4OSA_TRUE); 544 } 545 546 /** 547 * Copy effects list RC */ 548 549 /*FB bug fix 19.03.2008 if the number of effects is 0 -> crash*/ 550 if( pSettings->nbEffects > 0 ) 551 { 552 pC->nbEffects = pSettings->nbEffects; 553 pC->pEffectsList = (M4VSS3GPP_EffectSettings 554 *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_EffectSettings) * pC->nbEffects, 555 M4VSS3GPP, (M4OSA_Char *)"pC->pEffectsList"); 556 557 if( M4OSA_NULL == pC->pEffectsList ) 558 { 559 M4OSA_TRACE1_0( 560 "M4VSS3GPP_editOpen: unable to allocate pC->pEffectsList, returning M4ERR_ALLOC"); 561 return M4ERR_ALLOC; 562 } 563 564 for ( i = 0; i < pC->nbEffects; i++ ) 565 { 566 memcpy((void *) &(pC->pEffectsList[i]), 567 (void *) &(pSettings->Effects[i]), 568 sizeof(M4VSS3GPP_EffectSettings)); 569 } 570 571 /** 572 * Allocate active effects list RC */ 573 pC->pActiveEffectsList = 574 (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(sizeof(M4OSA_UInt8) * pC->nbEffects, 575 M4VSS3GPP, (M4OSA_Char *)"pC->pActiveEffectsList"); 576 577 if( M4OSA_NULL == pC->pActiveEffectsList ) 578 { 579 M4OSA_TRACE1_0( 580 "M4VSS3GPP_editOpen: unable to allocate pC->pActiveEffectsList,\ 581 returning M4ERR_ALLOC"); 582 return M4ERR_ALLOC; 583 } 584 /** 585 * Allocate active effects list */ 586 pC->pActiveEffectsList1 = 587 (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(sizeof(M4OSA_UInt8) * pC->nbEffects, 588 M4VSS3GPP, (M4OSA_Char *)"pC->pActiveEffectsList"); 589 if (M4OSA_NULL == pC->pActiveEffectsList1) 590 { 591 M4OSA_TRACE1_0("M4VSS3GPP_editOpen: unable to allocate pC->pActiveEffectsList, \ 592 returning M4ERR_ALLOC"); 593 return M4ERR_ALLOC; 594 } 595 596 } 597 else 598 { 599 pC->nbEffects = 0; 600 pC->nbActiveEffects = 0; 601 pC->nbActiveEffects1 = 0; 602 pC->pEffectsList = M4OSA_NULL; 603 pC->pActiveEffectsList = M4OSA_NULL; 604 pC->pActiveEffectsList1 = M4OSA_NULL; 605 } 606 607 /** 608 * Test the clip analysis data, if it is not provided, analyse the clips by ourselves. */ 609 for ( i = 0; i < pC->uiClipNumber; i++ ) 610 { 611 if( M4OSA_FALSE == pC->pClipList[i].ClipProperties.bAnalysed ) 612 { 613 /**< Analysis not provided by the integrator */ 614 err = M4VSS3GPP_editAnalyseClip(pC->pClipList[i].pFile, 615 pC->pClipList[i].FileType, &pC->pClipList[i].ClipProperties, 616 pC->pOsaFileReadPtr); 617 618 if( M4NO_ERROR != err ) 619 { 620 M4OSA_TRACE1_1( 621 "M4VSS3GPP_editOpen: M4VSS3GPP_editAnalyseClip returns 0x%x!", 622 err); 623 return err; 624 } 625 } 626 } 627 628 /** 629 * Check clip compatibility */ 630 for ( i = 0; i < pC->uiClipNumber; i++ ) 631 { 632 if (pC->pClipList[i].FileType !=M4VIDEOEDITING_kFileType_ARGB8888) { 633 /** 634 * Check all the clips are compatible with VSS 3GPP */ 635 err = M4VSS3GPP_intCheckClipCompatibleWithVssEditing( 636 &pC->pClipList[i].ClipProperties); 637 638 if( M4NO_ERROR != err ) 639 { 640 M4OSA_TRACE1_2( 641 "M4VSS3GPP_editOpen:\ 642 M4VSS3GPP_intCheckClipCompatibleWithVssEditing(%d) returns 0x%x!", 643 i, err); 644 return err; 645 } 646 } 647 648 /** 649 * Check the master clip versus all the other ones. 650 (including master clip with itself, else variables for master clip 651 are not properly setted) */ 652 if(pC->pClipList[i].FileType != M4VIDEOEDITING_kFileType_ARGB8888) { 653 654 err = M4VSS3GPP_editCheckClipCompatibility( 655 &pC->pClipList[pSettings->uiMasterClip].ClipProperties, 656 &pC->pClipList[i].ClipProperties); 657 /* in case of warning regarding audio incompatibility, 658 editing continues */ 659 if( M4OSA_ERR_IS_ERROR(err) ) 660 { 661 M4OSA_TRACE1_2( 662 "M4VSS3GPP_editOpen: M4VSS3GPP_editCheckClipCompatibility \ 663 (%d) returns 0x%x!", i, err); 664 return err; 665 } 666 } else { 667 pC->pClipList[i].ClipProperties.bAudioIsCompatibleWithMasterClip = 668 M4OSA_FALSE; 669 } 670 } 671 /* Search audio tracks that cannot be edited : 672 * - delete all audio effects for the clip 673 * - if master clip is editable let the transition 674 (bad track will be replaced later with silence) 675 * - if master clip is not editable switch to a dummy transition (only copy/paste) */ 676 for ( i = 0; i < pC->uiClipNumber; i++ ) 677 { 678 if( M4OSA_FALSE == pC->pClipList[i].ClipProperties.bAudioIsEditable ) 679 { 680 M4OSA_UInt8 uiFx; 681 682 for ( uiFx = 0; uiFx < pC->nbEffects; uiFx++ ) 683 { 684 pC->pEffectsList[uiFx].AudioEffectType 685 = M4VSS3GPP_kAudioEffectType_None; 686 } 687 688 if( ( i < (pC->uiClipNumber - 1)) 689 && (M4OSA_NULL != pSettings->pTransitionList[i]) 690 && (M4OSA_FALSE == pC->pClipList[pSettings-> 691 uiMasterClip].ClipProperties.bAudioIsEditable) ) 692 { 693 pSettings->pTransitionList[i]->AudioTransitionType 694 = M4VSS3GPP_kAudioTransitionType_None; 695 } 696 } 697 } 698 699 /** 700 * We add a transition of duration 0 at the end of the last clip. 701 * It will suppress a whole bunch a test latter in the processing... */ 702 pC->pTransitionList = (M4VSS3GPP_TransitionSettings 703 *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_TransitionSettings) 704 * (pC->uiClipNumber), M4VSS3GPP, (M4OSA_Char *)"pC->pTransitionList"); 705 706 if( M4OSA_NULL == pC->pTransitionList ) 707 { 708 M4OSA_TRACE1_0( 709 "M4VSS3GPP_editOpen: unable to allocate pC->Settings.pTransitionList,\ 710 returning M4ERR_ALLOC"); 711 return M4ERR_ALLOC; 712 } 713 714 /**< copy transition settings */ 715 for ( i = 0; i < (pSettings->uiClipNumber - 1); i++ ) 716 { 717 memcpy((void *) &(pC->pTransitionList[i]), 718 (void *)pSettings->pTransitionList[i], 719 sizeof(M4VSS3GPP_TransitionSettings)); 720 } 721 722 /**< We fill the last "dummy" transition */ 723 pC->pTransitionList[pC->uiClipNumber - 1].uiTransitionDuration = 0; 724 pC->pTransitionList[pC->uiClipNumber 725 - 1].VideoTransitionType = M4VSS3GPP_kVideoTransitionType_None; 726 pC->pTransitionList[pC->uiClipNumber 727 - 1].AudioTransitionType = M4VSS3GPP_kAudioTransitionType_None; 728 729 /** 730 * Avoid weird clip settings */ 731 for ( i = 0; i < pSettings->uiClipNumber; i++ ) 732 { 733 if (pC->pClipList[i].FileType !=M4VIDEOEDITING_kFileType_ARGB8888) { 734 err = M4VSS3GPP_intClipSettingsSanityCheck(&pC->pClipList[i]); 735 736 if( M4NO_ERROR != err ) 737 { 738 M4OSA_TRACE1_1( 739 "M4VSS3GPP_editOpen: M4VSS3GPP_intClipSettingsSanityCheck returns 0x%x!", 740 err); 741 return err; 742 } 743 } 744 } 745 746 for ( i = 0; i < (pSettings->uiClipNumber - 1); i++ ) 747 { 748 if (pC->pTransitionList[i].uiTransitionDuration != 0) { 749 if (pC->pClipList[i].FileType == M4VIDEOEDITING_kFileType_ARGB8888) { 750 pC->pClipList[i].uiBeginCutTime = 0; 751 pC->pClipList[i].uiEndCutTime = 752 pC->pTransitionList[i].uiTransitionDuration; 753 } 754 755 if (pC->pClipList[i+1].FileType == M4VIDEOEDITING_kFileType_ARGB8888) { 756 pC->pClipList[i+1].uiBeginCutTime = 0; 757 pC->pClipList[i+1].uiEndCutTime = 758 pC->pTransitionList[i].uiTransitionDuration; 759 } 760 } else { 761 762 if (pC->pClipList[i].FileType == M4VIDEOEDITING_kFileType_ARGB8888) { 763 pC->pClipList[i].uiEndCutTime = 764 pC->pClipList[i].uiEndCutTime - pC->pClipList[i].uiBeginCutTime; 765 pC->pClipList[i].uiBeginCutTime = 0; 766 } 767 768 if (pC->pClipList[i+1].FileType == M4VIDEOEDITING_kFileType_ARGB8888) { 769 pC->pClipList[i+1].uiEndCutTime = 770 pC->pClipList[i+1].uiEndCutTime - pC->pClipList[i+1].uiBeginCutTime; 771 pC->pClipList[i+1].uiBeginCutTime = 0; 772 } 773 774 } 775 776 /** 777 * Maximum transition duration between clip n and clip n+1 is the duration 778 * of the shortest clip */ 779 if( 0 == pC->pClipList[i].uiEndCutTime ) 780 { 781 uiC1duration = pC->pClipList[i].ClipProperties.uiClipVideoDuration; 782 } 783 else 784 { 785 /**< duration of clip n is the end cut time */ 786 uiC1duration = pC->pClipList[i].uiEndCutTime; 787 } 788 789 /**< Substract begin cut */ 790 uiC1duration -= pC->pClipList[i].uiBeginCutTime; 791 792 /**< Check that the transition is shorter than clip n */ 793 if( pC->pTransitionList[i].uiTransitionDuration > uiC1duration ) 794 { 795 pC->pTransitionList[i].uiTransitionDuration = uiC1duration - 1; 796 } 797 798 if( 0 == pC->pClipList[i + 1].uiEndCutTime ) 799 { 800 uiC2duration = 801 pC->pClipList[i + 1].ClipProperties.uiClipVideoDuration; 802 } 803 else 804 { 805 /**< duration of clip n+1 is the end cut time */ 806 uiC2duration = pC->pClipList[i + 1].uiEndCutTime; 807 } 808 809 /**< Substract begin cut */ 810 uiC2duration -= pC->pClipList[i + 1].uiBeginCutTime; 811 812 /**< Check that the transition is shorter than clip n+1 */ 813 if( pC->pTransitionList[i].uiTransitionDuration > uiC2duration ) 814 { 815 pC->pTransitionList[i].uiTransitionDuration = uiC2duration - 1; 816 } 817 818 /** 819 * Avoid weird transition settings */ 820 err = 821 M4VSS3GPP_intTransitionSettingsSanityCheck(&pC->pTransitionList[i]); 822 823 if( M4NO_ERROR != err ) 824 { 825 M4OSA_TRACE1_1( 826 "M4VSS3GPP_editOpen: M4VSS3GPP_intClipSettingsSanityCheck returns 0x%x!", 827 err); 828 return err; 829 } 830 831 /** 832 * Check that two transitions are not overlapping 833 (no overlapping possible for first clip) */ 834 if( i > 0 ) 835 { 836 /** 837 * There is a transition overlap if the sum of the duration of 838 two consecutive transitions 839 * is higher than the duration of the clip in-between. */ 840 if( ( pC->pTransitionList[i - 1].uiTransitionDuration 841 + pC->pTransitionList[i].uiTransitionDuration) >= uiC1duration ) 842 { 843 M4OSA_TRACE1_1( 844 "M4VSS3GPP_editOpen: Overlapping transitions on clip %d,\ 845 returning M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS", 846 i); 847 return M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS; 848 } 849 } 850 } 851 852 /** 853 * Output clip duration */ 854 for ( i = 0; i < pC->uiClipNumber; i++ ) 855 { 856 /** 857 * Compute the sum of the clip duration */ 858 if( 0 == pC->pClipList[i].uiEndCutTime ) 859 { 860 pC->ewc.iOutputDuration += 861 pC-> 862 pClipList[ 863 i].ClipProperties. 864 uiClipVideoDuration; /* Only video track duration is important to 865 avoid deviation if audio track is longer */ 866 } 867 else 868 { 869 pC->ewc.iOutputDuration += 870 pC->pClipList[i].uiEndCutTime; /**< Add end cut */ 871 } 872 873 pC->ewc.iOutputDuration -= 874 pC->pClipList[i].uiBeginCutTime; /**< Remove begin cut */ 875 876 /** 877 * Remove the duration of the transition (it is counted twice) */ 878 pC->ewc.iOutputDuration -= pC->pTransitionList[i].uiTransitionDuration; 879 } 880 881 /* Get video properties from output properties */ 882 883 /* Get output width and height */ 884 switch(pC->xVSS.outputVideoSize) { 885 case M4VIDEOEDITING_kSQCIF: 886 pC->ewc.uiVideoWidth = 128; 887 pC->ewc.uiVideoHeight = 96; 888 break; 889 case M4VIDEOEDITING_kQQVGA: 890 pC->ewc.uiVideoWidth = 160; 891 pC->ewc.uiVideoHeight = 120; 892 break; 893 case M4VIDEOEDITING_kQCIF: 894 pC->ewc.uiVideoWidth = 176; 895 pC->ewc.uiVideoHeight = 144; 896 break; 897 case M4VIDEOEDITING_kQVGA: 898 pC->ewc.uiVideoWidth = 320; 899 pC->ewc.uiVideoHeight = 240; 900 break; 901 case M4VIDEOEDITING_kCIF: 902 pC->ewc.uiVideoWidth = 352; 903 pC->ewc.uiVideoHeight = 288; 904 break; 905 case M4VIDEOEDITING_kVGA: 906 pC->ewc.uiVideoWidth = 640; 907 pC->ewc.uiVideoHeight = 480; 908 break; 909 /* +PR LV5807 */ 910 case M4VIDEOEDITING_kWVGA: 911 pC->ewc.uiVideoWidth = 800; 912 pC->ewc.uiVideoHeight = 480; 913 break; 914 case M4VIDEOEDITING_kNTSC: 915 pC->ewc.uiVideoWidth = 720; 916 pC->ewc.uiVideoHeight = 480; 917 break; 918 /* -PR LV5807 */ 919 /* +CR Google */ 920 case M4VIDEOEDITING_k640_360: 921 pC->ewc.uiVideoWidth = 640; 922 pC->ewc.uiVideoHeight = 360; 923 break; 924 925 case M4VIDEOEDITING_k854_480: 926 pC->ewc.uiVideoWidth = M4ENCODER_854_480_Width; 927 pC->ewc.uiVideoHeight = 480; 928 break; 929 930 case M4VIDEOEDITING_k1280_720: 931 pC->ewc.uiVideoWidth = 1280; 932 pC->ewc.uiVideoHeight = 720; 933 break; 934 case M4VIDEOEDITING_k1080_720: 935 pC->ewc.uiVideoWidth = M4ENCODER_1080_720_Width; 936 937 pC->ewc.uiVideoHeight = 720; 938 break; 939 case M4VIDEOEDITING_k960_720: 940 pC->ewc.uiVideoWidth = 960; 941 pC->ewc.uiVideoHeight = 720; 942 break; 943 944 default: /* If output video size is not given, we take QCIF size */ 945 pC->ewc.uiVideoWidth = 176; 946 pC->ewc.uiVideoHeight = 144; 947 pC->xVSS.outputVideoSize = M4VIDEOEDITING_kQCIF; 948 break; 949 } 950 951 pC->ewc.uiVideoTimeScale = 30; 952 pC->ewc.bVideoDataPartitioning = 0; 953 /* Set output video profile and level */ 954 pC->ewc.outputVideoProfile = pC->xVSS.outputVideoProfile; 955 pC->ewc.outputVideoLevel = pC->xVSS.outputVideoLevel; 956 957 switch(pC->xVSS.outputVideoFormat) { 958 case M4VIDEOEDITING_kH263: 959 pC->ewc.VideoStreamType = M4SYS_kH263; 960 break; 961 case M4VIDEOEDITING_kMPEG4: 962 pC->ewc.VideoStreamType = M4SYS_kMPEG_4; 963 break; 964 case M4VIDEOEDITING_kH264: 965 pC->ewc.VideoStreamType = M4SYS_kH264; 966 break; 967 default: 968 pC->ewc.VideoStreamType = M4SYS_kVideoUnknown; 969 break; 970 } 971 972 /** 973 * Copy the audio properties of the master clip to the output properties */ 974 pC->ewc.uiNbChannels = 975 pC->pClipList[pSettings->uiMasterClip].ClipProperties.uiNbChannels; 976 pC->ewc.uiAudioBitrate = 977 pC->pClipList[pSettings->uiMasterClip].ClipProperties.uiAudioBitrate; 978 pC->ewc.uiSamplingFrequency = pC->pClipList[pSettings-> 979 uiMasterClip].ClipProperties.uiSamplingFrequency; 980 pC->ewc.uiSilencePcmSize = 981 pC->pClipList[pSettings->uiMasterClip].ClipProperties.uiDecodedPcmSize; 982 pC->ewc.scale_audio = pC->ewc.uiSamplingFrequency / 1000.0; 983 984 switch( pC->pClipList[pSettings->uiMasterClip].ClipProperties.AudioStreamType ) 985 { 986 case M4VIDEOEDITING_kAMR_NB: 987 pC->ewc.AudioStreamType = M4SYS_kAMR; 988 pC->ewc.pSilenceFrameData = 989 (M4OSA_UInt8 *)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048; 990 pC->ewc.uiSilenceFrameSize = 991 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE; 992 pC->ewc.iSilenceFrameDuration = 993 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_DURATION; 994 pC->bSupportSilence = M4OSA_TRUE; 995 break; 996 997 case M4VIDEOEDITING_kAAC: 998 case M4VIDEOEDITING_kAACplus: 999 case M4VIDEOEDITING_keAACplus: 1000 pC->ewc.AudioStreamType = M4SYS_kAAC; 1001 1002 if( pC->ewc.uiNbChannels == 1 ) 1003 { 1004 pC->ewc.pSilenceFrameData = 1005 (M4OSA_UInt8 *)M4VSS3GPP_AAC_AU_SILENCE_MONO; 1006 pC->ewc.uiSilenceFrameSize = M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE; 1007 pC->bSupportSilence = M4OSA_TRUE; 1008 } 1009 else 1010 { 1011 pC->ewc.pSilenceFrameData = 1012 (M4OSA_UInt8 *)M4VSS3GPP_AAC_AU_SILENCE_STEREO; 1013 pC->ewc.uiSilenceFrameSize = 1014 M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE; 1015 pC->bSupportSilence = M4OSA_TRUE; 1016 } 1017 pC->ewc.iSilenceFrameDuration = 1018 1024; /* AAC is always 1024/Freq sample duration */ 1019 break; 1020 1021 case M4VIDEOEDITING_kMP3: 1022 pC->ewc.AudioStreamType = M4SYS_kMP3; 1023 pC->ewc.pSilenceFrameData = M4OSA_NULL; 1024 pC->ewc.uiSilenceFrameSize = 0; 1025 pC->ewc.iSilenceFrameDuration = 0; 1026 /* Special case, mp3 core reader return a time in ms */ 1027 pC->ewc.scale_audio = 1.0; 1028 break; 1029 1030 case M4VIDEOEDITING_kEVRC: 1031 pC->ewc.AudioStreamType = M4SYS_kEVRC; 1032 pC->ewc.pSilenceFrameData = M4OSA_NULL; 1033 pC->ewc.uiSilenceFrameSize = 0; 1034 pC->ewc.iSilenceFrameDuration = 160; /* EVRC frames are 20 ms at 8000 Hz 1035 (makes it easier to factorize amr and evrc code) */ 1036 break; 1037 1038 default: 1039 pC->ewc.AudioStreamType = M4SYS_kAudioUnknown; 1040 break; 1041 } 1042 1043 for (i=0; i<pC->uiClipNumber; i++) { 1044 if ((pC->pClipList[i].ClipProperties.VideoStreamType != 1045 pC->xVSS.outputVideoFormat)|| 1046 (pC->pClipList[i].ClipProperties.uiVideoWidth != 1047 pC->ewc.uiVideoWidth) || 1048 (pC->pClipList[i].ClipProperties.uiVideoHeight != 1049 pC->ewc.uiVideoHeight) || 1050 (pC->pClipList[i].ClipProperties.VideoStreamType == 1051 M4VIDEOEDITING_kH264) || 1052 (pC->pClipList[i].ClipProperties.VideoStreamType == 1053 M4VIDEOEDITING_kMPEG4 && 1054 pC->pClipList[i].ClipProperties.uiVideoTimeScale != 1055 pC->ewc.uiVideoTimeScale)) { 1056 pC->pClipList[i].bTranscodingRequired = M4OSA_TRUE; 1057 } 1058 } 1059 /** 1060 * We produce a 3gpp file, unless it is mp3 */ 1061 if( M4VIDEOEDITING_kMP3 == pC-> 1062 pClipList[pSettings->uiMasterClip].ClipProperties.AudioStreamType ) 1063 outputFileType = M4VIDEOEDITING_kFileType_MP3; 1064 else 1065 outputFileType = M4VIDEOEDITING_kFileType_3GPP; 1066 1067 /** 1068 * Beware, a null duration would lead to a divide by zero error (better safe than sorry...) */ 1069 if( 0 == pC->ewc.iOutputDuration ) 1070 { 1071 pC->ewc.iOutputDuration = 1; 1072 } 1073 1074 /** 1075 * Open first clip */ 1076 pC->uiCurrentClip = 0; 1077 1078 // Decorrelate input and output encoding timestamp to handle encoder prefetch 1079 pC->ewc.dInputVidCts = 0.0; 1080 pC->ewc.dOutputVidCts = 0.0; 1081 pC->ewc.dATo = 0.0; 1082 1083 err = M4VSS3GPP_intSwitchToNextClip(pC); 1084 /* RC: to know when a file has been processed */ 1085 if( M4NO_ERROR != err && err != M4VSS3GPP_WAR_SWITCH_CLIP ) 1086 { 1087 M4OSA_TRACE1_1( 1088 "M4VSS3GPP_editOpen: M4VSS3GPP_intSwitchToNextClip() returns 0x%x!", 1089 err); 1090 return err; 1091 } 1092 1093 /** 1094 * Do the video stuff in 3GPP Audio/Video case */ 1095 if( M4VIDEOEDITING_kFileType_3GPP == outputFileType ) 1096 { 1097 /** 1098 * Compute the Decoder Specific Info for the output video and audio streams */ 1099 err = M4VSS3GPP_intComputeOutputVideoAndAudioDsi(pC, 1100 pSettings->uiMasterClip); 1101 1102 if( M4NO_ERROR != err ) 1103 { 1104 M4OSA_TRACE1_1( 1105 "M4VSS3GPP_editOpen: M4VSS3GPP_intComputeOutputVideoAndAudioDsi() returns 0x%x!", 1106 err); 1107 return err; 1108 } 1109 1110 /** 1111 * Compute the time increment for the transition file */ 1112 switch( pSettings->videoFrameRate ) 1113 { 1114 case M4VIDEOEDITING_k5_FPS: 1115 pC->dOutputFrameDuration = 1000.0 / 5.0; 1116 break; 1117 1118 case M4VIDEOEDITING_k7_5_FPS: 1119 pC->dOutputFrameDuration = 1000.0 / 7.5; 1120 break; 1121 1122 case M4VIDEOEDITING_k10_FPS: 1123 pC->dOutputFrameDuration = 1000.0 / 10.0; 1124 break; 1125 1126 case M4VIDEOEDITING_k12_5_FPS: 1127 pC->dOutputFrameDuration = 1000.0 / 12.5; 1128 break; 1129 1130 case M4VIDEOEDITING_k15_FPS: 1131 pC->dOutputFrameDuration = 1000.0 / 15.0; 1132 break; 1133 1134 case M4VIDEOEDITING_k20_FPS: 1135 pC->dOutputFrameDuration = 1000.0 / 20.0; 1136 break; 1137 1138 case M4VIDEOEDITING_k25_FPS: 1139 pC->dOutputFrameDuration = 1000.0 / 25.0; 1140 break; 1141 1142 case M4VIDEOEDITING_k30_FPS: 1143 pC->dOutputFrameDuration = 1000.0 / 30.0; 1144 break; 1145 1146 default: 1147 M4OSA_TRACE1_1( 1148 "M4VSS3GPP_editOpen(): invalid videoFrameRate (0x%x),\ 1149 returning M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE", 1150 pSettings->videoFrameRate); 1151 return M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE; 1152 } 1153 1154 if( M4SYS_kMPEG_4 == pC->ewc.VideoStreamType ) 1155 { 1156 M4OSA_UInt32 uiAlpha; 1157 /** 1158 * MPEG-4 case. 1159 * Time scale of the transition encoder must be the same than the 1160 * timescale of the input files. 1161 * So the frame duration must be compatible with this time scale, 1162 * but without beeing too short. 1163 * For that, we must compute alpha (integer) so that: 1164 * (alpha x 1000)/EncoderTimeScale > MinFrameDuration 1165 **/ 1166 1167 uiAlpha = (M4OSA_UInt32)(( pC->dOutputFrameDuration 1168 * pC->ewc.uiVideoTimeScale) / 1000.0 + 0.5); 1169 1170 if( uiAlpha > 0 ) 1171 { 1172 pC->dOutputFrameDuration = 1173 ( uiAlpha * 1000.0) / pC->ewc.uiVideoTimeScale; 1174 } 1175 } 1176 else if( M4SYS_kH263 == pC->ewc.VideoStreamType ) 1177 { 1178 switch( pSettings->videoFrameRate ) 1179 { 1180 case M4VIDEOEDITING_k12_5_FPS: 1181 case M4VIDEOEDITING_k20_FPS: 1182 case M4VIDEOEDITING_k25_FPS: 1183 M4OSA_TRACE1_0( 1184 "M4VSS3GPP_editOpen(): invalid videoFrameRate for H263,\ 1185 returning M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE"); 1186 return M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE; 1187 default: 1188 break; 1189 } 1190 } 1191 } 1192 1193 /** 1194 * Create the MP3 output file */ 1195 if( M4VIDEOEDITING_kFileType_MP3 == outputFileType ) 1196 { 1197 M4READER_Buffer mp3tagBuffer; 1198 err = M4VSS3GPP_intCreateMP3OutputFile(pC, pSettings->pOutputFile); 1199 1200 if( M4NO_ERROR != err ) 1201 { 1202 M4OSA_TRACE1_1( 1203 "M4VSS3GPP_editOpen: M4VSS3GPP_intCreateMP3OutputFile returns 0x%x", 1204 err); 1205 return err; 1206 } 1207 1208 /* The ID3v2 tag could be at any place in the mp3 file */ 1209 /* The mp3 reader only checks few bytes in the beginning of 1210 stream to look for a ID3v2 tag */ 1211 /* It means that if the ID3v2 tag is not at the beginning of the file the reader do 1212 as there is no these metadata */ 1213 1214 /* Retrieve the data of the ID3v2 Tag */ 1215 err = pC->pC1->ShellAPI.m_pReader->m_pFctGetOption( 1216 pC->pC1->pReaderContext, M4READER_kOptionID_Mp3Id3v2Tag, 1217 (M4OSA_DataOption) &mp3tagBuffer); 1218 1219 if( M4NO_ERROR != err ) 1220 { 1221 M4OSA_TRACE1_1("M4VSS3GPP_editOpen: M4MP3R_getOption returns 0x%x", 1222 err); 1223 return err; 1224 } 1225 1226 /* Write the data of the ID3v2 Tag in the output file */ 1227 if( 0 != mp3tagBuffer.m_uiBufferSize ) 1228 { 1229 err = pC->pOsaFileWritPtr->writeData(pC->ewc.p3gpWriterContext, 1230 (M4OSA_MemAddr8)mp3tagBuffer.m_pData, mp3tagBuffer.m_uiBufferSize); 1231 1232 /** 1233 * Free before the error checking anyway */ 1234 free(mp3tagBuffer.m_pData); 1235 1236 /** 1237 * Error checking */ 1238 if( M4NO_ERROR != err ) 1239 { 1240 M4OSA_TRACE1_1( 1241 "M4VSS3GPP_editOpen: WriteData(ID3v2Tag) returns 0x%x", 1242 err); 1243 return err; 1244 } 1245 1246 mp3tagBuffer.m_uiBufferSize = 0; 1247 mp3tagBuffer.m_pData = M4OSA_NULL; 1248 } 1249 } 1250 /** 1251 * Create the 3GPP output file */ 1252 else if( M4VIDEOEDITING_kFileType_3GPP == outputFileType ) 1253 { 1254 pC->ewc.uiVideoBitrate = pSettings->xVSS.outputVideoBitrate; 1255 1256 /** 1257 * 11/12/2008 CR3283 MMS use case in VideoArtist: Set max output file size if needed */ 1258 if( pC->bIsMMS == M4OSA_TRUE ) 1259 { 1260 err = M4VSS3GPP_intCreate3GPPOutputFile(&pC->ewc, &pC->ShellAPI, 1261 pC->pOsaFileWritPtr, pSettings->pOutputFile, 1262 pC->pOsaFileReadPtr, pSettings->pTemporaryFile, 1263 pSettings->xVSS.outputFileSize); 1264 } 1265 else 1266 { 1267 err = M4VSS3GPP_intCreate3GPPOutputFile(&pC->ewc, &pC->ShellAPI, 1268 pC->pOsaFileWritPtr, pSettings->pOutputFile, 1269 pC->pOsaFileReadPtr, pSettings->pTemporaryFile, 0); 1270 } 1271 1272 if( M4NO_ERROR != err ) 1273 { 1274 M4OSA_TRACE1_1( 1275 "M4VSS3GPP_editOpen: M4VSS3GPP_intCreate3GPPOutputFile returns 0x%x", 1276 err); 1277 return err; 1278 } 1279 } 1280 /** 1281 * Default error case */ 1282 else 1283 { 1284 M4OSA_TRACE1_1( 1285 "M4VSS3GPP_editOpen: invalid outputFileType = 0x%x,\ 1286 returning M4VSS3GPP_ERR_OUTPUT_FILE_TYPE_ERROR", 1287 outputFileType); 1288 return 1289 M4VSS3GPP_ERR_OUTPUT_FILE_TYPE_ERROR; /**< this is an internal error code 1290 unknown to the user */ 1291 } 1292 1293 /** 1294 * Initialize state */ 1295 if( M4SYS_kMP3 == pC->ewc.AudioStreamType ) 1296 { 1297 /** 1298 * In the MP3 case we use a special audio state */ 1299 pC->State = M4VSS3GPP_kEditState_MP3_JUMP; 1300 } 1301 else 1302 { 1303 /** 1304 * We start with the video processing */ 1305 pC->State = M4VSS3GPP_kEditState_VIDEO; 1306 } 1307 1308 /** 1309 * Initialize state. 1310 * The first clip is independant to the "virtual previous clips", 1311 * so it's like if we where in Read/Write mode before it. */ 1312 pC->Vstate = M4VSS3GPP_kEditVideoState_READ_WRITE; 1313 pC->Astate = M4VSS3GPP_kEditAudioState_READ_WRITE; 1314 1315 /** 1316 * Return with no error */ 1317 M4OSA_TRACE3_0("M4VSS3GPP_editOpen(): returning M4NO_ERROR"); 1318 return M4NO_ERROR; 1319} 1320 1321/** 1322 ****************************************************************************** 1323 * M4OSA_ERR M4VSS3GPP_editStep() 1324 * @brief Perform one step of editing. 1325 * @note 1326 * @param pContext (IN) VSS 3GPP edit context 1327 * @param pProgress (OUT) Progress percentage (0 to 100) of the editing operation 1328 * @return M4NO_ERROR: No error 1329 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) 1330 * @return M4ERR_STATE: VSS 3GPP is not in an appropriate state for this 1331 * function to be called 1332 * @return M4VSS3GPP_WAR_EDITING_DONE: Edition is done, user should now call 1333 * M4VSS3GPP_editClose() 1334 ****************************************************************************** 1335 */ 1336M4OSA_ERR M4VSS3GPP_editStep( M4VSS3GPP_EditContext pContext, 1337 M4OSA_UInt8 *pProgress ) 1338{ 1339 M4VSS3GPP_InternalEditContext *pC = 1340 (M4VSS3GPP_InternalEditContext *)pContext; 1341 M4OSA_UInt32 uiProgressAudio, uiProgressVideo, uiProgress; 1342 M4OSA_ERR err; 1343 1344 M4OSA_TRACE3_1("M4VSS3GPP_editStep called with pContext=0x%x", pContext); 1345 1346 /** 1347 * Check input parameter */ 1348 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 1349 "M4VSS3GPP_editStep: pContext is M4OSA_NULL"); 1350 M4OSA_DEBUG_IF2((M4OSA_NULL == pProgress), M4ERR_PARAMETER, 1351 "M4VSS3GPP_editStep: pProgress is M4OSA_NULL"); 1352 1353 /** 1354 * Check state automaton and select correct processing */ 1355 switch( pC->State ) 1356 { 1357 case M4VSS3GPP_kEditState_VIDEO: 1358 err = M4VSS3GPP_intEditStepVideo(pC); 1359 break; 1360 1361 case M4VSS3GPP_kEditState_AUDIO: 1362 err = M4VSS3GPP_intEditStepAudio(pC); 1363 break; 1364 1365 case M4VSS3GPP_kEditState_MP3: 1366 err = M4VSS3GPP_intEditStepMP3(pC); 1367 break; 1368 1369 case M4VSS3GPP_kEditState_MP3_JUMP: 1370 err = M4VSS3GPP_intEditJumpMP3(pC); 1371 break; 1372 1373 default: 1374 M4OSA_TRACE1_0( 1375 "M4VSS3GPP_editStep(): invalid internal state (0x%x), returning M4ERR_STATE"); 1376 return M4ERR_STATE; 1377 } 1378 1379 /** 1380 * Compute progress. 1381 * We do the computing with 32bits precision because in some (very) extreme case, we may get 1382 * values higher than 256 (...) */ 1383 uiProgressAudio = 1384 ( (M4OSA_UInt32)(pC->ewc.dATo * 100)) / pC->ewc.iOutputDuration; 1385 // Decorrelate input and output encoding timestamp to handle encoder prefetch 1386 uiProgressVideo = ((M4OSA_UInt32)(pC->ewc.dInputVidCts * 100)) / pC->ewc.iOutputDuration; 1387 1388 uiProgress = uiProgressAudio + uiProgressVideo; 1389 1390 if( ( pC->ewc.AudioStreamType != M4SYS_kAudioUnknown) 1391 && (pC->ewc.VideoStreamType != M4SYS_kVideoUnknown) ) 1392 uiProgress /= 2; 1393 1394 /** 1395 * Sanity check */ 1396 if( uiProgress > 100 ) 1397 { 1398 *pProgress = 100; 1399 } 1400 else 1401 { 1402 *pProgress = (M4OSA_UInt8)uiProgress; 1403 } 1404 1405 /** 1406 * Return the error */ 1407 M4OSA_TRACE3_1("M4VSS3GPP_editStep(): returning 0x%x", err); 1408 return err; 1409} 1410 1411/** 1412 ****************************************************************************** 1413 * M4OSA_ERR M4VSS3GPP_editClose() 1414 * @brief Finish the VSS edit operation. 1415 * @note The output 3GPP file is ready to be played after this call 1416 * @param pContext (IN) VSS edit context 1417 * @return M4NO_ERROR: No error 1418 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) 1419 * @return M4ERR_STATE: VSS is not in an appropriate state for this function to be called 1420 ****************************************************************************** 1421 */ 1422M4OSA_ERR M4VSS3GPP_editClose( M4VSS3GPP_EditContext pContext ) 1423{ 1424 M4VSS3GPP_InternalEditContext *pC = 1425 (M4VSS3GPP_InternalEditContext *)pContext; 1426 M4OSA_ERR err; 1427 M4OSA_ERR returnedError = M4NO_ERROR; 1428 M4OSA_UInt32 lastCTS; 1429 1430 M4OSA_TRACE3_1("M4VSS3GPP_editClose called with pContext=0x%x", pContext); 1431 1432 /** 1433 * Check input parameter */ 1434 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 1435 "M4VSS3GPP_editClose: pContext is M4OSA_NULL"); 1436 1437 /** 1438 * Check state automaton. 1439 * In "theory", we should not authorize closing if we are in CREATED state. 1440 * But in practice, in case the opening failed, it may have been partially done. 1441 * In that case we have to free some opened ressources by calling Close. */ 1442 if( M4VSS3GPP_kEditState_CLOSED == pC->State ) 1443 { 1444 M4OSA_TRACE1_1( 1445 "M4VSS3GPP_editClose: Wrong state (0x%x), returning M4ERR_STATE", 1446 pC->State); 1447 return M4ERR_STATE; 1448 } 1449 1450 /** 1451 * There may be an encoder to destroy */ 1452 err = M4VSS3GPP_intDestroyVideoEncoder(pC); 1453 1454 if( M4NO_ERROR != err ) 1455 { 1456 M4OSA_TRACE1_1( 1457 "M4VSS3GPP_editClose: M4VSS3GPP_editDestroyVideoEncoder() returns 0x%x!", 1458 err); 1459 /**< We do not return the error here because we still have stuff to free */ 1460 returnedError = err; 1461 } 1462 1463 /** 1464 * Close the output file */ 1465 if( M4SYS_kMP3 == pC->ewc.AudioStreamType ) 1466 { 1467 /** 1468 * MP3 case */ 1469 if( M4OSA_NULL != pC->ewc.p3gpWriterContext ) 1470 { 1471 err = pC->pOsaFileWritPtr->closeWrite(pC->ewc.p3gpWriterContext); 1472 pC->ewc.p3gpWriterContext = M4OSA_NULL; 1473 } 1474 } 1475 else 1476 { 1477 /** 1478 * Close the output 3GPP clip, if it has been opened */ 1479 if( M4OSA_NULL != pC->ewc.p3gpWriterContext ) 1480 { 1481 /* Update last Video CTS */ 1482 lastCTS = pC->ewc.iOutputDuration; 1483 1484 err = pC->ShellAPI.pWriterGlobalFcts->pFctSetOption( 1485 pC->ewc.p3gpWriterContext, 1486 (M4OSA_UInt32)M4WRITER_kMaxFileDuration, &lastCTS); 1487 1488 if( M4NO_ERROR != err ) 1489 { 1490 M4OSA_TRACE1_1( 1491 "M4VSS3GPP_editClose: SetOption(M4WRITER_kMaxFileDuration) returns 0x%x", 1492 err); 1493 } 1494 1495 err = pC->ShellAPI.pWriterGlobalFcts->pFctCloseWrite( 1496 pC->ewc.p3gpWriterContext); 1497 1498 if( M4NO_ERROR != err ) 1499 { 1500 M4OSA_TRACE1_1( 1501 "M4VSS3GPP_editClose: pFctCloseWrite(OUT) returns 0x%x!", 1502 err); 1503 /**< We do not return the error here because we still have stuff to free */ 1504 if( M4NO_ERROR 1505 == returnedError ) /**< we return the first error that happened */ 1506 { 1507 returnedError = err; 1508 } 1509 } 1510 pC->ewc.p3gpWriterContext = M4OSA_NULL; 1511 } 1512 } 1513 1514 /** 1515 * Free the output video DSI, if it has been created */ 1516 if( M4OSA_NULL != pC->ewc.pVideoOutputDsi ) 1517 { 1518 free(pC->ewc.pVideoOutputDsi); 1519 pC->ewc.pVideoOutputDsi = M4OSA_NULL; 1520 } 1521 1522 /** 1523 * Free the output audio DSI, if it has been created */ 1524 if( M4OSA_NULL != pC->ewc.pAudioOutputDsi ) 1525 { 1526 free(pC->ewc.pAudioOutputDsi); 1527 pC->ewc.pAudioOutputDsi = M4OSA_NULL; 1528 } 1529 1530 /** 1531 * Close clip1, if needed */ 1532 if( M4OSA_NULL != pC->pC1 ) 1533 { 1534 err = M4VSS3GPP_intClipCleanUp(pC->pC1); 1535 1536 if( M4NO_ERROR != err ) 1537 { 1538 M4OSA_TRACE1_1( 1539 "M4VSS3GPP_editClose: M4VSS3GPP_intClipCleanUp(C1) returns 0x%x!", 1540 err); 1541 /**< We do not return the error here because we still have stuff to free */ 1542 if( M4NO_ERROR 1543 == returnedError ) /**< we return the first error that happened */ 1544 { 1545 returnedError = err; 1546 } 1547 } 1548 pC->pC1 = M4OSA_NULL; 1549 } 1550 1551 /** 1552 * Close clip2, if needed */ 1553 if( M4OSA_NULL != pC->pC2 ) 1554 { 1555 err = M4VSS3GPP_intClipCleanUp(pC->pC2); 1556 1557 if( M4NO_ERROR != err ) 1558 { 1559 M4OSA_TRACE1_1( 1560 "M4VSS3GPP_editClose: M4VSS3GPP_intClipCleanUp(C2) returns 0x%x!", 1561 err); 1562 /**< We do not return the error here because we still have stuff to free */ 1563 if( M4NO_ERROR 1564 == returnedError ) /**< we return the first error that happened */ 1565 { 1566 returnedError = err; 1567 } 1568 } 1569 pC->pC2 = M4OSA_NULL; 1570 } 1571 1572 /** 1573 * Free the temporary YUV planes */ 1574 if( M4OSA_NULL != pC->yuv1[0].pac_data ) 1575 { 1576 free(pC->yuv1[0].pac_data); 1577 pC->yuv1[0].pac_data = M4OSA_NULL; 1578 } 1579 1580 if( M4OSA_NULL != pC->yuv1[1].pac_data ) 1581 { 1582 free(pC->yuv1[1].pac_data); 1583 pC->yuv1[1].pac_data = M4OSA_NULL; 1584 } 1585 1586 if( M4OSA_NULL != pC->yuv1[2].pac_data ) 1587 { 1588 free(pC->yuv1[2].pac_data); 1589 pC->yuv1[2].pac_data = M4OSA_NULL; 1590 } 1591 1592 if( M4OSA_NULL != pC->yuv2[0].pac_data ) 1593 { 1594 free(pC->yuv2[0].pac_data); 1595 pC->yuv2[0].pac_data = M4OSA_NULL; 1596 } 1597 1598 if( M4OSA_NULL != pC->yuv2[1].pac_data ) 1599 { 1600 free(pC->yuv2[1].pac_data); 1601 pC->yuv2[1].pac_data = M4OSA_NULL; 1602 } 1603 1604 if( M4OSA_NULL != pC->yuv2[2].pac_data ) 1605 { 1606 free(pC->yuv2[2].pac_data); 1607 pC->yuv2[2].pac_data = M4OSA_NULL; 1608 } 1609 1610 /* RC */ 1611 if( M4OSA_NULL != pC->yuv3[0].pac_data ) 1612 { 1613 free(pC->yuv3[0].pac_data); 1614 pC->yuv3[0].pac_data = M4OSA_NULL; 1615 } 1616 1617 if( M4OSA_NULL != pC->yuv3[1].pac_data ) 1618 { 1619 free(pC->yuv3[1].pac_data); 1620 pC->yuv3[1].pac_data = M4OSA_NULL; 1621 } 1622 1623 if( M4OSA_NULL != pC->yuv3[2].pac_data ) 1624 { 1625 free(pC->yuv3[2].pac_data); 1626 pC->yuv3[2].pac_data = M4OSA_NULL; 1627 } 1628 1629 /* RC */ 1630 if( M4OSA_NULL != pC->yuv4[0].pac_data ) 1631 { 1632 free(pC->yuv4[0].pac_data); 1633 pC->yuv4[0].pac_data = M4OSA_NULL; 1634 } 1635 1636 if( M4OSA_NULL != pC->yuv4[1].pac_data ) 1637 { 1638 free(pC->yuv4[1].pac_data); 1639 pC->yuv4[1].pac_data = M4OSA_NULL; 1640 } 1641 1642 if( M4OSA_NULL != pC->yuv4[2].pac_data ) 1643 { 1644 free(pC->yuv4[2].pac_data); 1645 pC->yuv4[2].pac_data = M4OSA_NULL; 1646 } 1647 1648 /** 1649 * RC Free effects list */ 1650 if( pC->pEffectsList != M4OSA_NULL ) 1651 { 1652 free(pC->pEffectsList); 1653 pC->pEffectsList = M4OSA_NULL; 1654 } 1655 1656 /** 1657 * RC Free active effects list */ 1658 if( pC->pActiveEffectsList != M4OSA_NULL ) 1659 { 1660 free(pC->pActiveEffectsList); 1661 pC->pActiveEffectsList = M4OSA_NULL; 1662 } 1663 /** 1664 * Free active effects list */ 1665 if(pC->pActiveEffectsList1 != M4OSA_NULL) 1666 { 1667 free(pC->pActiveEffectsList1); 1668 pC->pActiveEffectsList1 = M4OSA_NULL; 1669 } 1670 if(pC->m_air_context != M4OSA_NULL) { 1671 free(pC->m_air_context); 1672 pC->m_air_context = M4OSA_NULL; 1673 } 1674 /** 1675 * Update state automaton */ 1676 pC->State = M4VSS3GPP_kEditState_CLOSED; 1677 1678 /** 1679 * Return with no error */ 1680 M4OSA_TRACE3_1("M4VSS3GPP_editClose(): returning 0x%x", returnedError); 1681 return returnedError; 1682} 1683 1684/** 1685 ****************************************************************************** 1686 * M4OSA_ERR M4VSS3GPP_editCleanUp() 1687 * @brief Free all resources used by the VSS edit operation. 1688 * @note The context is no more valid after this call 1689 * @param pContext (IN) VSS edit context 1690 * @return M4NO_ERROR: No error 1691 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) 1692 ****************************************************************************** 1693 */ 1694M4OSA_ERR M4VSS3GPP_editCleanUp( M4VSS3GPP_EditContext pContext ) 1695{ 1696 M4OSA_ERR err; 1697 M4VSS3GPP_InternalEditContext *pC = 1698 (M4VSS3GPP_InternalEditContext *)pContext; 1699 1700 M4OSA_TRACE3_1("M4VSS3GPP_editCleanUp called with pContext=0x%x", pContext); 1701 1702 /** 1703 * Check input parameter */ 1704 if( M4OSA_NULL == pContext ) 1705 { 1706 M4OSA_TRACE1_0( 1707 "M4VSS3GPP_editCleanUp(): pContext is M4OSA_NULL, returning M4ERR_PARAMETER"); 1708 return M4ERR_PARAMETER; 1709 } 1710 1711 /** 1712 * Close, if needed. 1713 * In "theory", we should not close if we are in CREATED state. 1714 * But in practice, in case the opening failed, it may have been partially done. 1715 * In that case we have to free some opened ressources by calling Close. */ 1716 if( M4VSS3GPP_kEditState_CLOSED != pC->State ) 1717 { 1718 M4OSA_TRACE3_0("M4VSS3GPP_editCleanUp(): calling M4VSS3GPP_editClose"); 1719 err = M4VSS3GPP_editClose(pC); 1720 1721 if( M4NO_ERROR != err ) 1722 { 1723 M4OSA_TRACE1_1( 1724 "M4VSS3GPP_editCleanUp(): M4VSS3GPP_editClose returns 0x%x", 1725 err); 1726 } 1727 } 1728 1729 /** 1730 * Free the video encoder dummy AU */ 1731 if( M4OSA_NULL != pC->ewc.pDummyAuBuffer ) 1732 { 1733 free(pC->ewc.pDummyAuBuffer); 1734 pC->ewc.pDummyAuBuffer = M4OSA_NULL; 1735 } 1736 1737 /** 1738 * Free the Audio encoder context */ 1739 if( M4OSA_NULL != pC->ewc.pAudioEncCtxt ) 1740 { 1741 err = pC->ShellAPI.pAudioEncoderGlobalFcts->pFctClose( 1742 pC->ewc.pAudioEncCtxt); 1743 1744 if( M4NO_ERROR != err ) 1745 { 1746 M4OSA_TRACE1_1( 1747 "M4VSS3GPP_editCleanUp: pAudioEncoderGlobalFcts->pFctClose returns 0x%x", 1748 err); 1749 /**< don't return, we still have stuff to free */ 1750 } 1751 1752 err = pC->ShellAPI.pAudioEncoderGlobalFcts->pFctCleanUp( 1753 pC->ewc.pAudioEncCtxt); 1754 1755 if( M4NO_ERROR != err ) 1756 { 1757 M4OSA_TRACE1_1( 1758 "M4VSS3GPP_editCleanUp: pAudioEncoderGlobalFcts->pFctCleanUp returns 0x%x", 1759 err); 1760 /**< don't return, we still have stuff to free */ 1761 } 1762 1763 pC->ewc.pAudioEncCtxt = M4OSA_NULL; 1764 } 1765 1766 /** 1767 * Free the shells interfaces */ 1768 M4VSS3GPP_unRegisterAllWriters(&pC->ShellAPI); 1769 M4VSS3GPP_unRegisterAllEncoders(&pC->ShellAPI); 1770 M4VSS3GPP_unRegisterAllReaders(&pC->ShellAPI); 1771 M4VSS3GPP_unRegisterAllDecoders(&pC->ShellAPI); 1772 1773 /** 1774 * Free the settings copied in the internal context */ 1775 M4VSS3GPP_intFreeSettingsList(pC); 1776 1777 /** 1778 * Finally, Free context */ 1779 free(pC); 1780 pC = M4OSA_NULL; 1781 1782 /** 1783 * Return with no error */ 1784 M4OSA_TRACE3_0("M4VSS3GPP_editCleanUp(): returning M4NO_ERROR"); 1785 return M4NO_ERROR; 1786} 1787 1788#ifdef WIN32 1789/** 1790 ****************************************************************************** 1791 * M4OSA_ERR M4VSS3GPP_GetErrorMessage() 1792 * @brief Return a string describing the given error code 1793 * @note The input string must be already allocated (and long enough!) 1794 * @param err (IN) Error code to get the description from 1795 * @param sMessage (IN/OUT) Allocated string in which the description will be copied 1796 * @return M4NO_ERROR: Input error is from the VSS3GPP module 1797 * @return M4ERR_PARAMETER:Input error is not from the VSS3GPP module 1798 ****************************************************************************** 1799 */ 1800 1801M4OSA_ERR M4VSS3GPP_GetErrorMessage( M4OSA_ERR err, M4OSA_Char *sMessage ) 1802{ 1803 switch( err ) 1804 { 1805 case M4VSS3GPP_WAR_EDITING_DONE: 1806 strcpy(sMessage, "M4VSS3GPP_WAR_EDITING_DONE"); 1807 break; 1808 1809 case M4VSS3GPP_WAR_END_OF_AUDIO_MIXING: 1810 strcpy(sMessage, "M4VSS3GPP_WAR_END_OF_AUDIO_MIXING"); 1811 break; 1812 1813 case M4VSS3GPP_WAR_END_OF_EXTRACT_PICTURE: 1814 strcpy(sMessage, "M4VSS3GPP_WAR_END_OF_EXTRACT_PICTURE"); 1815 break; 1816 1817 case M4VSS3GPP_ERR_INVALID_FILE_TYPE: 1818 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_FILE_TYPE"); 1819 break; 1820 1821 case M4VSS3GPP_ERR_INVALID_EFFECT_KIND: 1822 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_EFFECT_KIND"); 1823 break; 1824 1825 case M4VSS3GPP_ERR_INVALID_VIDEO_EFFECT_TYPE: 1826 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_VIDEO_EFFECT_TYPE"); 1827 break; 1828 1829 case M4VSS3GPP_ERR_INVALID_AUDIO_EFFECT_TYPE: 1830 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_AUDIO_EFFECT_TYPE"); 1831 break; 1832 1833 case M4VSS3GPP_ERR_INVALID_VIDEO_TRANSITION_TYPE: 1834 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_VIDEO_TRANSITION_TYPE"); 1835 break; 1836 1837 case M4VSS3GPP_ERR_INVALID_AUDIO_TRANSITION_TYPE: 1838 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_AUDIO_TRANSITION_TYPE"); 1839 break; 1840 1841 case M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE: 1842 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE"); 1843 break; 1844 1845 case M4VSS3GPP_ERR_EXTERNAL_EFFECT_NULL: 1846 strcpy(sMessage, "M4VSS3GPP_ERR_EXTERNAL_EFFECT_NULL"); 1847 break; 1848 1849 case M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL: 1850 strcpy(sMessage, "M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL"); 1851 break; 1852 1853 case M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION: 1854 strcpy(sMessage, "M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION"); 1855 break; 1856 1857 case M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT: 1858 strcpy(sMessage, "M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT"); 1859 break; 1860 1861 case M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS: 1862 strcpy(sMessage, "M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS"); 1863 break; 1864 1865 case M4VSS3GPP_ERR_INVALID_3GPP_FILE: 1866 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_3GPP_FILE"); 1867 break; 1868 1869 case M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT: 1870 strcpy(sMessage, "M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT"); 1871 break; 1872 1873 case M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT: 1874 strcpy(sMessage, "M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT"); 1875 break; 1876 1877 case M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED: 1878 strcpy(sMessage, "M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED"); 1879 break; 1880 1881 case M4VSS3GPP_ERR_INPUT_VIDEO_AU_TOO_LARGE: 1882 strcpy(sMessage, "M4VSS3GPP_ERR_INPUT_VIDEO_AU_TOO_LARGE"); 1883 break; 1884 1885 case M4VSS3GPP_ERR_INPUT_AUDIO_AU_TOO_LARGE: 1886 strcpy(sMessage, "M4VSS3GPP_ERR_INPUT_AUDIO_AU_TOO_LARGE"); 1887 break; 1888 1889 case M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU: 1890 strcpy(sMessage, "M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU"); 1891 break; 1892 1893 case M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR: 1894 strcpy(sMessage, "M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR"); 1895 break; 1896 1897 case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT: 1898 strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT"); 1899 break; 1900 1901 case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE: 1902 strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE"); 1903 break; 1904 1905 case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE: 1906 strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE"); 1907 break; 1908 1909 case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC: 1910 strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC"); 1911 break; 1912 1913 case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT: 1914 strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT"); 1915 break; 1916 1917 case M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE: 1918 strcpy(sMessage, 1919 "M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE"); 1920 break; 1921 1922 case M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE: 1923 strcpy(sMessage, 1924 "M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE"); 1925 break; 1926 1927 case M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION: 1928 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION"); 1929 break; 1930 1931 case M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT: 1932 strcpy(sMessage, "M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT"); 1933 break; 1934 1935 case M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE: 1936 strcpy(sMessage, "M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE"); 1937 break; 1938 1939 case M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE: 1940 strcpy(sMessage, "M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE"); 1941 break; 1942 1943 case M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING: 1944 strcpy(sMessage, 1945 "M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING"); 1946 break; 1947 1948 case M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY: 1949 strcpy(sMessage, "M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY"); 1950 break; 1951 1952 case M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_STREAM_TYPE: 1953 strcpy(sMessage, "M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_STREAM_TYPE"); 1954 break; 1955 1956 case M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS: 1957 strcpy(sMessage, "M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS"); 1958 break; 1959 1960 case M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY: 1961 strcpy(sMessage, 1962 "M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY"); 1963 break; 1964 1965 case M4VSS3GPP_ERR_NO_SUPPORTED_STREAM_IN_FILE: 1966 strcpy(sMessage, "M4VSS3GPP_ERR_NO_SUPPORTED_STREAM_IN_FILE"); 1967 break; 1968 1969 case M4VSS3GPP_ERR_ADDVOLUME_EQUALS_ZERO: 1970 strcpy(sMessage, "M4VSS3GPP_ERR_ADDVOLUME_EQUALS_ZERO"); 1971 break; 1972 1973 case M4VSS3GPP_ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION: 1974 strcpy(sMessage, "M4VSS3GPP_ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION"); 1975 break; 1976 1977 case M4VSS3GPP_ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT: 1978 strcpy(sMessage, "M4VSS3GPP_ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT"); 1979 break; 1980 1981 case M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM: 1982 strcpy(sMessage, "M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM"); 1983 break; 1984 1985 case M4VSS3GPP_ERR_AUDIO_MIXING_UNSUPPORTED: 1986 strcpy(sMessage, "M4VSS3GPP_ERR_AUDIO_MIXING_UNSUPPORTED"); 1987 break; 1988 1989 case M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK: 1990 strcpy(sMessage, 1991 "M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK"); 1992 break; 1993 1994 case M4VSS3GPP_ERR_AUDIO_CANNOT_BE_MIXED: 1995 strcpy(sMessage, "M4VSS3GPP_ERR_AUDIO_CANNOT_BE_MIXED"); 1996 break; 1997 1998 case M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP: 1999 strcpy(sMessage, "M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP"); 2000 break; 2001 2002 case M4VSS3GPP_ERR_BEGINLOOP_HIGHER_ENDLOOP: 2003 strcpy(sMessage, "M4VSS3GPP_ERR_BEGINLOOP_HIGHER_ENDLOOP"); 2004 break; 2005 2006 case M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED: 2007 strcpy(sMessage, "M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED"); 2008 break; 2009 2010 case M4VSS3GPP_ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE: 2011 strcpy(sMessage, "M4VSS3GPP_ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE"); 2012 break; 2013 2014 default: /**< Not a VSS3GPP error */ 2015 strcpy(sMessage, ""); 2016 return M4ERR_PARAMETER; 2017 } 2018 return M4NO_ERROR; 2019} 2020 2021#endif /* WIN32 */ 2022 2023/********************************************************/ 2024/********************************************************/ 2025/********************************************************/ 2026/**************** STATIC FUNCTIONS ******************/ 2027/********************************************************/ 2028/********************************************************/ 2029/********************************************************/ 2030 2031/** 2032 ****************************************************************************** 2033 * M4OSA_ERR M4VSS3GPP_intClipSettingsSanityCheck() 2034 * @brief Simplify the given clip settings 2035 * @note This function may modify the given structure 2036 * @param pClip (IN/OUT) Clip settings 2037 * @return M4NO_ERROR: No error 2038 * @return M4VSS3GPP_ERR_EXTERNAL_EFFECT_NULL: 2039 ****************************************************************************** 2040 */ 2041 2042static M4OSA_ERR M4VSS3GPP_intClipSettingsSanityCheck( 2043 M4VSS3GPP_ClipSettings *pClip ) 2044{ 2045 M4OSA_UInt8 uiFx; 2046 M4OSA_UInt32 2047 uiClipActualDuration; /**< the clip duration once the cuts are done */ 2048 M4OSA_UInt32 uiDuration; 2049 M4VSS3GPP_EffectSettings *pFx; 2050 2051 /** 2052 * If begin cut is too far, return an error */ 2053 uiDuration = pClip->ClipProperties.uiClipDuration; 2054 2055 if( pClip->uiBeginCutTime > uiDuration ) 2056 { 2057 M4OSA_TRACE1_2( 2058 "M4VSS3GPP_intClipSettingsSanityCheck: %d > %d,\ 2059 returning M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION", 2060 pClip->uiBeginCutTime, uiDuration); 2061 return M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION; 2062 } 2063 2064 /** 2065 * If end cut is too far, set to zero (it means no end cut) */ 2066 if( pClip->uiEndCutTime > uiDuration ) 2067 { 2068 pClip->uiEndCutTime = 0; 2069 } 2070 2071 /** 2072 * Compute actual clip duration (once cuts are done) */ 2073 if( 0 == pClip->uiEndCutTime ) 2074 { 2075 /** 2076 * No end cut */ 2077 uiClipActualDuration = uiDuration - pClip->uiBeginCutTime; 2078 } 2079 else 2080 { 2081 if( pClip->uiBeginCutTime >= pClip->uiEndCutTime ) 2082 { 2083 M4OSA_TRACE1_2( 2084 "M4VSS3GPP_intClipSettingsSanityCheck: %d > %d,\ 2085 returning M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT", 2086 pClip->uiBeginCutTime, pClip->uiEndCutTime); 2087 return M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT; 2088 } 2089 uiClipActualDuration = pClip->uiEndCutTime - pClip->uiBeginCutTime; 2090 } 2091 2092 return M4NO_ERROR; 2093} 2094 2095/** 2096 ****************************************************************************** 2097 * M4OSA_ERR M4VSS3GPP_intTransitionSettingsSanityCheck() 2098 * @brief Simplify the given transition settings 2099 * @note This function may modify the given structure 2100 * @param pTransition (IN/OUT) Transition settings 2101 * @return M4NO_ERROR: No error 2102 * @return M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL: 2103 ****************************************************************************** 2104 */ 2105static M4OSA_ERR M4VSS3GPP_intTransitionSettingsSanityCheck( 2106 M4VSS3GPP_TransitionSettings *pTransition ) 2107{ 2108 /** 2109 * No transition */ 2110 if( 0 == pTransition->uiTransitionDuration ) 2111 { 2112 pTransition->VideoTransitionType = M4VSS3GPP_kVideoTransitionType_None; 2113 pTransition->AudioTransitionType = M4VSS3GPP_kAudioTransitionType_None; 2114 } 2115 else if( ( M4VSS3GPP_kVideoTransitionType_None 2116 == pTransition->VideoTransitionType) 2117 && (M4VSS3GPP_kAudioTransitionType_None 2118 == pTransition->AudioTransitionType) ) 2119 { 2120 pTransition->uiTransitionDuration = 0; 2121 } 2122 2123 /** 2124 * Check external transition function is set */ 2125 if( ( pTransition->VideoTransitionType 2126 >= M4VSS3GPP_kVideoTransitionType_External) 2127 && (M4OSA_NULL == pTransition->ExtVideoTransitionFct) ) 2128 { 2129 return M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL; 2130 } 2131 2132 /** 2133 * Set minimal transition duration */ 2134 if( ( pTransition->uiTransitionDuration > 0) 2135 && (pTransition->uiTransitionDuration 2136 < M4VSS3GPP_MINIMAL_TRANSITION_DURATION) ) 2137 { 2138 pTransition->uiTransitionDuration = 2139 M4VSS3GPP_MINIMAL_TRANSITION_DURATION; 2140 } 2141 return M4NO_ERROR; 2142} 2143 2144/** 2145 ****************************************************************************** 2146 * M4OSA_ERR M4VSS3GPP_intFreeSettingsList() 2147 * @brief Free the settings copied in the internal context 2148 * @param pC (IN/OUT) Internal edit context 2149 ****************************************************************************** 2150 */ 2151static M4OSA_Void M4VSS3GPP_intFreeSettingsList( 2152 M4VSS3GPP_InternalEditContext *pC ) 2153{ 2154 M4OSA_UInt32 i; 2155 2156 /** 2157 * Free the settings list */ 2158 if( M4OSA_NULL != pC->pClipList ) 2159 { 2160 for ( i = 0; i < pC->uiClipNumber; i++ ) 2161 { 2162 M4VSS3GPP_editFreeClipSettings(&(pC->pClipList[i])); 2163 } 2164 2165 free(pC->pClipList); 2166 pC->pClipList = M4OSA_NULL; 2167 } 2168 2169 /** 2170 * Free the transition list */ 2171 if( M4OSA_NULL != pC->pTransitionList ) 2172 { 2173 free(pC->pTransitionList); 2174 pC->pTransitionList = M4OSA_NULL; 2175 } 2176} 2177/** 2178 ****************************************************************************** 2179 * M4OSA_ERR M4VSS3GPP_intCreateMP3OutputFile() 2180 * @brief Creates and prepare the output MP file 2181 * @param pC (IN/OUT) Internal edit context 2182 ****************************************************************************** 2183 */ 2184static M4OSA_ERR 2185M4VSS3GPP_intCreateMP3OutputFile( M4VSS3GPP_InternalEditContext *pC, 2186 M4OSA_Void *pOutputFile ) 2187{ 2188 M4OSA_ERR err; 2189 2190 err = 2191 pC->pOsaFileWritPtr->openWrite(&pC->ewc.p3gpWriterContext, pOutputFile, 2192 M4OSA_kFileWrite); 2193 2194 if( M4NO_ERROR != err ) 2195 { 2196 M4OSA_TRACE1_1( 2197 "M4VSS3GPP_intCreateMP3OutputFile: WriteOpen returns 0x%x!", err); 2198 return err; 2199 } 2200 2201 return M4NO_ERROR; 2202} 2203/** 2204 ****************************************************************************** 2205 * M4OSA_ERR M4VSS3GPP_intCreate3GPPOutputFile() 2206 * @brief Creates and prepare the output MP3 file 2207 * @note Creates the writer, Creates the output file, Adds the streams, 2208 Readies the writing process 2209 * @param pC (IN/OUT) Internal edit context 2210 ****************************************************************************** 2211 */ 2212M4OSA_ERR 2213M4VSS3GPP_intCreate3GPPOutputFile( M4VSS3GPP_EncodeWriteContext *pC_ewc, 2214 M4VSS3GPP_MediaAndCodecCtxt *pC_ShellAPI, 2215 M4OSA_FileWriterPointer *pOsaFileWritPtr, 2216 M4OSA_Void *pOutputFile, 2217 M4OSA_FileReadPointer *pOsaFileReadPtr, 2218 M4OSA_Void *pTempFile, 2219 M4OSA_UInt32 maxOutputFileSize ) 2220{ 2221 M4OSA_ERR err; 2222 M4OSA_UInt32 uiVersion; 2223 M4SYS_StreamIDValue temp; 2224 2225 M4OSA_TRACE3_2( 2226 "M4VSS3GPP_intCreate3GPPOutputFile called with pC_ewc=0x%x, pOutputFile=0x%x", 2227 pC_ewc, pOutputFile); 2228 2229 /** 2230 * Check input parameter */ 2231 M4OSA_DEBUG_IF2((M4OSA_NULL == pC_ewc), M4ERR_PARAMETER, 2232 "M4VSS3GPP_intCreate3GPPOutputFile: pC_ewc is M4OSA_NULL"); 2233 M4OSA_DEBUG_IF2((M4OSA_NULL == pOutputFile), M4ERR_PARAMETER, 2234 "M4VSS3GPP_intCreate3GPPOutputFile: pOutputFile is M4OSA_NULL"); 2235 2236 /* Set writer */ 2237 err = 2238 M4VSS3GPP_setCurrentWriter(pC_ShellAPI, M4VIDEOEDITING_kFileType_3GPP); 2239 M4ERR_CHECK_RETURN(err); 2240 2241 /** 2242 * Create the output file */ 2243 err = pC_ShellAPI->pWriterGlobalFcts->pFctOpen(&pC_ewc->p3gpWriterContext, 2244 pOutputFile, pOsaFileWritPtr, pTempFile, pOsaFileReadPtr); 2245 2246 if( M4NO_ERROR != err ) 2247 { 2248 M4OSA_TRACE1_1( 2249 "M4VSS3GPP_intCreate3GPPOutputFile: pWriterGlobalFcts->pFctOpen returns 0x%x!", 2250 err); 2251 return err; 2252 } 2253 2254 /** 2255 * Set the signature option of the writer */ 2256 err = 2257 pC_ShellAPI->pWriterGlobalFcts->pFctSetOption(pC_ewc->p3gpWriterContext, 2258 M4WRITER_kEmbeddedString, (M4OSA_DataOption)"NXP-SW : VSS "); 2259 2260 if( ( M4NO_ERROR != err) && (((M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 2261 != err) ) /* this option may not be implemented by some writers */ 2262 { 2263 M4OSA_TRACE1_1( 2264 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2265 pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedString) returns 0x%x!", 2266 err); 2267 return err; 2268 } 2269 2270 /*11/12/2008 CR3283 MMS use case for VideoArtist: 2271 Set the max output file size option in the writer so that the output file will be 2272 smaller than the given file size limitation*/ 2273 if( maxOutputFileSize > 0 ) 2274 { 2275 err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( 2276 pC_ewc->p3gpWriterContext, 2277 M4WRITER_kMaxFileSize, &maxOutputFileSize); 2278 2279 if( M4NO_ERROR != err ) 2280 { 2281 M4OSA_TRACE1_1( 2282 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2283 writer set option M4WRITER_kMaxFileSize returns 0x%x", 2284 err); 2285 return err; 2286 } 2287 } 2288 2289 /** 2290 * Set the version option of the writer */ 2291 uiVersion = 2292 (M4VIDEOEDITING_VERSION_MAJOR * 100 + M4VIDEOEDITING_VERSION_MINOR * 10 2293 + M4VIDEOEDITING_VERSION_REVISION); 2294 err = 2295 pC_ShellAPI->pWriterGlobalFcts->pFctSetOption(pC_ewc->p3gpWriterContext, 2296 M4WRITER_kEmbeddedVersion, (M4OSA_DataOption) &uiVersion); 2297 2298 if( ( M4NO_ERROR != err) && (((M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 2299 != err) ) /* this option may not be implemented by some writers */ 2300 { 2301 M4OSA_TRACE1_1( 2302 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2303 pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedVersion) returns 0x%x!", 2304 err); 2305 return err; 2306 } 2307 2308 if( M4SYS_kVideoUnknown != pC_ewc->VideoStreamType ) 2309 { 2310 /** 2311 * Set the video stream properties */ 2312 pC_ewc->WriterVideoStreamInfo.height = pC_ewc->uiVideoHeight; 2313 pC_ewc->WriterVideoStreamInfo.width = pC_ewc->uiVideoWidth; 2314 pC_ewc->WriterVideoStreamInfo.fps = 2315 0.0; /**< Not used by the shell/core writer */ 2316 pC_ewc->WriterVideoStreamInfo.Header.pBuf = 2317 pC_ewc->pVideoOutputDsi; /**< Previously computed output DSI */ 2318 pC_ewc->WriterVideoStreamInfo.Header.Size = pC_ewc-> 2319 uiVideoOutputDsiSize; /**< Previously computed output DSI size */ 2320 2321 pC_ewc->WriterVideoStream.streamType = pC_ewc->VideoStreamType; 2322 2323 switch( pC_ewc->VideoStreamType ) 2324 { 2325 case M4SYS_kMPEG_4: 2326 case M4SYS_kH263: 2327 case M4SYS_kH264: 2328 /**< We HAVE to put a value here... */ 2329 pC_ewc->WriterVideoStream.averageBitrate = 2330 pC_ewc->uiVideoBitrate; 2331 pC_ewc->WriterVideoStream.maxBitrate = pC_ewc->uiVideoBitrate; 2332 break; 2333 2334 default: 2335 M4OSA_TRACE1_1( 2336 "M4VSS3GPP_intCreate3GPPOutputFile: unknown input video format (0x%x),\ 2337 returning M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT!", 2338 pC_ewc->VideoStreamType); 2339 return M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT; 2340 } 2341 2342 pC_ewc->WriterVideoStream.streamID = M4VSS3GPP_WRITER_VIDEO_STREAM_ID; 2343 pC_ewc->WriterVideoStream.timeScale = 2344 0; /**< Not used by the shell/core writer */ 2345 pC_ewc->WriterVideoStream.profileLevel = 2346 0; /**< Not used by the shell/core writer */ 2347 pC_ewc->WriterVideoStream.duration = 2348 0; /**< Not used by the shell/core writer */ 2349 2350 pC_ewc->WriterVideoStream.decoderSpecificInfoSize = 2351 sizeof(M4WRITER_StreamVideoInfos); 2352 pC_ewc->WriterVideoStream.decoderSpecificInfo = 2353 (M4OSA_MemAddr32) &(pC_ewc->WriterVideoStreamInfo); 2354 2355 /** 2356 * Add the video stream */ 2357 err = pC_ShellAPI->pWriterGlobalFcts->pFctAddStream( 2358 pC_ewc->p3gpWriterContext, &pC_ewc->WriterVideoStream); 2359 2360 if( M4NO_ERROR != err ) 2361 { 2362 M4OSA_TRACE1_1( 2363 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2364 pWriterGlobalFcts->pFctAddStream(video) returns 0x%x!", 2365 err); 2366 return err; 2367 } 2368 2369 /** 2370 * Update AU properties for video stream */ 2371 pC_ewc->WriterVideoAU.attribute = AU_RAP; 2372 pC_ewc->WriterVideoAU.CTS = 0; 2373 pC_ewc->WriterVideoAU.DTS = 0; /** Reset time */ 2374 pC_ewc->WriterVideoAU.frag = M4OSA_NULL; 2375 pC_ewc->WriterVideoAU.nbFrag = 0; /** No fragment */ 2376 pC_ewc->WriterVideoAU.size = 0; 2377 pC_ewc->WriterVideoAU.dataAddress = M4OSA_NULL; 2378 pC_ewc->WriterVideoAU.stream = &(pC_ewc->WriterVideoStream); 2379 2380 /** 2381 * Set the writer max video AU size */ 2382 pC_ewc->uiVideoMaxAuSize = (M4OSA_UInt32)(1.5F 2383 *(M4OSA_Float)(pC_ewc->WriterVideoStreamInfo.width 2384 * pC_ewc->WriterVideoStreamInfo.height) 2385 * M4VSS3GPP_VIDEO_MIN_COMPRESSION_RATIO); 2386 temp.streamID = M4VSS3GPP_WRITER_VIDEO_STREAM_ID; 2387 temp.value = pC_ewc->uiVideoMaxAuSize; 2388 err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( 2389 pC_ewc->p3gpWriterContext, (M4OSA_UInt32)M4WRITER_kMaxAUSize, 2390 (M4OSA_DataOption) &temp); 2391 2392 if( M4NO_ERROR != err ) 2393 { 2394 M4OSA_TRACE1_1( 2395 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2396 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!", 2397 err); 2398 return err; 2399 } 2400 2401 /** 2402 * Set the writer max video chunk size */ 2403 temp.streamID = M4VSS3GPP_WRITER_VIDEO_STREAM_ID; 2404 temp.value = (M4OSA_UInt32)(pC_ewc->uiVideoMaxAuSize \ 2405 * M4VSS3GPP_VIDEO_AU_SIZE_TO_CHUNCK_SIZE_RATIO); /**< from max AU size to 2406 max Chunck size */ 2407 err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( 2408 pC_ewc->p3gpWriterContext, 2409 (M4OSA_UInt32)M4WRITER_kMaxChunckSize, 2410 (M4OSA_DataOption) &temp); 2411 2412 if( M4NO_ERROR != err ) 2413 { 2414 M4OSA_TRACE1_1( 2415 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2416 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!", 2417 err); 2418 return err; 2419 } 2420 } 2421 2422 if( M4SYS_kAudioUnknown != pC_ewc->AudioStreamType ) 2423 { 2424 M4WRITER_StreamAudioInfos streamAudioInfo; 2425 2426 streamAudioInfo.nbSamplesPerSec = 0; /**< unused by our shell writer */ 2427 streamAudioInfo.nbBitsPerSample = 0; /**< unused by our shell writer */ 2428 streamAudioInfo.nbChannels = 1; /**< unused by our shell writer */ 2429 2430 if( pC_ewc->pAudioOutputDsi != M4OSA_NULL ) 2431 { 2432 /* If we copy the stream from the input, we copy its DSI */ 2433 streamAudioInfo.Header.Size = pC_ewc->uiAudioOutputDsiSize; 2434 streamAudioInfo.Header.pBuf = pC_ewc->pAudioOutputDsi; 2435 } 2436 else 2437 { 2438 /* Writer will put a default DSI */ 2439 streamAudioInfo.Header.Size = 0; 2440 streamAudioInfo.Header.pBuf = M4OSA_NULL; 2441 } 2442 2443 pC_ewc->WriterAudioStream.streamID = M4VSS3GPP_WRITER_AUDIO_STREAM_ID; 2444 pC_ewc->WriterAudioStream.streamType = pC_ewc->AudioStreamType; 2445 pC_ewc->WriterAudioStream.duration = 2446 0; /**< Not used by the shell/core writer */ 2447 pC_ewc->WriterAudioStream.profileLevel = 2448 0; /**< Not used by the shell/core writer */ 2449 pC_ewc->WriterAudioStreamInfo.nbSamplesPerSec = 2450 pC_ewc->uiSamplingFrequency; 2451 pC_ewc->WriterAudioStream.timeScale = pC_ewc->uiSamplingFrequency; 2452 pC_ewc->WriterAudioStreamInfo.nbChannels = 2453 (M4OSA_UInt16)pC_ewc->uiNbChannels; 2454 pC_ewc->WriterAudioStreamInfo.nbBitsPerSample = 2455 0; /**< Not used by the shell/core writer */ 2456 2457 /** 2458 * Add the audio stream */ 2459 switch( pC_ewc->AudioStreamType ) 2460 { 2461 case M4SYS_kAMR: 2462 pC_ewc->WriterAudioStream.averageBitrate = 2463 0; /**< It is not used by the shell, the DSI is taken into account instead */ 2464 pC_ewc->WriterAudioStream.maxBitrate = 2465 0; /**< Not used by the shell/core writer */ 2466 break; 2467 2468 case M4SYS_kAAC: 2469 pC_ewc->WriterAudioStream.averageBitrate = 2470 pC_ewc->uiAudioBitrate; 2471 pC_ewc->WriterAudioStream.maxBitrate = pC_ewc->uiAudioBitrate; 2472 break; 2473 2474 case M4SYS_kEVRC: 2475 pC_ewc->WriterAudioStream.averageBitrate = 2476 0; /**< It is not used by the shell, the DSI is taken into account instead */ 2477 pC_ewc->WriterAudioStream.maxBitrate = 2478 0; /**< Not used by the shell/core writer */ 2479 break; 2480 2481 case M4SYS_kMP3: /**< there can't be MP3 track in 3GPP file -> error */ 2482 default: 2483 M4OSA_TRACE1_1( 2484 "M4VSS3GPP_intCreate3GPPOutputFile: unknown output audio format (0x%x),\ 2485 returning M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT!", 2486 pC_ewc->AudioStreamType); 2487 return M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT; 2488 } 2489 2490 /** 2491 * Our writer shell interface is a little tricky: we put M4WRITER_StreamAudioInfos 2492 in the DSI pointer... */ 2493 pC_ewc->WriterAudioStream.decoderSpecificInfo = 2494 (M4OSA_MemAddr32) &streamAudioInfo; 2495 2496 /** 2497 * Link the AU and the stream */ 2498 pC_ewc->WriterAudioAU.stream = &(pC_ewc->WriterAudioStream); 2499 pC_ewc->WriterAudioAU.dataAddress = M4OSA_NULL; 2500 pC_ewc->WriterAudioAU.size = 0; 2501 pC_ewc->WriterAudioAU.CTS = 2502 -pC_ewc->iSilenceFrameDuration; /** Reset time */ 2503 pC_ewc->WriterAudioAU.DTS = 0; 2504 pC_ewc->WriterAudioAU.attribute = 0; 2505 pC_ewc->WriterAudioAU.nbFrag = 0; /** No fragment */ 2506 pC_ewc->WriterAudioAU.frag = M4OSA_NULL; 2507 2508 err = pC_ShellAPI->pWriterGlobalFcts->pFctAddStream( 2509 pC_ewc->p3gpWriterContext, &pC_ewc->WriterAudioStream); 2510 2511 if( M4NO_ERROR != err ) 2512 { 2513 M4OSA_TRACE1_1( 2514 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2515 pWriterGlobalFcts->pFctAddStream(audio) returns 0x%x!", 2516 err); 2517 return err; 2518 } 2519 2520 /** 2521 * Set the writer max audio AU size */ 2522 pC_ewc->uiAudioMaxAuSize = M4VSS3GPP_AUDIO_MAX_AU_SIZE; 2523 temp.streamID = M4VSS3GPP_WRITER_AUDIO_STREAM_ID; 2524 temp.value = pC_ewc->uiAudioMaxAuSize; 2525 err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( 2526 pC_ewc->p3gpWriterContext, (M4OSA_UInt32)M4WRITER_kMaxAUSize, 2527 (M4OSA_DataOption) &temp); 2528 2529 if( M4NO_ERROR != err ) 2530 { 2531 M4OSA_TRACE1_1( 2532 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2533 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, audio) returns 0x%x!", 2534 err); 2535 return err; 2536 } 2537 2538 /** 2539 * Set the writer max audio chunck size */ 2540 temp.streamID = M4VSS3GPP_WRITER_AUDIO_STREAM_ID; 2541 temp.value = M4VSS3GPP_AUDIO_MAX_CHUNCK_SIZE; 2542 err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( 2543 pC_ewc->p3gpWriterContext, 2544 (M4OSA_UInt32)M4WRITER_kMaxChunckSize, 2545 (M4OSA_DataOption) &temp); 2546 2547 if( M4NO_ERROR != err ) 2548 { 2549 M4OSA_TRACE1_1( 2550 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2551 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, audio) returns 0x%x!", 2552 err); 2553 return err; 2554 } 2555 } 2556 2557 /** 2558 * All streams added, we're now ready to write */ 2559 err = pC_ShellAPI->pWriterGlobalFcts->pFctStartWriting( 2560 pC_ewc->p3gpWriterContext); 2561 2562 if( M4NO_ERROR != err ) 2563 { 2564 M4OSA_TRACE1_1( 2565 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2566 pWriterGlobalFcts->pFctStartWriting() returns 0x%x!", 2567 err); 2568 return err; 2569 } 2570 2571 /** 2572 * Return with no error */ 2573 M4OSA_TRACE3_0("M4VSS3GPP_intCreate3GPPOutputFile(): returning M4NO_ERROR"); 2574 return M4NO_ERROR; 2575} 2576 2577/** 2578 ****************************************************************************** 2579 * M4OSA_ERR M4VSS3GPP_intComputeOutputVideoAndAudioDsi() 2580 * @brief Generate a H263 or MPEG-4 decoder specific info compatible with all input video 2581 * tracks. Copy audio dsi from master clip. 2582 * @param pC (IN/OUT) Internal edit context 2583 ****************************************************************************** 2584 */ 2585static M4OSA_ERR 2586M4VSS3GPP_intComputeOutputVideoAndAudioDsi( M4VSS3GPP_InternalEditContext *pC, 2587 M4OSA_UInt8 uiMasterClip ) 2588{ 2589 M4OSA_Int32 iResynchMarkerDsiIndex; 2590 M4_StreamHandler *pStreamForDsi; 2591 M4VSS3GPP_ClipContext *pClip; 2592 M4OSA_ERR err; 2593 M4OSA_UInt32 i; 2594 M4DECODER_MPEG4_DecoderConfigInfo DecConfigInfo; 2595 M4DECODER_VideoSize dummySize; 2596 M4OSA_Bool bGetDSiFromEncoder = M4OSA_FALSE; 2597 2598 M4ENCODER_Header *encHeader; 2599 M4SYS_StreamIDmemAddr streamHeader; 2600 2601 pStreamForDsi = M4OSA_NULL; 2602 pClip = M4OSA_NULL; 2603 2604 /** 2605 * H263 case */ 2606 if( M4SYS_kH263 == pC->ewc.VideoStreamType ) 2607 { 2608 /** 2609 * H263 output DSI is always 7 bytes */ 2610 pC->ewc.uiVideoOutputDsiSize = 7; 2611 pC->ewc.pVideoOutputDsi = 2612 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ewc.uiVideoOutputDsiSize, 2613 M4VSS3GPP, (M4OSA_Char *)"pC->ewc.pVideoOutputDsi (H263)"); 2614 2615 if( M4OSA_NULL == pC->ewc.pVideoOutputDsi ) 2616 { 2617 M4OSA_TRACE1_0( 2618 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi():\ 2619 unable to allocate pVideoOutputDsi (H263), returning M4ERR_ALLOC"); 2620 return M4ERR_ALLOC; 2621 } 2622 2623 /** 2624 * (We override the input vendor info. 2625 * At least we know that nothing special will be tried with PHLP-stamped 2626 edited streams...) */ 2627 pC->ewc.pVideoOutputDsi[0] = 'P'; 2628 pC->ewc.pVideoOutputDsi[1] = 'H'; 2629 pC->ewc.pVideoOutputDsi[2] = 'L'; 2630 pC->ewc.pVideoOutputDsi[3] = 'P'; 2631 2632 /** 2633 * Decoder version is 0 */ 2634 pC->ewc.pVideoOutputDsi[4] = 0; 2635 2636 /** 2637 * Level is the sixth byte in the DSI */ 2638 pC->ewc.pVideoOutputDsi[5] = pC->xVSS.outputVideoLevel; 2639 2640 /** 2641 * Profile is the seventh byte in the DSI*/ 2642 pC->ewc.pVideoOutputDsi[6] = pC->xVSS.outputVideoProfile; 2643 } 2644 2645 /** 2646 * MPEG-4 case */ 2647 else if( M4SYS_kMPEG_4 == pC->ewc.VideoStreamType || 2648 M4SYS_kH264 == pC->ewc.VideoStreamType) { 2649 2650 /* For MPEG4 and H.264 encoder case 2651 * Fetch the DSI from the shell video encoder, and feed it to the writer before 2652 closing it. */ 2653 2654 M4OSA_TRACE1_0( 2655 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi: get DSI for H264 stream"); 2656 2657 if( M4OSA_NULL == pC->ewc.pEncContext ) 2658 { 2659 M4OSA_TRACE1_0( 2660 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi: pC->ewc.pEncContext is NULL"); 2661 err = M4VSS3GPP_intCreateVideoEncoder(pC); 2662 2663 if( M4NO_ERROR != err ) 2664 { 2665 M4OSA_TRACE1_1( 2666 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2667 M4VSS3GPP_intCreateVideoEncoder returned error 0x%x", 2668 err); 2669 } 2670 } 2671 2672 if( M4OSA_NULL != pC->ewc.pEncContext ) 2673 { 2674 err = pC->ShellAPI.pVideoEncoderGlobalFcts->pFctGetOption( 2675 pC->ewc.pEncContext, M4ENCODER_kOptionID_EncoderHeader, 2676 (M4OSA_DataOption) &encHeader); 2677 2678 if( ( M4NO_ERROR != err) || (M4OSA_NULL == encHeader->pBuf) ) 2679 { 2680 M4OSA_TRACE1_1( 2681 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2682 failed to get the encoder header (err 0x%x)", 2683 err); 2684 M4OSA_TRACE1_2( 2685 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi: encHeader->pBuf=0x%x, size=0x%x", 2686 encHeader->pBuf, encHeader->Size); 2687 } 2688 else 2689 { 2690 M4OSA_TRACE1_0( 2691 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2692 send DSI for video stream to 3GP writer"); 2693 2694 /** 2695 * Allocate and copy the new DSI */ 2696 pC->ewc.pVideoOutputDsi = 2697 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(encHeader->Size, M4VSS3GPP, 2698 (M4OSA_Char *)"pC->ewc.pVideoOutputDsi (H264)"); 2699 2700 if( M4OSA_NULL == pC->ewc.pVideoOutputDsi ) 2701 { 2702 M4OSA_TRACE1_0( 2703 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi():\ 2704 unable to allocate pVideoOutputDsi, returning M4ERR_ALLOC"); 2705 return M4ERR_ALLOC; 2706 } 2707 pC->ewc.uiVideoOutputDsiSize = (M4OSA_UInt16)encHeader->Size; 2708 memcpy((void *)pC->ewc.pVideoOutputDsi, (void *)encHeader->pBuf, 2709 encHeader->Size); 2710 } 2711 2712 err = M4VSS3GPP_intDestroyVideoEncoder(pC); 2713 2714 if( M4NO_ERROR != err ) 2715 { 2716 M4OSA_TRACE1_1( 2717 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2718 M4VSS3GPP_intDestroyVideoEncoder returned error 0x%x", 2719 err); 2720 } 2721 } 2722 else 2723 { 2724 M4OSA_TRACE1_0( 2725 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2726 pC->ewc.pEncContext is NULL, cannot get the DSI"); 2727 } 2728 } 2729 2730 pStreamForDsi = M4OSA_NULL; 2731 pClip = M4OSA_NULL; 2732 2733 /* Compute Audio DSI */ 2734 if( M4SYS_kAudioUnknown != pC->ewc.AudioStreamType ) 2735 { 2736 if( uiMasterClip == 0 ) 2737 { 2738 /* Clip is already opened */ 2739 pStreamForDsi = &(pC->pC1->pAudioStream->m_basicProperties); 2740 } 2741 else 2742 { 2743 /** 2744 * We can use the fast open mode to get the DSI */ 2745 err = M4VSS3GPP_intClipInit(&pClip, pC->pOsaFileReadPtr); 2746 2747 if( M4NO_ERROR != err ) 2748 { 2749 M4OSA_TRACE1_1( 2750 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2751 M4VSS3GPP_intClipInit() returns 0x%x!", 2752 err); 2753 2754 if( pClip != M4OSA_NULL ) 2755 { 2756 M4VSS3GPP_intClipCleanUp(pClip); 2757 } 2758 return err; 2759 } 2760 2761 err = M4VSS3GPP_intClipOpen(pClip, &pC->pClipList[uiMasterClip], 2762 M4OSA_FALSE, M4OSA_TRUE, M4OSA_TRUE); 2763 2764 if( M4NO_ERROR != err ) 2765 { 2766 M4OSA_TRACE1_1( 2767 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2768 M4VSS3GPP_intClipOpen() returns 0x%x!", 2769 err); 2770 M4VSS3GPP_intClipCleanUp(pClip); 2771 return err; 2772 } 2773 2774 pStreamForDsi = &(pClip->pAudioStream->m_basicProperties); 2775 } 2776 2777 /** 2778 * Allocate and copy the new DSI */ 2779 pC->ewc.pAudioOutputDsi = (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc( 2780 pStreamForDsi->m_decoderSpecificInfoSize, 2781 M4VSS3GPP, (M4OSA_Char *)"pC->ewc.pAudioOutputDsi"); 2782 2783 if( M4OSA_NULL == pC->ewc.pAudioOutputDsi ) 2784 { 2785 M4OSA_TRACE1_0( 2786 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi():\ 2787 unable to allocate pAudioOutputDsi, returning M4ERR_ALLOC"); 2788 return M4ERR_ALLOC; 2789 } 2790 pC->ewc.uiAudioOutputDsiSize = 2791 (M4OSA_UInt16)pStreamForDsi->m_decoderSpecificInfoSize; 2792 memcpy((void *)pC->ewc.pAudioOutputDsi, 2793 (void *)pStreamForDsi->m_pDecoderSpecificInfo, 2794 pC->ewc.uiAudioOutputDsiSize); 2795 2796 /** 2797 * If a clip has been temporarily opened to get its DSI, close it */ 2798 if( M4OSA_NULL != pClip ) 2799 { 2800 err = M4VSS3GPP_intClipCleanUp(pClip); 2801 2802 if( M4NO_ERROR != err ) 2803 { 2804 M4OSA_TRACE1_1( 2805 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2806 M4VSS3GPP_intClipCleanUp() returns 0x%x!", 2807 err); 2808 return err; 2809 } 2810 } 2811 } 2812 2813 /** 2814 * Return with no error */ 2815 M4OSA_TRACE3_0( 2816 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi(): returning M4NO_ERROR"); 2817 return M4NO_ERROR; 2818} 2819 2820/** 2821 ****************************************************************************** 2822 * M4OSA_ERR M4VSS3GPP_intSwitchToNextClip() 2823 * @brief Switch from the current clip to the next one 2824 * @param pC (IN/OUT) Internal edit context 2825 ****************************************************************************** 2826 */ 2827static M4OSA_ERR M4VSS3GPP_intSwitchToNextClip( 2828 M4VSS3GPP_InternalEditContext *pC ) 2829{ 2830 M4OSA_ERR err; 2831 2832 if( M4OSA_NULL != pC->pC1 ) 2833 { 2834 if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame) { 2835 if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame[0].pac_data) { 2836 free(pC->pC1->m_pPreResizeFrame[0].pac_data); 2837 pC->pC1->m_pPreResizeFrame[0].pac_data = M4OSA_NULL; 2838 } 2839 if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame[1].pac_data) { 2840 free(pC->pC1->m_pPreResizeFrame[1].pac_data); 2841 pC->pC1->m_pPreResizeFrame[1].pac_data = M4OSA_NULL; 2842 } 2843 if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame[2].pac_data) { 2844 free(pC->pC1->m_pPreResizeFrame[2].pac_data); 2845 pC->pC1->m_pPreResizeFrame[2].pac_data = M4OSA_NULL; 2846 } 2847 free(pC->pC1->m_pPreResizeFrame); 2848 pC->pC1->m_pPreResizeFrame = M4OSA_NULL; 2849 } 2850 /** 2851 * Close the current first clip */ 2852 err = M4VSS3GPP_intClipCleanUp(pC->pC1); 2853 2854 if( M4NO_ERROR != err ) 2855 { 2856 M4OSA_TRACE1_1( 2857 "M4VSS3GPP_intSwitchToNextClip: M4VSS3GPP_intClipCleanUp(C1) returns 0x%x!", 2858 err); 2859 return err; 2860 } 2861 2862 /** 2863 * increment clip counter */ 2864 pC->uiCurrentClip++; 2865 } 2866 2867 /** 2868 * Check if we reached the last clip */ 2869 if( pC->uiCurrentClip >= pC->uiClipNumber ) 2870 { 2871 pC->pC1 = M4OSA_NULL; 2872 pC->State = M4VSS3GPP_kEditState_FINISHED; 2873 2874 M4OSA_TRACE1_0( 2875 "M4VSS3GPP_intSwitchToNextClip:\ 2876 M4VSS3GPP_intClipClose(C1) returns M4VSS3GPP_WAR_EDITING_DONE"); 2877 return M4VSS3GPP_WAR_EDITING_DONE; 2878 } 2879 2880 /** 2881 * If the next clip has already be opened, set it as first clip */ 2882 if( M4OSA_NULL != pC->pC2 ) 2883 { 2884 pC->pC1 = pC->pC2; 2885 if(M4OSA_NULL != pC->pC2->m_pPreResizeFrame) { 2886 pC->pC1->m_pPreResizeFrame = pC->pC2->m_pPreResizeFrame; 2887 } 2888 pC->pC2 = M4OSA_NULL; 2889 } 2890 /** 2891 * else open it */ 2892 else 2893 { 2894 err = M4VSS3GPP_intOpenClip(pC, &pC->pC1, 2895 &pC->pClipList[pC->uiCurrentClip]); 2896 2897 if( M4NO_ERROR != err ) 2898 { 2899 M4OSA_TRACE1_1( 2900 "M4VSS3GPP_intSwitchToNextClip: M4VSS3GPP_intOpenClip() returns 0x%x!", 2901 err); 2902 return err; 2903 } 2904 2905 /** 2906 * If the second clip has not been opened yet, 2907 that means that there has been no transition. 2908 * So both output video and audio times are OK. 2909 * So we can set both video2 and audio offsets */ 2910 2911 /** 2912 * Add current video output CTS to the clip video offset */ 2913 2914 // Decorrelate input and output encoding timestamp to handle encoder prefetch 2915 pC->pC1->iVoffset += (M4OSA_UInt32)pC->ewc.dInputVidCts; 2916 /** 2917 * Add current audio output CTS to the clip audio offset */ 2918 pC->pC1->iAoffset += 2919 (M4OSA_UInt32)(pC->ewc.dATo * pC->ewc.scale_audio + 0.5); 2920 2921 /** 2922 * 2005-03-24: BugFix for audio-video synchro: 2923 * There may be a portion of the duration of an audio AU of desynchro at each assembly. 2924 * It leads to an audible desynchro when there are a lot of clips assembled. 2925 * This bug fix allows to resynch the audio track when the delta is higher 2926 * than one audio AU duration. 2927 * We Step one AU in the second clip and we change the audio offset accordingly. */ 2928 if( ( pC->pC1->iAoffset 2929 - (M4OSA_Int32)(pC->pC1->iVoffset *pC->pC1->scale_audio + 0.5)) 2930 > pC->ewc.iSilenceFrameDuration ) 2931 { 2932 /** 2933 * Advance one AMR frame */ 2934 err = M4VSS3GPP_intClipReadNextAudioFrame(pC->pC1); 2935 2936 if( M4OSA_ERR_IS_ERROR(err) ) 2937 { 2938 M4OSA_TRACE1_1( 2939 "M4VSS3GPP_intSwitchToNextClip:\ 2940 M4VSS3GPP_intClipReadNextAudioFrame returns 0x%x!", 2941 err); 2942 return err; 2943 } 2944 /** 2945 * Update audio offset accordingly*/ 2946 pC->pC1->iAoffset -= pC->ewc.iSilenceFrameDuration; 2947 } 2948 } 2949 2950 /** 2951 * Init starting state for this clip processing */ 2952 if( M4SYS_kMP3 == pC->ewc.AudioStreamType ) 2953 { 2954 /** 2955 * In the MP3 case we use a special audio state */ 2956 pC->State = M4VSS3GPP_kEditState_MP3_JUMP; 2957 } 2958 else 2959 { 2960 /** 2961 * We start with the video processing */ 2962 pC->State = M4VSS3GPP_kEditState_VIDEO; 2963 2964 if( pC->Vstate != M4VSS3GPP_kEditVideoState_TRANSITION ) 2965 { 2966 /* if not a transition then reset previous video state */ 2967 pC->Vstate = M4VSS3GPP_kEditVideoState_READ_WRITE; 2968 2969 if( pC->bIsMMS == M4OSA_FALSE ) /* RC */ 2970 { 2971 /* There may be an encoder to destroy */ 2972 err = M4VSS3GPP_intDestroyVideoEncoder(pC); 2973 2974 if( M4NO_ERROR != err ) 2975 { 2976 M4OSA_TRACE1_1( 2977 "M4VSS3GPP_intSwitchToNextClip:\ 2978 M4VSS3GPP_editDestroyVideoEncoder() returns 0x%x!", 2979 err); 2980 return err; 2981 } 2982 } 2983 } 2984 } 2985 /* The flags are set to false at the beginning of every clip */ 2986 pC->m_bClipExternalHasStarted = M4OSA_FALSE; 2987 pC->bEncodeTillEoF = M4OSA_FALSE; 2988 2989 /** 2990 * Return with no error */ 2991 M4OSA_TRACE3_0("M4VSS3GPP_intSwitchToNextClip(): returning M4NO_ERROR"); 2992 /* RC: to know when a file has been processed */ 2993 return M4VSS3GPP_WAR_SWITCH_CLIP; 2994} 2995 2996/** 2997 ****************************************************************************** 2998 * M4OSA_ERR M4VSS3GPP_intReachedEndOfVideo() 2999 * @brief Do what to do when the end of a clip video track is reached 3000 * @note If there is audio on the current clip, process it, else switch to the next clip 3001 * @param pC (IN/OUT) Internal edit context 3002 ****************************************************************************** 3003 */ 3004M4OSA_ERR M4VSS3GPP_intReachedEndOfVideo( M4VSS3GPP_InternalEditContext *pC ) 3005{ 3006 M4OSA_ERR err; 3007 3008 /** 3009 * Video is done for this clip, now we do the audio */ 3010 if( M4SYS_kAudioUnknown != pC->ewc.AudioStreamType ) 3011 { 3012 pC->State = M4VSS3GPP_kEditState_AUDIO; 3013 } 3014 else 3015 { 3016 /** 3017 * Clip done, do the next one */ 3018 err = M4VSS3GPP_intSwitchToNextClip(pC); 3019 3020 if( M4NO_ERROR != err ) 3021 { 3022 M4OSA_TRACE1_1( 3023 "M4VSS3GPP_intReachedEndOfVideo: M4VSS3GPP_intSwitchToNextClip() returns 0x%x", 3024 err); 3025 return err; 3026 } 3027 } 3028 3029 /** 3030 * Return with no error */ 3031 M4OSA_TRACE3_0("M4VSS3GPP_intReachedEndOfVideo(): returning M4NO_ERROR"); 3032 return M4NO_ERROR; 3033} 3034 3035/** 3036 ****************************************************************************** 3037 * M4OSA_ERR M4VSS3GPP_intReachedEndOfAudio() 3038 * @brief Do what to do when the end of a clip audio track is reached 3039 * @param pC (IN/OUT) Internal edit context 3040 ****************************************************************************** 3041 */ 3042M4OSA_ERR M4VSS3GPP_intReachedEndOfAudio( M4VSS3GPP_InternalEditContext *pC ) 3043{ 3044 M4OSA_ERR err; 3045 3046 /** 3047 * Clip done, do the next one */ 3048 err = M4VSS3GPP_intSwitchToNextClip(pC); 3049 3050 if( M4NO_ERROR != err ) 3051 { 3052 M4OSA_TRACE1_1( 3053 "M4VSS3GPP_intReachedEndOfAudio: M4VSS3GPP_intSwitchToNextClip() returns 0x%x", 3054 err); 3055 return err; 3056 } 3057 3058 /** 3059 * Start with the video */ 3060 if( M4SYS_kVideoUnknown != pC->ewc.VideoStreamType ) 3061 { 3062 pC->State = M4VSS3GPP_kEditState_VIDEO; 3063 } 3064 3065 /** 3066 * Return with no error */ 3067 M4OSA_TRACE3_0("M4VSS3GPP_intReachedEndOfAudio(): returning M4NO_ERROR"); 3068 return M4NO_ERROR; 3069} 3070 3071/** 3072 ****************************************************************************** 3073 * M4OSA_ERR M4VSS3GPP_intOpenClip() 3074 * @brief Open next clip 3075 * @param pC (IN/OUT) Internal edit context 3076 ****************************************************************************** 3077 */ 3078M4OSA_ERR M4VSS3GPP_intOpenClip( M4VSS3GPP_InternalEditContext *pC, 3079 M4VSS3GPP_ClipContext ** hClip, 3080 M4VSS3GPP_ClipSettings *pClipSettings ) 3081{ 3082 M4OSA_ERR err; 3083 M4VSS3GPP_ClipContext *pClip; /**< shortcut */ 3084 M4VIDEOEDITING_ClipProperties *pClipProperties = M4OSA_NULL; 3085 M4OSA_Int32 iCts; 3086 M4OSA_UInt32 i; 3087 3088 M4OSA_TRACE2_1("M4VSS3GPP_intOpenClip: \"%s\"", 3089 (M4OSA_Char *)pClipSettings->pFile); 3090 3091 err = M4VSS3GPP_intClipInit(hClip, pC->pOsaFileReadPtr); 3092 3093 if( M4NO_ERROR != err ) 3094 { 3095 M4OSA_TRACE1_1( 3096 "M4VSS3GPP_intOpenClip: M4VSS3GPP_intClipInit() returns 0x%x!", 3097 err); 3098 3099 if( *hClip != M4OSA_NULL ) 3100 { 3101 M4VSS3GPP_intClipCleanUp(*hClip); 3102 } 3103 return err; 3104 } 3105 3106 /** 3107 * Set shortcut */ 3108 pClip = *hClip; 3109 3110 if (pClipSettings->FileType == M4VIDEOEDITING_kFileType_ARGB8888 ) { 3111 pClipProperties = &pClipSettings->ClipProperties; 3112 pClip->pSettings = pClipSettings; 3113 pClip->iEndTime = pClipSettings->uiEndCutTime; 3114 } 3115 3116 err = M4VSS3GPP_intClipOpen(pClip, pClipSettings, 3117 M4OSA_FALSE, M4OSA_FALSE, M4OSA_FALSE); 3118 if (M4NO_ERROR != err) { 3119 M4OSA_TRACE1_1("M4VSS3GPP_intOpenClip: \ 3120 M4VSS3GPP_intClipOpen() returns 0x%x!", err); 3121 M4VSS3GPP_intClipCleanUp(pClip); 3122 *hClip = M4OSA_NULL; 3123 return err; 3124 } 3125 3126 if (pClipSettings->FileType != M4VIDEOEDITING_kFileType_ARGB8888 ) { 3127 pClipProperties = &pClip->pSettings->ClipProperties; 3128 } 3129 3130 /** 3131 * Copy common 'silence frame stuff' to ClipContext */ 3132 pClip->uiSilencePcmSize = pC->ewc.uiSilencePcmSize; 3133 pClip->pSilenceFrameData = pC->ewc.pSilenceFrameData; 3134 pClip->uiSilenceFrameSize = pC->ewc.uiSilenceFrameSize; 3135 pClip->iSilenceFrameDuration = pC->ewc.iSilenceFrameDuration; 3136 pClip->scale_audio = pC->ewc.scale_audio; 3137 3138 pClip->iAudioFrameCts = -pClip->iSilenceFrameDuration; /* Reset time */ 3139 3140 /** 3141 * If the audio track is not compatible with the output audio format, 3142 * we remove it. So it will be replaced by silence */ 3143 if( M4OSA_FALSE == pClipProperties->bAudioIsCompatibleWithMasterClip ) 3144 { 3145 M4VSS3GPP_intClipDeleteAudioTrack(pClip); 3146 } 3147 3148 /** 3149 * Actual begin cut */ 3150 if( 0 == pClipSettings->uiBeginCutTime ) 3151 { 3152 pClip->iVoffset = 0; 3153 pClip->iAoffset = 0; 3154 pClip->iActualVideoBeginCut = 0; 3155 pClip->iActualAudioBeginCut = 0; 3156 } 3157 else if(pClipSettings->FileType != M4VIDEOEDITING_kFileType_ARGB8888) { 3158 if( M4SYS_kVideoUnknown != pC->ewc.VideoStreamType ) 3159 { 3160 /** 3161 * Jump the video to the target begin cut to get the actual begin cut value */ 3162 pClip->iActualVideoBeginCut = 3163 (M4OSA_Int32)pClipSettings->uiBeginCutTime; 3164 iCts = pClip->iActualVideoBeginCut; 3165 3166 err = pClip->ShellAPI.m_pReader->m_pFctJump(pClip->pReaderContext, 3167 (M4_StreamHandler *)pClip->pVideoStream, &iCts); 3168 3169 if( M4NO_ERROR != err ) 3170 { 3171 M4OSA_TRACE1_1( 3172 "M4VSS3GPP_intOpenClip: m_pFctJump(V) returns 0x%x!", err); 3173 return err; 3174 } 3175 3176 /** 3177 * Update clip offset with the video begin cut */ 3178 pClip->iVoffset = -pClip->iActualVideoBeginCut; 3179 } 3180 3181 if( M4SYS_kAudioUnknown != pC->ewc.AudioStreamType ) 3182 { 3183 /** 3184 * Jump the audio to the video actual begin cut */ 3185 if( M4VIDEOEDITING_kMP3 != pClipProperties->AudioStreamType ) 3186 { 3187 pClip->iActualAudioBeginCut = pClip->iActualVideoBeginCut; 3188 iCts = (M4OSA_Int32)(pClip->iActualAudioBeginCut 3189 * pClip->scale_audio + 0.5); 3190 3191 err = M4VSS3GPP_intClipJumpAudioAt(pClip, &iCts); 3192 3193 if( M4NO_ERROR != err ) 3194 { 3195 M4OSA_TRACE1_1( 3196 "M4VSS3GPP_intOpenClip: M4VSS3GPP_intClipJumpAudioAt(A) returns 0x%x!", 3197 err); 3198 return err; 3199 } 3200 /** 3201 * Update clip offset with the audio begin cut */ 3202 pClip->iAoffset = -iCts; 3203 } 3204 else 3205 { 3206 /** 3207 * For the MP3, the jump is not done because of the VBR, 3208 it could be not enough accurate */ 3209 pClip->iActualAudioBeginCut = 3210 (M4OSA_Int32)pClipSettings->uiBeginCutTime; 3211 } 3212 } 3213 } 3214 3215 if( M4SYS_kVideoUnknown != pC->ewc.VideoStreamType ) 3216 { 3217 if ((pClipSettings->FileType != M4VIDEOEDITING_kFileType_ARGB8888 )) { 3218 3219 /** 3220 * Read the first Video AU of the clip */ 3221 err = pClip->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu( 3222 pClip->pReaderContext, 3223 (M4_StreamHandler *)pClip->pVideoStream, &pClip->VideoAU); 3224 3225 if( M4WAR_NO_MORE_AU == err ) 3226 { 3227 /** 3228 * If we (already!) reach the end of the clip, we filter the error. 3229 * It will be correctly managed at the first step. */ 3230 err = M4NO_ERROR; 3231 } 3232 else if( M4NO_ERROR != err ) 3233 { 3234 M4OSA_TRACE1_1("M4VSS3GPP_intOpenClip: \ 3235 m_pReaderDataIt->m_pFctGetNextAu() returns 0x%x!", err); 3236 return err; 3237 } 3238 } else { 3239 pClipProperties->uiVideoWidth = pClipProperties->uiStillPicWidth; 3240 pClipProperties->uiVideoHeight = pClipProperties->uiStillPicHeight; 3241 } 3242 /* state check not to allocate buffer during save start */ 3243 3244 3245 /******************************/ 3246 /* Video resize management */ 3247 /******************************/ 3248 /** 3249 * Compare input video size with output video size 3250 to check if resize needed */ 3251 if (((M4OSA_UInt32)pC->ewc.uiVideoWidth != 3252 pClipProperties->uiVideoWidth) || 3253 ((M4OSA_UInt32)pC->ewc.uiVideoHeight != 3254 pClipProperties->uiVideoHeight)) { 3255 if(pClip->m_pPreResizeFrame == M4OSA_NULL) { 3256 /** 3257 * Allocate the intermediate video plane that will 3258 receive the decoded image before resizing */ 3259 pClip->m_pPreResizeFrame = 3260 (M4VIFI_ImagePlane*)M4OSA_32bitAlignedMalloc( 3261 3*sizeof(M4VIFI_ImagePlane), M4VSS3GPP, 3262 (M4OSA_Char *)"pPreResizeFrame"); 3263 if (M4OSA_NULL == pClip->m_pPreResizeFrame) { 3264 M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder(): \ 3265 unable to allocate m_pPreResizeFrame"); 3266 return M4ERR_ALLOC; 3267 } 3268 3269 pClip->m_pPreResizeFrame[0].pac_data = M4OSA_NULL; 3270 pClip->m_pPreResizeFrame[1].pac_data = M4OSA_NULL; 3271 pClip->m_pPreResizeFrame[2].pac_data = M4OSA_NULL; 3272 3273 /** 3274 * Allocate the Y plane */ 3275 pClip->m_pPreResizeFrame[0].u_topleft = 0; 3276 pClip->m_pPreResizeFrame[0].u_width = 3277 pClipProperties->uiVideoWidth; 3278 pClip->m_pPreResizeFrame[0].u_height = 3279 pClipProperties->uiVideoHeight; 3280 pClip->m_pPreResizeFrame[0].u_stride = 3281 pClip->m_pPreResizeFrame[0].u_width; 3282 3283 pClip->m_pPreResizeFrame[0].pac_data = 3284 (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc ( 3285 pClip->m_pPreResizeFrame[0].u_stride * pClip->m_pPreResizeFrame[0].u_height, 3286 M4MCS, (M4OSA_Char *)"m_pPreResizeFrame[0].pac_data"); 3287 if (M4OSA_NULL == pClip->m_pPreResizeFrame[0].pac_data) { 3288 M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder(): \ 3289 unable to allocate m_pPreResizeFrame[0].pac_data"); 3290 free(pClip->m_pPreResizeFrame); 3291 return M4ERR_ALLOC; 3292 } 3293 3294 /** 3295 * Allocate the U plane */ 3296 pClip->m_pPreResizeFrame[1].u_topleft = 0; 3297 pClip->m_pPreResizeFrame[1].u_width = 3298 pClip->m_pPreResizeFrame[0].u_width >> 1; 3299 pClip->m_pPreResizeFrame[1].u_height = 3300 pClip->m_pPreResizeFrame[0].u_height >> 1; 3301 pClip->m_pPreResizeFrame[1].u_stride = 3302 pClip->m_pPreResizeFrame[1].u_width; 3303 3304 pClip->m_pPreResizeFrame[1].pac_data = 3305 (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc ( 3306 pClip->m_pPreResizeFrame[1].u_stride * pClip->m_pPreResizeFrame[1].u_height, 3307 M4MCS, (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data"); 3308 if (M4OSA_NULL == pClip->m_pPreResizeFrame[1].pac_data) { 3309 M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder(): \ 3310 unable to allocate m_pPreResizeFrame[1].pac_data"); 3311 free(pClip->m_pPreResizeFrame[0].pac_data); 3312 free(pClip->m_pPreResizeFrame); 3313 return M4ERR_ALLOC; 3314 } 3315 3316 /** 3317 * Allocate the V plane */ 3318 pClip->m_pPreResizeFrame[2].u_topleft = 0; 3319 pClip->m_pPreResizeFrame[2].u_width = 3320 pClip->m_pPreResizeFrame[1].u_width; 3321 pClip->m_pPreResizeFrame[2].u_height = 3322 pClip->m_pPreResizeFrame[1].u_height; 3323 pClip->m_pPreResizeFrame[2].u_stride = 3324 pClip->m_pPreResizeFrame[2].u_width; 3325 3326 pClip->m_pPreResizeFrame[2].pac_data = 3327 (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc ( 3328 pClip->m_pPreResizeFrame[2].u_stride * pClip->m_pPreResizeFrame[2].u_height, 3329 M4MCS, (M4OSA_Char *)"m_pPreResizeFrame[2].pac_data"); 3330 if (M4OSA_NULL == pClip->m_pPreResizeFrame[2].pac_data) { 3331 M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder(): \ 3332 unable to allocate m_pPreResizeFrame[2].pac_data"); 3333 free(pClip->m_pPreResizeFrame[0].pac_data); 3334 free(pClip->m_pPreResizeFrame[1].pac_data); 3335 free(pClip->m_pPreResizeFrame); 3336 return M4ERR_ALLOC; 3337 } 3338 } 3339 } 3340 3341 /** 3342 * The video is currently in reading mode */ 3343 pClip->Vstatus = M4VSS3GPP_kClipStatus_READ; 3344 } 3345 3346 if( ( M4SYS_kAudioUnknown != pC->ewc.AudioStreamType) 3347 && (M4VIDEOEDITING_kMP3 != pClipProperties->AudioStreamType) ) 3348 { 3349 /** 3350 * Read the first Audio AU of the clip */ 3351 err = M4VSS3GPP_intClipReadNextAudioFrame(pClip); 3352 3353 if( M4OSA_ERR_IS_ERROR(err) ) 3354 { 3355 M4OSA_TRACE1_1( 3356 "M4VSS3GPP_intOpenClip: M4VSS3GPP_intClipReadNextAudioFrame returns 0x%x!", 3357 err); 3358 return err; 3359 } 3360 3361 /** 3362 * The audio is currently in reading mode */ 3363 pClip->Astatus = M4VSS3GPP_kClipStatus_READ; 3364 } 3365 3366 /** 3367 * Return with no error */ 3368 M4OSA_TRACE3_0("M4VSS3GPP_intOpenClip(): returning M4NO_ERROR"); 3369 return M4NO_ERROR; 3370} 3371 3372/** 3373 ****************************************************************************** 3374 * M4OSA_ERR M4VSS3GPP_intComputeOutputAverageVideoBitrate() 3375 * @brief Average bitrate of the output file, computed from input bitrates, 3376 * durations, transitions and cuts. 3377 * @param pC (IN/OUT) Internal edit context 3378 ****************************************************************************** 3379 */ 3380static M4OSA_Void M4VSS3GPP_intComputeOutputAverageVideoBitrate( 3381 M4VSS3GPP_InternalEditContext *pC ) 3382{ 3383 M4VSS3GPP_ClipSettings *pCS_0, *pCS_1, *pCS_2; 3384 M4VSS3GPP_TransitionSettings *pT0, *pT2; 3385 M4OSA_Int32 i; 3386 3387 M4OSA_UInt32 t0_duration, t2_duration; 3388 M4OSA_UInt32 t0_bitrate, t2_bitrate; 3389 M4OSA_UInt32 c1_duration; 3390 3391 M4OSA_UInt32 total_duration; 3392 M4OSA_UInt32 total_bitsum; 3393 3394 total_duration = 0; 3395 total_bitsum = 0; 3396 3397 /* Loop on the number of clips */ 3398 for ( i = 0; i < pC->uiClipNumber; i++ ) 3399 { 3400 pCS_1 = &pC->pClipList[i]; 3401 3402 t0_duration = 0; 3403 t0_bitrate = pCS_1->ClipProperties.uiVideoBitrate; 3404 t2_duration = 0; 3405 t2_bitrate = pCS_1->ClipProperties.uiVideoBitrate; 3406 3407 /* Transition with the previous clip */ 3408 if( i > 0 ) 3409 { 3410 pCS_0 = &pC->pClipList[i - 1]; 3411 pT0 = &pC->pTransitionList[i - 1]; 3412 3413 if( pT0->VideoTransitionType 3414 != M4VSS3GPP_kVideoTransitionType_None ) 3415 { 3416 t0_duration = pT0->uiTransitionDuration; 3417 3418 if( pCS_0->ClipProperties.uiVideoBitrate > t0_bitrate ) 3419 { 3420 t0_bitrate = pCS_0->ClipProperties.uiVideoBitrate; 3421 } 3422 } 3423 } 3424 3425 /* Transition with the next clip */ 3426 if( i < pC->uiClipNumber - 1 ) 3427 { 3428 pCS_2 = &pC->pClipList[i + 1]; 3429 pT2 = &pC->pTransitionList[i]; 3430 3431 if( pT2->VideoTransitionType 3432 != M4VSS3GPP_kVideoTransitionType_None ) 3433 { 3434 t2_duration = pT2->uiTransitionDuration; 3435 3436 if( pCS_2->ClipProperties.uiVideoBitrate > t2_bitrate ) 3437 { 3438 t2_bitrate = pCS_2->ClipProperties.uiVideoBitrate; 3439 } 3440 } 3441 } 3442 3443 /* Check for cut times */ 3444 if( pCS_1->uiEndCutTime > 0 ) 3445 c1_duration = pCS_1->uiEndCutTime; 3446 else 3447 c1_duration = pCS_1->ClipProperties.uiClipVideoDuration; 3448 3449 if( pCS_1->uiBeginCutTime > 0 ) 3450 c1_duration -= pCS_1->uiBeginCutTime; 3451 3452 c1_duration -= t0_duration + t2_duration; 3453 3454 /* Compute bitsum and duration */ 3455 total_duration += c1_duration + t0_duration / 2 + t2_duration / 2; 3456 3457 total_bitsum += 3458 c1_duration * (pCS_1->ClipProperties.uiVideoBitrate / 1000) 3459 + (t0_bitrate / 1000) * t0_duration / 2 3460 + (t2_bitrate / 1000) * t2_duration / 2; 3461 } 3462 3463 pC->ewc.uiVideoBitrate = ( total_bitsum / total_duration) * 1000; 3464} 3465 3466