M4VSS3GPP_Edit.c revision 276adbc8cab51c5cd60906fdbff9c7d5345ad0a6
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 case M4VIDEOEDITING_k1920_1080: 944 pC->ewc.uiVideoWidth = 1920; 945 pC->ewc.uiVideoHeight = 1088; // need to be multiples of 16 946 break; 947 948 default: /* If output video size is not given, we take QCIF size */ 949 M4OSA_TRACE1_0( 950 "M4VSS3GPP_editOpen: no output video size given, default to QCIF!"); 951 pC->ewc.uiVideoWidth = 176; 952 pC->ewc.uiVideoHeight = 144; 953 pC->xVSS.outputVideoSize = M4VIDEOEDITING_kQCIF; 954 break; 955 } 956 957 pC->ewc.uiVideoTimeScale = 30; 958 pC->ewc.bVideoDataPartitioning = 0; 959 /* Set output video profile and level */ 960 pC->ewc.outputVideoProfile = pC->xVSS.outputVideoProfile; 961 pC->ewc.outputVideoLevel = pC->xVSS.outputVideoLevel; 962 963 switch(pC->xVSS.outputVideoFormat) { 964 case M4VIDEOEDITING_kH263: 965 pC->ewc.VideoStreamType = M4SYS_kH263; 966 break; 967 case M4VIDEOEDITING_kMPEG4: 968 pC->ewc.VideoStreamType = M4SYS_kMPEG_4; 969 break; 970 case M4VIDEOEDITING_kH264: 971 pC->ewc.VideoStreamType = M4SYS_kH264; 972 break; 973 default: 974 pC->ewc.VideoStreamType = M4SYS_kVideoUnknown; 975 break; 976 } 977 978 /** 979 * Copy the audio properties of the master clip to the output properties */ 980 pC->ewc.uiNbChannels = 981 pC->pClipList[pSettings->uiMasterClip].ClipProperties.uiNbChannels; 982 pC->ewc.uiAudioBitrate = 983 pC->pClipList[pSettings->uiMasterClip].ClipProperties.uiAudioBitrate; 984 pC->ewc.uiSamplingFrequency = pC->pClipList[pSettings-> 985 uiMasterClip].ClipProperties.uiSamplingFrequency; 986 pC->ewc.uiSilencePcmSize = 987 pC->pClipList[pSettings->uiMasterClip].ClipProperties.uiDecodedPcmSize; 988 pC->ewc.scale_audio = pC->ewc.uiSamplingFrequency / 1000.0; 989 990 switch( pC->pClipList[pSettings->uiMasterClip].ClipProperties.AudioStreamType ) 991 { 992 case M4VIDEOEDITING_kAMR_NB: 993 pC->ewc.AudioStreamType = M4SYS_kAMR; 994 pC->ewc.pSilenceFrameData = 995 (M4OSA_UInt8 *)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048; 996 pC->ewc.uiSilenceFrameSize = 997 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE; 998 pC->ewc.iSilenceFrameDuration = 999 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_DURATION; 1000 pC->bSupportSilence = M4OSA_TRUE; 1001 break; 1002 1003 case M4VIDEOEDITING_kAAC: 1004 case M4VIDEOEDITING_kAACplus: 1005 case M4VIDEOEDITING_keAACplus: 1006 pC->ewc.AudioStreamType = M4SYS_kAAC; 1007 1008 if( pC->ewc.uiNbChannels == 1 ) 1009 { 1010 pC->ewc.pSilenceFrameData = 1011 (M4OSA_UInt8 *)M4VSS3GPP_AAC_AU_SILENCE_MONO; 1012 pC->ewc.uiSilenceFrameSize = M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE; 1013 pC->bSupportSilence = M4OSA_TRUE; 1014 } 1015 else 1016 { 1017 pC->ewc.pSilenceFrameData = 1018 (M4OSA_UInt8 *)M4VSS3GPP_AAC_AU_SILENCE_STEREO; 1019 pC->ewc.uiSilenceFrameSize = 1020 M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE; 1021 pC->bSupportSilence = M4OSA_TRUE; 1022 } 1023 pC->ewc.iSilenceFrameDuration = 1024 1024; /* AAC is always 1024/Freq sample duration */ 1025 break; 1026 1027 case M4VIDEOEDITING_kMP3: 1028 pC->ewc.AudioStreamType = M4SYS_kMP3; 1029 pC->ewc.pSilenceFrameData = M4OSA_NULL; 1030 pC->ewc.uiSilenceFrameSize = 0; 1031 pC->ewc.iSilenceFrameDuration = 0; 1032 /* Special case, mp3 core reader return a time in ms */ 1033 pC->ewc.scale_audio = 1.0; 1034 break; 1035 1036 case M4VIDEOEDITING_kEVRC: 1037 pC->ewc.AudioStreamType = M4SYS_kEVRC; 1038 pC->ewc.pSilenceFrameData = M4OSA_NULL; 1039 pC->ewc.uiSilenceFrameSize = 0; 1040 pC->ewc.iSilenceFrameDuration = 160; /* EVRC frames are 20 ms at 8000 Hz 1041 (makes it easier to factorize amr and evrc code) */ 1042 break; 1043 1044 default: 1045 pC->ewc.AudioStreamType = M4SYS_kAudioUnknown; 1046 break; 1047 } 1048 1049 for (i=0; i<pC->uiClipNumber; i++) { 1050 if ((pC->pClipList[i].ClipProperties.VideoStreamType != 1051 pC->xVSS.outputVideoFormat)|| 1052 (pC->pClipList[i].ClipProperties.uiVideoWidth != 1053 pC->ewc.uiVideoWidth) || 1054 (pC->pClipList[i].ClipProperties.uiVideoHeight != 1055 pC->ewc.uiVideoHeight) || 1056 (pC->pClipList[i].ClipProperties.VideoStreamType == 1057 M4VIDEOEDITING_kH264) || 1058 (pC->pClipList[i].ClipProperties.VideoStreamType == 1059 M4VIDEOEDITING_kMPEG4 && 1060 pC->pClipList[i].ClipProperties.uiVideoTimeScale != 1061 pC->ewc.uiVideoTimeScale)) { 1062 pC->pClipList[i].bTranscodingRequired = M4OSA_TRUE; 1063 } 1064 } 1065 /** 1066 * We produce a 3gpp file, unless it is mp3 */ 1067 if( M4VIDEOEDITING_kMP3 == pC-> 1068 pClipList[pSettings->uiMasterClip].ClipProperties.AudioStreamType ) 1069 outputFileType = M4VIDEOEDITING_kFileType_MP3; 1070 else 1071 outputFileType = M4VIDEOEDITING_kFileType_3GPP; 1072 1073 /** 1074 * Beware, a null duration would lead to a divide by zero error (better safe than sorry...) */ 1075 if( 0 == pC->ewc.iOutputDuration ) 1076 { 1077 pC->ewc.iOutputDuration = 1; 1078 } 1079 1080 /** 1081 * Open first clip */ 1082 pC->uiCurrentClip = 0; 1083 1084 // Decorrelate input and output encoding timestamp to handle encoder prefetch 1085 pC->ewc.dInputVidCts = 0.0; 1086 pC->ewc.dOutputVidCts = 0.0; 1087 pC->ewc.dATo = 0.0; 1088 1089 err = M4VSS3GPP_intSwitchToNextClip(pC); 1090 /* RC: to know when a file has been processed */ 1091 if( M4NO_ERROR != err && err != M4VSS3GPP_WAR_SWITCH_CLIP ) 1092 { 1093 M4OSA_TRACE1_1( 1094 "M4VSS3GPP_editOpen: M4VSS3GPP_intSwitchToNextClip() returns 0x%x!", 1095 err); 1096 return err; 1097 } 1098 1099 /** 1100 * Do the video stuff in 3GPP Audio/Video case */ 1101 if( M4VIDEOEDITING_kFileType_3GPP == outputFileType ) 1102 { 1103 /** 1104 * Compute the Decoder Specific Info for the output video and audio streams */ 1105 err = M4VSS3GPP_intComputeOutputVideoAndAudioDsi(pC, 1106 pSettings->uiMasterClip); 1107 1108 if( M4NO_ERROR != err ) 1109 { 1110 M4OSA_TRACE1_1( 1111 "M4VSS3GPP_editOpen: M4VSS3GPP_intComputeOutputVideoAndAudioDsi() returns 0x%x!", 1112 err); 1113 return err; 1114 } 1115 1116 /** 1117 * Compute the time increment for the transition file */ 1118 switch( pSettings->videoFrameRate ) 1119 { 1120 case M4VIDEOEDITING_k5_FPS: 1121 pC->dOutputFrameDuration = 1000.0 / 5.0; 1122 break; 1123 1124 case M4VIDEOEDITING_k7_5_FPS: 1125 pC->dOutputFrameDuration = 1000.0 / 7.5; 1126 break; 1127 1128 case M4VIDEOEDITING_k10_FPS: 1129 pC->dOutputFrameDuration = 1000.0 / 10.0; 1130 break; 1131 1132 case M4VIDEOEDITING_k12_5_FPS: 1133 pC->dOutputFrameDuration = 1000.0 / 12.5; 1134 break; 1135 1136 case M4VIDEOEDITING_k15_FPS: 1137 pC->dOutputFrameDuration = 1000.0 / 15.0; 1138 break; 1139 1140 case M4VIDEOEDITING_k20_FPS: 1141 pC->dOutputFrameDuration = 1000.0 / 20.0; 1142 break; 1143 1144 case M4VIDEOEDITING_k25_FPS: 1145 pC->dOutputFrameDuration = 1000.0 / 25.0; 1146 break; 1147 1148 case M4VIDEOEDITING_k30_FPS: 1149 pC->dOutputFrameDuration = 1000.0 / 30.0; 1150 break; 1151 1152 default: 1153 M4OSA_TRACE1_1( 1154 "M4VSS3GPP_editOpen(): invalid videoFrameRate (0x%x),\ 1155 returning M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE", 1156 pSettings->videoFrameRate); 1157 return M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE; 1158 } 1159 1160 if( M4SYS_kMPEG_4 == pC->ewc.VideoStreamType ) 1161 { 1162 M4OSA_UInt32 uiAlpha; 1163 /** 1164 * MPEG-4 case. 1165 * Time scale of the transition encoder must be the same than the 1166 * timescale of the input files. 1167 * So the frame duration must be compatible with this time scale, 1168 * but without beeing too short. 1169 * For that, we must compute alpha (integer) so that: 1170 * (alpha x 1000)/EncoderTimeScale > MinFrameDuration 1171 **/ 1172 1173 uiAlpha = (M4OSA_UInt32)(( pC->dOutputFrameDuration 1174 * pC->ewc.uiVideoTimeScale) / 1000.0 + 0.5); 1175 1176 if( uiAlpha > 0 ) 1177 { 1178 pC->dOutputFrameDuration = 1179 ( uiAlpha * 1000.0) / pC->ewc.uiVideoTimeScale; 1180 } 1181 } 1182 else if( M4SYS_kH263 == pC->ewc.VideoStreamType ) 1183 { 1184 switch( pSettings->videoFrameRate ) 1185 { 1186 case M4VIDEOEDITING_k12_5_FPS: 1187 case M4VIDEOEDITING_k20_FPS: 1188 case M4VIDEOEDITING_k25_FPS: 1189 M4OSA_TRACE1_0( 1190 "M4VSS3GPP_editOpen(): invalid videoFrameRate for H263,\ 1191 returning M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE"); 1192 return M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE; 1193 default: 1194 break; 1195 } 1196 } 1197 } 1198 1199 /** 1200 * Create the MP3 output file */ 1201 if( M4VIDEOEDITING_kFileType_MP3 == outputFileType ) 1202 { 1203 M4READER_Buffer mp3tagBuffer; 1204 err = M4VSS3GPP_intCreateMP3OutputFile(pC, pSettings->pOutputFile); 1205 1206 if( M4NO_ERROR != err ) 1207 { 1208 M4OSA_TRACE1_1( 1209 "M4VSS3GPP_editOpen: M4VSS3GPP_intCreateMP3OutputFile returns 0x%x", 1210 err); 1211 return err; 1212 } 1213 1214 /* The ID3v2 tag could be at any place in the mp3 file */ 1215 /* The mp3 reader only checks few bytes in the beginning of 1216 stream to look for a ID3v2 tag */ 1217 /* It means that if the ID3v2 tag is not at the beginning of the file the reader do 1218 as there is no these metadata */ 1219 1220 /* Retrieve the data of the ID3v2 Tag */ 1221 err = pC->pC1->ShellAPI.m_pReader->m_pFctGetOption( 1222 pC->pC1->pReaderContext, M4READER_kOptionID_Mp3Id3v2Tag, 1223 (M4OSA_DataOption) &mp3tagBuffer); 1224 1225 if( M4NO_ERROR != err ) 1226 { 1227 M4OSA_TRACE1_1("M4VSS3GPP_editOpen: M4MP3R_getOption returns 0x%x", 1228 err); 1229 return err; 1230 } 1231 1232 /* Write the data of the ID3v2 Tag in the output file */ 1233 if( 0 != mp3tagBuffer.m_uiBufferSize ) 1234 { 1235 err = pC->pOsaFileWritPtr->writeData(pC->ewc.p3gpWriterContext, 1236 (M4OSA_MemAddr8)mp3tagBuffer.m_pData, mp3tagBuffer.m_uiBufferSize); 1237 1238 /** 1239 * Free before the error checking anyway */ 1240 free(mp3tagBuffer.m_pData); 1241 1242 /** 1243 * Error checking */ 1244 if( M4NO_ERROR != err ) 1245 { 1246 M4OSA_TRACE1_1( 1247 "M4VSS3GPP_editOpen: WriteData(ID3v2Tag) returns 0x%x", 1248 err); 1249 return err; 1250 } 1251 1252 mp3tagBuffer.m_uiBufferSize = 0; 1253 mp3tagBuffer.m_pData = M4OSA_NULL; 1254 } 1255 } 1256 /** 1257 * Create the 3GPP output file */ 1258 else if( M4VIDEOEDITING_kFileType_3GPP == outputFileType ) 1259 { 1260 pC->ewc.uiVideoBitrate = pSettings->xVSS.outputVideoBitrate; 1261 1262 /** 1263 * 11/12/2008 CR3283 MMS use case in VideoArtist: Set max output file size if needed */ 1264 if( pC->bIsMMS == M4OSA_TRUE ) 1265 { 1266 err = M4VSS3GPP_intCreate3GPPOutputFile(&pC->ewc, &pC->ShellAPI, 1267 pC->pOsaFileWritPtr, pSettings->pOutputFile, 1268 pC->pOsaFileReadPtr, pSettings->pTemporaryFile, 1269 pSettings->xVSS.outputFileSize); 1270 } 1271 else 1272 { 1273 err = M4VSS3GPP_intCreate3GPPOutputFile(&pC->ewc, &pC->ShellAPI, 1274 pC->pOsaFileWritPtr, pSettings->pOutputFile, 1275 pC->pOsaFileReadPtr, pSettings->pTemporaryFile, 0); 1276 } 1277 1278 if( M4NO_ERROR != err ) 1279 { 1280 M4OSA_TRACE1_1( 1281 "M4VSS3GPP_editOpen: M4VSS3GPP_intCreate3GPPOutputFile returns 0x%x", 1282 err); 1283 return err; 1284 } 1285 } 1286 /** 1287 * Default error case */ 1288 else 1289 { 1290 M4OSA_TRACE1_1( 1291 "M4VSS3GPP_editOpen: invalid outputFileType = 0x%x,\ 1292 returning M4VSS3GPP_ERR_OUTPUT_FILE_TYPE_ERROR", 1293 outputFileType); 1294 return 1295 M4VSS3GPP_ERR_OUTPUT_FILE_TYPE_ERROR; /**< this is an internal error code 1296 unknown to the user */ 1297 } 1298 1299 /** 1300 * Initialize state */ 1301 if( M4SYS_kMP3 == pC->ewc.AudioStreamType ) 1302 { 1303 /** 1304 * In the MP3 case we use a special audio state */ 1305 pC->State = M4VSS3GPP_kEditState_MP3_JUMP; 1306 } 1307 else 1308 { 1309 /** 1310 * We start with the video processing */ 1311 pC->State = M4VSS3GPP_kEditState_VIDEO; 1312 } 1313 1314 /** 1315 * Initialize state. 1316 * The first clip is independant to the "virtual previous clips", 1317 * so it's like if we where in Read/Write mode before it. */ 1318 pC->Vstate = M4VSS3GPP_kEditVideoState_READ_WRITE; 1319 pC->Astate = M4VSS3GPP_kEditAudioState_READ_WRITE; 1320 1321 /** 1322 * Return with no error */ 1323 M4OSA_TRACE3_0("M4VSS3GPP_editOpen(): returning M4NO_ERROR"); 1324 return M4NO_ERROR; 1325} 1326 1327/** 1328 ****************************************************************************** 1329 * M4OSA_ERR M4VSS3GPP_editStep() 1330 * @brief Perform one step of editing. 1331 * @note 1332 * @param pContext (IN) VSS 3GPP edit context 1333 * @param pProgress (OUT) Progress percentage (0 to 100) of the editing operation 1334 * @return M4NO_ERROR: No error 1335 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) 1336 * @return M4ERR_STATE: VSS 3GPP is not in an appropriate state for this 1337 * function to be called 1338 * @return M4VSS3GPP_WAR_EDITING_DONE: Edition is done, user should now call 1339 * M4VSS3GPP_editClose() 1340 ****************************************************************************** 1341 */ 1342M4OSA_ERR M4VSS3GPP_editStep( M4VSS3GPP_EditContext pContext, 1343 M4OSA_UInt8 *pProgress ) 1344{ 1345 M4VSS3GPP_InternalEditContext *pC = 1346 (M4VSS3GPP_InternalEditContext *)pContext; 1347 M4OSA_UInt32 uiProgressAudio, uiProgressVideo, uiProgress; 1348 M4OSA_ERR err; 1349 1350 M4OSA_TRACE3_1("M4VSS3GPP_editStep called with pContext=0x%x", pContext); 1351 1352 /** 1353 * Check input parameter */ 1354 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 1355 "M4VSS3GPP_editStep: pContext is M4OSA_NULL"); 1356 M4OSA_DEBUG_IF2((M4OSA_NULL == pProgress), M4ERR_PARAMETER, 1357 "M4VSS3GPP_editStep: pProgress is M4OSA_NULL"); 1358 1359 /** 1360 * Check state automaton and select correct processing */ 1361 switch( pC->State ) 1362 { 1363 case M4VSS3GPP_kEditState_VIDEO: 1364 err = M4VSS3GPP_intEditStepVideo(pC); 1365 break; 1366 1367 case M4VSS3GPP_kEditState_AUDIO: 1368 err = M4VSS3GPP_intEditStepAudio(pC); 1369 break; 1370 1371 case M4VSS3GPP_kEditState_MP3: 1372 err = M4VSS3GPP_intEditStepMP3(pC); 1373 break; 1374 1375 case M4VSS3GPP_kEditState_MP3_JUMP: 1376 err = M4VSS3GPP_intEditJumpMP3(pC); 1377 break; 1378 1379 default: 1380 M4OSA_TRACE1_0( 1381 "M4VSS3GPP_editStep(): invalid internal state (0x%x), returning M4ERR_STATE"); 1382 return M4ERR_STATE; 1383 } 1384 1385 /** 1386 * Compute progress. 1387 * We do the computing with 32bits precision because in some (very) extreme case, we may get 1388 * values higher than 256 (...) */ 1389 uiProgressAudio = 1390 ( (M4OSA_UInt32)(pC->ewc.dATo * 100)) / pC->ewc.iOutputDuration; 1391 // Decorrelate input and output encoding timestamp to handle encoder prefetch 1392 uiProgressVideo = ((M4OSA_UInt32)(pC->ewc.dInputVidCts * 100)) / pC->ewc.iOutputDuration; 1393 1394 uiProgress = uiProgressAudio + uiProgressVideo; 1395 1396 if( ( pC->ewc.AudioStreamType != M4SYS_kAudioUnknown) 1397 && (pC->ewc.VideoStreamType != M4SYS_kVideoUnknown) ) 1398 uiProgress /= 2; 1399 1400 /** 1401 * Sanity check */ 1402 if( uiProgress > 100 ) 1403 { 1404 *pProgress = 100; 1405 } 1406 else 1407 { 1408 *pProgress = (M4OSA_UInt8)uiProgress; 1409 } 1410 1411 /** 1412 * Return the error */ 1413 M4OSA_TRACE3_1("M4VSS3GPP_editStep(): returning 0x%x", err); 1414 return err; 1415} 1416 1417/** 1418 ****************************************************************************** 1419 * M4OSA_ERR M4VSS3GPP_editClose() 1420 * @brief Finish the VSS edit operation. 1421 * @note The output 3GPP file is ready to be played after this call 1422 * @param pContext (IN) VSS edit context 1423 * @return M4NO_ERROR: No error 1424 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) 1425 * @return M4ERR_STATE: VSS is not in an appropriate state for this function to be called 1426 ****************************************************************************** 1427 */ 1428M4OSA_ERR M4VSS3GPP_editClose( M4VSS3GPP_EditContext pContext ) 1429{ 1430 M4VSS3GPP_InternalEditContext *pC = 1431 (M4VSS3GPP_InternalEditContext *)pContext; 1432 M4OSA_ERR err; 1433 M4OSA_ERR returnedError = M4NO_ERROR; 1434 M4OSA_UInt32 lastCTS; 1435 1436 M4OSA_TRACE3_1("M4VSS3GPP_editClose called with pContext=0x%x", pContext); 1437 1438 /** 1439 * Check input parameter */ 1440 M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, 1441 "M4VSS3GPP_editClose: pContext is M4OSA_NULL"); 1442 1443 /** 1444 * Check state automaton. 1445 * In "theory", we should not authorize closing if we are in CREATED state. 1446 * But in practice, in case the opening failed, it may have been partially done. 1447 * In that case we have to free some opened ressources by calling Close. */ 1448 if( M4VSS3GPP_kEditState_CLOSED == pC->State ) 1449 { 1450 M4OSA_TRACE1_1( 1451 "M4VSS3GPP_editClose: Wrong state (0x%x), returning M4ERR_STATE", 1452 pC->State); 1453 return M4ERR_STATE; 1454 } 1455 1456 /** 1457 * There may be an encoder to destroy */ 1458 err = M4VSS3GPP_intDestroyVideoEncoder(pC); 1459 1460 if( M4NO_ERROR != err ) 1461 { 1462 M4OSA_TRACE1_1( 1463 "M4VSS3GPP_editClose: M4VSS3GPP_editDestroyVideoEncoder() returns 0x%x!", 1464 err); 1465 /**< We do not return the error here because we still have stuff to free */ 1466 returnedError = err; 1467 } 1468 1469 /** 1470 * Close the output file */ 1471 if( M4SYS_kMP3 == pC->ewc.AudioStreamType ) 1472 { 1473 /** 1474 * MP3 case */ 1475 if( M4OSA_NULL != pC->ewc.p3gpWriterContext ) 1476 { 1477 err = pC->pOsaFileWritPtr->closeWrite(pC->ewc.p3gpWriterContext); 1478 pC->ewc.p3gpWriterContext = M4OSA_NULL; 1479 } 1480 } 1481 else 1482 { 1483 /** 1484 * Close the output 3GPP clip, if it has been opened */ 1485 if( M4OSA_NULL != pC->ewc.p3gpWriterContext ) 1486 { 1487 /* Update last Video CTS */ 1488 lastCTS = pC->ewc.iOutputDuration; 1489 1490 err = pC->ShellAPI.pWriterGlobalFcts->pFctSetOption( 1491 pC->ewc.p3gpWriterContext, 1492 (M4OSA_UInt32)M4WRITER_kMaxFileDuration, &lastCTS); 1493 1494 if( M4NO_ERROR != err ) 1495 { 1496 M4OSA_TRACE1_1( 1497 "M4VSS3GPP_editClose: SetOption(M4WRITER_kMaxFileDuration) returns 0x%x", 1498 err); 1499 } 1500 1501 err = pC->ShellAPI.pWriterGlobalFcts->pFctCloseWrite( 1502 pC->ewc.p3gpWriterContext); 1503 1504 if( M4NO_ERROR != err ) 1505 { 1506 M4OSA_TRACE1_1( 1507 "M4VSS3GPP_editClose: pFctCloseWrite(OUT) returns 0x%x!", 1508 err); 1509 /**< We do not return the error here because we still have stuff to free */ 1510 if( M4NO_ERROR 1511 == returnedError ) /**< we return the first error that happened */ 1512 { 1513 returnedError = err; 1514 } 1515 } 1516 pC->ewc.p3gpWriterContext = M4OSA_NULL; 1517 } 1518 } 1519 1520 /** 1521 * Free the output video DSI, if it has been created */ 1522 if( M4OSA_NULL != pC->ewc.pVideoOutputDsi ) 1523 { 1524 free(pC->ewc.pVideoOutputDsi); 1525 pC->ewc.pVideoOutputDsi = M4OSA_NULL; 1526 } 1527 1528 /** 1529 * Free the output audio DSI, if it has been created */ 1530 if( M4OSA_NULL != pC->ewc.pAudioOutputDsi ) 1531 { 1532 free(pC->ewc.pAudioOutputDsi); 1533 pC->ewc.pAudioOutputDsi = M4OSA_NULL; 1534 } 1535 1536 /** 1537 * Close clip1, if needed */ 1538 if( M4OSA_NULL != pC->pC1 ) 1539 { 1540 err = M4VSS3GPP_intClipCleanUp(pC->pC1); 1541 1542 if( M4NO_ERROR != err ) 1543 { 1544 M4OSA_TRACE1_1( 1545 "M4VSS3GPP_editClose: M4VSS3GPP_intClipCleanUp(C1) returns 0x%x!", 1546 err); 1547 /**< We do not return the error here because we still have stuff to free */ 1548 if( M4NO_ERROR 1549 == returnedError ) /**< we return the first error that happened */ 1550 { 1551 returnedError = err; 1552 } 1553 } 1554 pC->pC1 = M4OSA_NULL; 1555 } 1556 1557 /** 1558 * Close clip2, if needed */ 1559 if( M4OSA_NULL != pC->pC2 ) 1560 { 1561 err = M4VSS3GPP_intClipCleanUp(pC->pC2); 1562 1563 if( M4NO_ERROR != err ) 1564 { 1565 M4OSA_TRACE1_1( 1566 "M4VSS3GPP_editClose: M4VSS3GPP_intClipCleanUp(C2) returns 0x%x!", 1567 err); 1568 /**< We do not return the error here because we still have stuff to free */ 1569 if( M4NO_ERROR 1570 == returnedError ) /**< we return the first error that happened */ 1571 { 1572 returnedError = err; 1573 } 1574 } 1575 pC->pC2 = M4OSA_NULL; 1576 } 1577 1578 /** 1579 * Free the temporary YUV planes */ 1580 if( M4OSA_NULL != pC->yuv1[0].pac_data ) 1581 { 1582 free(pC->yuv1[0].pac_data); 1583 pC->yuv1[0].pac_data = M4OSA_NULL; 1584 } 1585 1586 if( M4OSA_NULL != pC->yuv1[1].pac_data ) 1587 { 1588 free(pC->yuv1[1].pac_data); 1589 pC->yuv1[1].pac_data = M4OSA_NULL; 1590 } 1591 1592 if( M4OSA_NULL != pC->yuv1[2].pac_data ) 1593 { 1594 free(pC->yuv1[2].pac_data); 1595 pC->yuv1[2].pac_data = M4OSA_NULL; 1596 } 1597 1598 if( M4OSA_NULL != pC->yuv2[0].pac_data ) 1599 { 1600 free(pC->yuv2[0].pac_data); 1601 pC->yuv2[0].pac_data = M4OSA_NULL; 1602 } 1603 1604 if( M4OSA_NULL != pC->yuv2[1].pac_data ) 1605 { 1606 free(pC->yuv2[1].pac_data); 1607 pC->yuv2[1].pac_data = M4OSA_NULL; 1608 } 1609 1610 if( M4OSA_NULL != pC->yuv2[2].pac_data ) 1611 { 1612 free(pC->yuv2[2].pac_data); 1613 pC->yuv2[2].pac_data = M4OSA_NULL; 1614 } 1615 1616 /* RC */ 1617 if( M4OSA_NULL != pC->yuv3[0].pac_data ) 1618 { 1619 free(pC->yuv3[0].pac_data); 1620 pC->yuv3[0].pac_data = M4OSA_NULL; 1621 } 1622 1623 if( M4OSA_NULL != pC->yuv3[1].pac_data ) 1624 { 1625 free(pC->yuv3[1].pac_data); 1626 pC->yuv3[1].pac_data = M4OSA_NULL; 1627 } 1628 1629 if( M4OSA_NULL != pC->yuv3[2].pac_data ) 1630 { 1631 free(pC->yuv3[2].pac_data); 1632 pC->yuv3[2].pac_data = M4OSA_NULL; 1633 } 1634 1635 /* RC */ 1636 if( M4OSA_NULL != pC->yuv4[0].pac_data ) 1637 { 1638 free(pC->yuv4[0].pac_data); 1639 pC->yuv4[0].pac_data = M4OSA_NULL; 1640 } 1641 1642 if( M4OSA_NULL != pC->yuv4[1].pac_data ) 1643 { 1644 free(pC->yuv4[1].pac_data); 1645 pC->yuv4[1].pac_data = M4OSA_NULL; 1646 } 1647 1648 if( M4OSA_NULL != pC->yuv4[2].pac_data ) 1649 { 1650 free(pC->yuv4[2].pac_data); 1651 pC->yuv4[2].pac_data = M4OSA_NULL; 1652 } 1653 1654 /** 1655 * RC Free effects list */ 1656 if( pC->pEffectsList != M4OSA_NULL ) 1657 { 1658 free(pC->pEffectsList); 1659 pC->pEffectsList = M4OSA_NULL; 1660 } 1661 1662 /** 1663 * RC Free active effects list */ 1664 if( pC->pActiveEffectsList != M4OSA_NULL ) 1665 { 1666 free(pC->pActiveEffectsList); 1667 pC->pActiveEffectsList = M4OSA_NULL; 1668 } 1669 /** 1670 * Free active effects list */ 1671 if(pC->pActiveEffectsList1 != M4OSA_NULL) 1672 { 1673 free(pC->pActiveEffectsList1); 1674 pC->pActiveEffectsList1 = M4OSA_NULL; 1675 } 1676 if(pC->m_air_context != M4OSA_NULL) { 1677 free(pC->m_air_context); 1678 pC->m_air_context = M4OSA_NULL; 1679 } 1680 /** 1681 * Update state automaton */ 1682 pC->State = M4VSS3GPP_kEditState_CLOSED; 1683 1684 /** 1685 * Return with no error */ 1686 M4OSA_TRACE3_1("M4VSS3GPP_editClose(): returning 0x%x", returnedError); 1687 return returnedError; 1688} 1689 1690/** 1691 ****************************************************************************** 1692 * M4OSA_ERR M4VSS3GPP_editCleanUp() 1693 * @brief Free all resources used by the VSS edit operation. 1694 * @note The context is no more valid after this call 1695 * @param pContext (IN) VSS edit context 1696 * @return M4NO_ERROR: No error 1697 * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) 1698 ****************************************************************************** 1699 */ 1700M4OSA_ERR M4VSS3GPP_editCleanUp( M4VSS3GPP_EditContext pContext ) 1701{ 1702 M4OSA_ERR err; 1703 M4VSS3GPP_InternalEditContext *pC = 1704 (M4VSS3GPP_InternalEditContext *)pContext; 1705 1706 M4OSA_TRACE3_1("M4VSS3GPP_editCleanUp called with pContext=0x%x", pContext); 1707 1708 /** 1709 * Check input parameter */ 1710 if( M4OSA_NULL == pContext ) 1711 { 1712 M4OSA_TRACE1_0( 1713 "M4VSS3GPP_editCleanUp(): pContext is M4OSA_NULL, returning M4ERR_PARAMETER"); 1714 return M4ERR_PARAMETER; 1715 } 1716 1717 /** 1718 * Close, if needed. 1719 * In "theory", we should not close if we are in CREATED state. 1720 * But in practice, in case the opening failed, it may have been partially done. 1721 * In that case we have to free some opened ressources by calling Close. */ 1722 if( M4VSS3GPP_kEditState_CLOSED != pC->State ) 1723 { 1724 M4OSA_TRACE3_0("M4VSS3GPP_editCleanUp(): calling M4VSS3GPP_editClose"); 1725 err = M4VSS3GPP_editClose(pC); 1726 1727 if( M4NO_ERROR != err ) 1728 { 1729 M4OSA_TRACE1_1( 1730 "M4VSS3GPP_editCleanUp(): M4VSS3GPP_editClose returns 0x%x", 1731 err); 1732 } 1733 } 1734 1735 /** 1736 * Free the video encoder dummy AU */ 1737 if( M4OSA_NULL != pC->ewc.pDummyAuBuffer ) 1738 { 1739 free(pC->ewc.pDummyAuBuffer); 1740 pC->ewc.pDummyAuBuffer = M4OSA_NULL; 1741 } 1742 1743 /** 1744 * Free the Audio encoder context */ 1745 if( M4OSA_NULL != pC->ewc.pAudioEncCtxt ) 1746 { 1747 err = pC->ShellAPI.pAudioEncoderGlobalFcts->pFctClose( 1748 pC->ewc.pAudioEncCtxt); 1749 1750 if( M4NO_ERROR != err ) 1751 { 1752 M4OSA_TRACE1_1( 1753 "M4VSS3GPP_editCleanUp: pAudioEncoderGlobalFcts->pFctClose returns 0x%x", 1754 err); 1755 /**< don't return, we still have stuff to free */ 1756 } 1757 1758 err = pC->ShellAPI.pAudioEncoderGlobalFcts->pFctCleanUp( 1759 pC->ewc.pAudioEncCtxt); 1760 1761 if( M4NO_ERROR != err ) 1762 { 1763 M4OSA_TRACE1_1( 1764 "M4VSS3GPP_editCleanUp: pAudioEncoderGlobalFcts->pFctCleanUp returns 0x%x", 1765 err); 1766 /**< don't return, we still have stuff to free */ 1767 } 1768 1769 pC->ewc.pAudioEncCtxt = M4OSA_NULL; 1770 } 1771 1772 /** 1773 * Free the shells interfaces */ 1774 M4VSS3GPP_unRegisterAllWriters(&pC->ShellAPI); 1775 M4VSS3GPP_unRegisterAllEncoders(&pC->ShellAPI); 1776 M4VSS3GPP_unRegisterAllReaders(&pC->ShellAPI); 1777 M4VSS3GPP_unRegisterAllDecoders(&pC->ShellAPI); 1778 1779 /** 1780 * Free the settings copied in the internal context */ 1781 M4VSS3GPP_intFreeSettingsList(pC); 1782 1783 /** 1784 * Finally, Free context */ 1785 free(pC); 1786 pC = M4OSA_NULL; 1787 1788 /** 1789 * Return with no error */ 1790 M4OSA_TRACE3_0("M4VSS3GPP_editCleanUp(): returning M4NO_ERROR"); 1791 return M4NO_ERROR; 1792} 1793 1794#ifdef WIN32 1795/** 1796 ****************************************************************************** 1797 * M4OSA_ERR M4VSS3GPP_GetErrorMessage() 1798 * @brief Return a string describing the given error code 1799 * @note The input string must be already allocated (and long enough!) 1800 * @param err (IN) Error code to get the description from 1801 * @param sMessage (IN/OUT) Allocated string in which the description will be copied 1802 * @return M4NO_ERROR: Input error is from the VSS3GPP module 1803 * @return M4ERR_PARAMETER:Input error is not from the VSS3GPP module 1804 ****************************************************************************** 1805 */ 1806 1807M4OSA_ERR M4VSS3GPP_GetErrorMessage( M4OSA_ERR err, M4OSA_Char *sMessage ) 1808{ 1809 switch( err ) 1810 { 1811 case M4VSS3GPP_WAR_EDITING_DONE: 1812 strcpy(sMessage, "M4VSS3GPP_WAR_EDITING_DONE"); 1813 break; 1814 1815 case M4VSS3GPP_WAR_END_OF_AUDIO_MIXING: 1816 strcpy(sMessage, "M4VSS3GPP_WAR_END_OF_AUDIO_MIXING"); 1817 break; 1818 1819 case M4VSS3GPP_WAR_END_OF_EXTRACT_PICTURE: 1820 strcpy(sMessage, "M4VSS3GPP_WAR_END_OF_EXTRACT_PICTURE"); 1821 break; 1822 1823 case M4VSS3GPP_ERR_INVALID_FILE_TYPE: 1824 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_FILE_TYPE"); 1825 break; 1826 1827 case M4VSS3GPP_ERR_INVALID_EFFECT_KIND: 1828 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_EFFECT_KIND"); 1829 break; 1830 1831 case M4VSS3GPP_ERR_INVALID_VIDEO_EFFECT_TYPE: 1832 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_VIDEO_EFFECT_TYPE"); 1833 break; 1834 1835 case M4VSS3GPP_ERR_INVALID_AUDIO_EFFECT_TYPE: 1836 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_AUDIO_EFFECT_TYPE"); 1837 break; 1838 1839 case M4VSS3GPP_ERR_INVALID_VIDEO_TRANSITION_TYPE: 1840 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_VIDEO_TRANSITION_TYPE"); 1841 break; 1842 1843 case M4VSS3GPP_ERR_INVALID_AUDIO_TRANSITION_TYPE: 1844 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_AUDIO_TRANSITION_TYPE"); 1845 break; 1846 1847 case M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE: 1848 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE"); 1849 break; 1850 1851 case M4VSS3GPP_ERR_EXTERNAL_EFFECT_NULL: 1852 strcpy(sMessage, "M4VSS3GPP_ERR_EXTERNAL_EFFECT_NULL"); 1853 break; 1854 1855 case M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL: 1856 strcpy(sMessage, "M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL"); 1857 break; 1858 1859 case M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION: 1860 strcpy(sMessage, "M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION"); 1861 break; 1862 1863 case M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT: 1864 strcpy(sMessage, "M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT"); 1865 break; 1866 1867 case M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS: 1868 strcpy(sMessage, "M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS"); 1869 break; 1870 1871 case M4VSS3GPP_ERR_INVALID_3GPP_FILE: 1872 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_3GPP_FILE"); 1873 break; 1874 1875 case M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT: 1876 strcpy(sMessage, "M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT"); 1877 break; 1878 1879 case M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT: 1880 strcpy(sMessage, "M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT"); 1881 break; 1882 1883 case M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED: 1884 strcpy(sMessage, "M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED"); 1885 break; 1886 1887 case M4VSS3GPP_ERR_INPUT_VIDEO_AU_TOO_LARGE: 1888 strcpy(sMessage, "M4VSS3GPP_ERR_INPUT_VIDEO_AU_TOO_LARGE"); 1889 break; 1890 1891 case M4VSS3GPP_ERR_INPUT_AUDIO_AU_TOO_LARGE: 1892 strcpy(sMessage, "M4VSS3GPP_ERR_INPUT_AUDIO_AU_TOO_LARGE"); 1893 break; 1894 1895 case M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU: 1896 strcpy(sMessage, "M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU"); 1897 break; 1898 1899 case M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR: 1900 strcpy(sMessage, "M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR"); 1901 break; 1902 1903 case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT: 1904 strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT"); 1905 break; 1906 1907 case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE: 1908 strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE"); 1909 break; 1910 1911 case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE: 1912 strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE"); 1913 break; 1914 1915 case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC: 1916 strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC"); 1917 break; 1918 1919 case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT: 1920 strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT"); 1921 break; 1922 1923 case M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE: 1924 strcpy(sMessage, 1925 "M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE"); 1926 break; 1927 1928 case M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE: 1929 strcpy(sMessage, 1930 "M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE"); 1931 break; 1932 1933 case M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION: 1934 strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION"); 1935 break; 1936 1937 case M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT: 1938 strcpy(sMessage, "M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT"); 1939 break; 1940 1941 case M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE: 1942 strcpy(sMessage, "M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE"); 1943 break; 1944 1945 case M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE: 1946 strcpy(sMessage, "M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE"); 1947 break; 1948 1949 case M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING: 1950 strcpy(sMessage, 1951 "M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING"); 1952 break; 1953 1954 case M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY: 1955 strcpy(sMessage, "M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY"); 1956 break; 1957 1958 case M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_STREAM_TYPE: 1959 strcpy(sMessage, "M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_STREAM_TYPE"); 1960 break; 1961 1962 case M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS: 1963 strcpy(sMessage, "M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS"); 1964 break; 1965 1966 case M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY: 1967 strcpy(sMessage, 1968 "M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY"); 1969 break; 1970 1971 case M4VSS3GPP_ERR_NO_SUPPORTED_STREAM_IN_FILE: 1972 strcpy(sMessage, "M4VSS3GPP_ERR_NO_SUPPORTED_STREAM_IN_FILE"); 1973 break; 1974 1975 case M4VSS3GPP_ERR_ADDVOLUME_EQUALS_ZERO: 1976 strcpy(sMessage, "M4VSS3GPP_ERR_ADDVOLUME_EQUALS_ZERO"); 1977 break; 1978 1979 case M4VSS3GPP_ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION: 1980 strcpy(sMessage, "M4VSS3GPP_ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION"); 1981 break; 1982 1983 case M4VSS3GPP_ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT: 1984 strcpy(sMessage, "M4VSS3GPP_ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT"); 1985 break; 1986 1987 case M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM: 1988 strcpy(sMessage, "M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM"); 1989 break; 1990 1991 case M4VSS3GPP_ERR_AUDIO_MIXING_UNSUPPORTED: 1992 strcpy(sMessage, "M4VSS3GPP_ERR_AUDIO_MIXING_UNSUPPORTED"); 1993 break; 1994 1995 case M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK: 1996 strcpy(sMessage, 1997 "M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK"); 1998 break; 1999 2000 case M4VSS3GPP_ERR_AUDIO_CANNOT_BE_MIXED: 2001 strcpy(sMessage, "M4VSS3GPP_ERR_AUDIO_CANNOT_BE_MIXED"); 2002 break; 2003 2004 case M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP: 2005 strcpy(sMessage, "M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP"); 2006 break; 2007 2008 case M4VSS3GPP_ERR_BEGINLOOP_HIGHER_ENDLOOP: 2009 strcpy(sMessage, "M4VSS3GPP_ERR_BEGINLOOP_HIGHER_ENDLOOP"); 2010 break; 2011 2012 case M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED: 2013 strcpy(sMessage, "M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED"); 2014 break; 2015 2016 case M4VSS3GPP_ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE: 2017 strcpy(sMessage, "M4VSS3GPP_ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE"); 2018 break; 2019 2020 default: /**< Not a VSS3GPP error */ 2021 strcpy(sMessage, ""); 2022 return M4ERR_PARAMETER; 2023 } 2024 return M4NO_ERROR; 2025} 2026 2027#endif /* WIN32 */ 2028 2029/********************************************************/ 2030/********************************************************/ 2031/********************************************************/ 2032/**************** STATIC FUNCTIONS ******************/ 2033/********************************************************/ 2034/********************************************************/ 2035/********************************************************/ 2036 2037/** 2038 ****************************************************************************** 2039 * M4OSA_ERR M4VSS3GPP_intClipSettingsSanityCheck() 2040 * @brief Simplify the given clip settings 2041 * @note This function may modify the given structure 2042 * @param pClip (IN/OUT) Clip settings 2043 * @return M4NO_ERROR: No error 2044 * @return M4VSS3GPP_ERR_EXTERNAL_EFFECT_NULL: 2045 ****************************************************************************** 2046 */ 2047 2048static M4OSA_ERR M4VSS3GPP_intClipSettingsSanityCheck( 2049 M4VSS3GPP_ClipSettings *pClip ) 2050{ 2051 M4OSA_UInt8 uiFx; 2052 M4OSA_UInt32 2053 uiClipActualDuration; /**< the clip duration once the cuts are done */ 2054 M4OSA_UInt32 uiDuration; 2055 M4VSS3GPP_EffectSettings *pFx; 2056 2057 /** 2058 * If begin cut is too far, return an error */ 2059 uiDuration = pClip->ClipProperties.uiClipDuration; 2060 2061 if( pClip->uiBeginCutTime > uiDuration ) 2062 { 2063 M4OSA_TRACE1_2( 2064 "M4VSS3GPP_intClipSettingsSanityCheck: %d > %d,\ 2065 returning M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION", 2066 pClip->uiBeginCutTime, uiDuration); 2067 return M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION; 2068 } 2069 2070 /** 2071 * If end cut is too far, set to zero (it means no end cut) */ 2072 if( pClip->uiEndCutTime > uiDuration ) 2073 { 2074 pClip->uiEndCutTime = 0; 2075 } 2076 2077 /** 2078 * Compute actual clip duration (once cuts are done) */ 2079 if( 0 == pClip->uiEndCutTime ) 2080 { 2081 /** 2082 * No end cut */ 2083 uiClipActualDuration = uiDuration - pClip->uiBeginCutTime; 2084 } 2085 else 2086 { 2087 if( pClip->uiBeginCutTime >= pClip->uiEndCutTime ) 2088 { 2089 M4OSA_TRACE1_2( 2090 "M4VSS3GPP_intClipSettingsSanityCheck: %d > %d,\ 2091 returning M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT", 2092 pClip->uiBeginCutTime, pClip->uiEndCutTime); 2093 return M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT; 2094 } 2095 uiClipActualDuration = pClip->uiEndCutTime - pClip->uiBeginCutTime; 2096 } 2097 2098 return M4NO_ERROR; 2099} 2100 2101/** 2102 ****************************************************************************** 2103 * M4OSA_ERR M4VSS3GPP_intTransitionSettingsSanityCheck() 2104 * @brief Simplify the given transition settings 2105 * @note This function may modify the given structure 2106 * @param pTransition (IN/OUT) Transition settings 2107 * @return M4NO_ERROR: No error 2108 * @return M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL: 2109 ****************************************************************************** 2110 */ 2111static M4OSA_ERR M4VSS3GPP_intTransitionSettingsSanityCheck( 2112 M4VSS3GPP_TransitionSettings *pTransition ) 2113{ 2114 /** 2115 * No transition */ 2116 if( 0 == pTransition->uiTransitionDuration ) 2117 { 2118 pTransition->VideoTransitionType = M4VSS3GPP_kVideoTransitionType_None; 2119 pTransition->AudioTransitionType = M4VSS3GPP_kAudioTransitionType_None; 2120 } 2121 else if( ( M4VSS3GPP_kVideoTransitionType_None 2122 == pTransition->VideoTransitionType) 2123 && (M4VSS3GPP_kAudioTransitionType_None 2124 == pTransition->AudioTransitionType) ) 2125 { 2126 pTransition->uiTransitionDuration = 0; 2127 } 2128 2129 /** 2130 * Check external transition function is set */ 2131 if( ( pTransition->VideoTransitionType 2132 >= M4VSS3GPP_kVideoTransitionType_External) 2133 && (M4OSA_NULL == pTransition->ExtVideoTransitionFct) ) 2134 { 2135 return M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL; 2136 } 2137 2138 /** 2139 * Set minimal transition duration */ 2140 if( ( pTransition->uiTransitionDuration > 0) 2141 && (pTransition->uiTransitionDuration 2142 < M4VSS3GPP_MINIMAL_TRANSITION_DURATION) ) 2143 { 2144 pTransition->uiTransitionDuration = 2145 M4VSS3GPP_MINIMAL_TRANSITION_DURATION; 2146 } 2147 return M4NO_ERROR; 2148} 2149 2150/** 2151 ****************************************************************************** 2152 * M4OSA_ERR M4VSS3GPP_intFreeSettingsList() 2153 * @brief Free the settings copied in the internal context 2154 * @param pC (IN/OUT) Internal edit context 2155 ****************************************************************************** 2156 */ 2157static M4OSA_Void M4VSS3GPP_intFreeSettingsList( 2158 M4VSS3GPP_InternalEditContext *pC ) 2159{ 2160 M4OSA_UInt32 i; 2161 2162 /** 2163 * Free the settings list */ 2164 if( M4OSA_NULL != pC->pClipList ) 2165 { 2166 for ( i = 0; i < pC->uiClipNumber; i++ ) 2167 { 2168 M4VSS3GPP_editFreeClipSettings(&(pC->pClipList[i])); 2169 } 2170 2171 free(pC->pClipList); 2172 pC->pClipList = M4OSA_NULL; 2173 } 2174 2175 /** 2176 * Free the transition list */ 2177 if( M4OSA_NULL != pC->pTransitionList ) 2178 { 2179 free(pC->pTransitionList); 2180 pC->pTransitionList = M4OSA_NULL; 2181 } 2182} 2183/** 2184 ****************************************************************************** 2185 * M4OSA_ERR M4VSS3GPP_intCreateMP3OutputFile() 2186 * @brief Creates and prepare the output MP file 2187 * @param pC (IN/OUT) Internal edit context 2188 ****************************************************************************** 2189 */ 2190static M4OSA_ERR 2191M4VSS3GPP_intCreateMP3OutputFile( M4VSS3GPP_InternalEditContext *pC, 2192 M4OSA_Void *pOutputFile ) 2193{ 2194 M4OSA_ERR err; 2195 2196 err = 2197 pC->pOsaFileWritPtr->openWrite(&pC->ewc.p3gpWriterContext, pOutputFile, 2198 M4OSA_kFileWrite); 2199 2200 if( M4NO_ERROR != err ) 2201 { 2202 M4OSA_TRACE1_1( 2203 "M4VSS3GPP_intCreateMP3OutputFile: WriteOpen returns 0x%x!", err); 2204 return err; 2205 } 2206 2207 return M4NO_ERROR; 2208} 2209/** 2210 ****************************************************************************** 2211 * M4OSA_ERR M4VSS3GPP_intCreate3GPPOutputFile() 2212 * @brief Creates and prepare the output MP3 file 2213 * @note Creates the writer, Creates the output file, Adds the streams, 2214 Readies the writing process 2215 * @param pC (IN/OUT) Internal edit context 2216 ****************************************************************************** 2217 */ 2218M4OSA_ERR 2219M4VSS3GPP_intCreate3GPPOutputFile( M4VSS3GPP_EncodeWriteContext *pC_ewc, 2220 M4VSS3GPP_MediaAndCodecCtxt *pC_ShellAPI, 2221 M4OSA_FileWriterPointer *pOsaFileWritPtr, 2222 M4OSA_Void *pOutputFile, 2223 M4OSA_FileReadPointer *pOsaFileReadPtr, 2224 M4OSA_Void *pTempFile, 2225 M4OSA_UInt32 maxOutputFileSize ) 2226{ 2227 M4OSA_ERR err; 2228 M4OSA_UInt32 uiVersion; 2229 M4SYS_StreamIDValue temp; 2230 2231 M4OSA_TRACE3_2( 2232 "M4VSS3GPP_intCreate3GPPOutputFile called with pC_ewc=0x%x, pOutputFile=0x%x", 2233 pC_ewc, pOutputFile); 2234 2235 /** 2236 * Check input parameter */ 2237 M4OSA_DEBUG_IF2((M4OSA_NULL == pC_ewc), M4ERR_PARAMETER, 2238 "M4VSS3GPP_intCreate3GPPOutputFile: pC_ewc is M4OSA_NULL"); 2239 M4OSA_DEBUG_IF2((M4OSA_NULL == pOutputFile), M4ERR_PARAMETER, 2240 "M4VSS3GPP_intCreate3GPPOutputFile: pOutputFile is M4OSA_NULL"); 2241 2242 /* Set writer */ 2243 err = 2244 M4VSS3GPP_setCurrentWriter(pC_ShellAPI, M4VIDEOEDITING_kFileType_3GPP); 2245 M4ERR_CHECK_RETURN(err); 2246 2247 /** 2248 * Create the output file */ 2249 err = pC_ShellAPI->pWriterGlobalFcts->pFctOpen(&pC_ewc->p3gpWriterContext, 2250 pOutputFile, pOsaFileWritPtr, pTempFile, pOsaFileReadPtr); 2251 2252 if( M4NO_ERROR != err ) 2253 { 2254 M4OSA_TRACE1_1( 2255 "M4VSS3GPP_intCreate3GPPOutputFile: pWriterGlobalFcts->pFctOpen returns 0x%x!", 2256 err); 2257 return err; 2258 } 2259 2260 /** 2261 * Set the signature option of the writer */ 2262 err = 2263 pC_ShellAPI->pWriterGlobalFcts->pFctSetOption(pC_ewc->p3gpWriterContext, 2264 M4WRITER_kEmbeddedString, (M4OSA_DataOption)"NXP-SW : VSS "); 2265 2266 if( ( M4NO_ERROR != err) && (((M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 2267 != err) ) /* this option may not be implemented by some writers */ 2268 { 2269 M4OSA_TRACE1_1( 2270 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2271 pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedString) returns 0x%x!", 2272 err); 2273 return err; 2274 } 2275 2276 /*11/12/2008 CR3283 MMS use case for VideoArtist: 2277 Set the max output file size option in the writer so that the output file will be 2278 smaller than the given file size limitation*/ 2279 if( maxOutputFileSize > 0 ) 2280 { 2281 err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( 2282 pC_ewc->p3gpWriterContext, 2283 M4WRITER_kMaxFileSize, &maxOutputFileSize); 2284 2285 if( M4NO_ERROR != err ) 2286 { 2287 M4OSA_TRACE1_1( 2288 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2289 writer set option M4WRITER_kMaxFileSize returns 0x%x", 2290 err); 2291 return err; 2292 } 2293 } 2294 2295 /** 2296 * Set the version option of the writer */ 2297 uiVersion = 2298 (M4VIDEOEDITING_VERSION_MAJOR * 100 + M4VIDEOEDITING_VERSION_MINOR * 10 2299 + M4VIDEOEDITING_VERSION_REVISION); 2300 err = 2301 pC_ShellAPI->pWriterGlobalFcts->pFctSetOption(pC_ewc->p3gpWriterContext, 2302 M4WRITER_kEmbeddedVersion, (M4OSA_DataOption) &uiVersion); 2303 2304 if( ( M4NO_ERROR != err) && (((M4OSA_UInt32)M4ERR_BAD_OPTION_ID) 2305 != err) ) /* this option may not be implemented by some writers */ 2306 { 2307 M4OSA_TRACE1_1( 2308 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2309 pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedVersion) returns 0x%x!", 2310 err); 2311 return err; 2312 } 2313 2314 if( M4SYS_kVideoUnknown != pC_ewc->VideoStreamType ) 2315 { 2316 /** 2317 * Set the video stream properties */ 2318 pC_ewc->WriterVideoStreamInfo.height = pC_ewc->uiVideoHeight; 2319 pC_ewc->WriterVideoStreamInfo.width = pC_ewc->uiVideoWidth; 2320 pC_ewc->WriterVideoStreamInfo.fps = 2321 0.0; /**< Not used by the shell/core writer */ 2322 pC_ewc->WriterVideoStreamInfo.Header.pBuf = 2323 pC_ewc->pVideoOutputDsi; /**< Previously computed output DSI */ 2324 pC_ewc->WriterVideoStreamInfo.Header.Size = pC_ewc-> 2325 uiVideoOutputDsiSize; /**< Previously computed output DSI size */ 2326 2327 pC_ewc->WriterVideoStream.streamType = pC_ewc->VideoStreamType; 2328 2329 switch( pC_ewc->VideoStreamType ) 2330 { 2331 case M4SYS_kMPEG_4: 2332 case M4SYS_kH263: 2333 case M4SYS_kH264: 2334 /**< We HAVE to put a value here... */ 2335 pC_ewc->WriterVideoStream.averageBitrate = 2336 pC_ewc->uiVideoBitrate; 2337 pC_ewc->WriterVideoStream.maxBitrate = pC_ewc->uiVideoBitrate; 2338 break; 2339 2340 default: 2341 M4OSA_TRACE1_1( 2342 "M4VSS3GPP_intCreate3GPPOutputFile: unknown input video format (0x%x),\ 2343 returning M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT!", 2344 pC_ewc->VideoStreamType); 2345 return M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT; 2346 } 2347 2348 pC_ewc->WriterVideoStream.streamID = M4VSS3GPP_WRITER_VIDEO_STREAM_ID; 2349 pC_ewc->WriterVideoStream.timeScale = 2350 0; /**< Not used by the shell/core writer */ 2351 pC_ewc->WriterVideoStream.profileLevel = 2352 0; /**< Not used by the shell/core writer */ 2353 pC_ewc->WriterVideoStream.duration = 2354 0; /**< Not used by the shell/core writer */ 2355 2356 pC_ewc->WriterVideoStream.decoderSpecificInfoSize = 2357 sizeof(M4WRITER_StreamVideoInfos); 2358 pC_ewc->WriterVideoStream.decoderSpecificInfo = 2359 (M4OSA_MemAddr32) &(pC_ewc->WriterVideoStreamInfo); 2360 2361 /** 2362 * Add the video stream */ 2363 err = pC_ShellAPI->pWriterGlobalFcts->pFctAddStream( 2364 pC_ewc->p3gpWriterContext, &pC_ewc->WriterVideoStream); 2365 2366 if( M4NO_ERROR != err ) 2367 { 2368 M4OSA_TRACE1_1( 2369 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2370 pWriterGlobalFcts->pFctAddStream(video) returns 0x%x!", 2371 err); 2372 return err; 2373 } 2374 2375 /** 2376 * Update AU properties for video stream */ 2377 pC_ewc->WriterVideoAU.attribute = AU_RAP; 2378 pC_ewc->WriterVideoAU.CTS = 0; 2379 pC_ewc->WriterVideoAU.DTS = 0; /** Reset time */ 2380 pC_ewc->WriterVideoAU.frag = M4OSA_NULL; 2381 pC_ewc->WriterVideoAU.nbFrag = 0; /** No fragment */ 2382 pC_ewc->WriterVideoAU.size = 0; 2383 pC_ewc->WriterVideoAU.dataAddress = M4OSA_NULL; 2384 pC_ewc->WriterVideoAU.stream = &(pC_ewc->WriterVideoStream); 2385 2386 /** 2387 * Set the writer max video AU size */ 2388 pC_ewc->uiVideoMaxAuSize = (M4OSA_UInt32)(1.5F 2389 *(M4OSA_Float)(pC_ewc->WriterVideoStreamInfo.width 2390 * pC_ewc->WriterVideoStreamInfo.height) 2391 * M4VSS3GPP_VIDEO_MIN_COMPRESSION_RATIO); 2392 temp.streamID = M4VSS3GPP_WRITER_VIDEO_STREAM_ID; 2393 temp.value = pC_ewc->uiVideoMaxAuSize; 2394 err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( 2395 pC_ewc->p3gpWriterContext, (M4OSA_UInt32)M4WRITER_kMaxAUSize, 2396 (M4OSA_DataOption) &temp); 2397 2398 if( M4NO_ERROR != err ) 2399 { 2400 M4OSA_TRACE1_1( 2401 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2402 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!", 2403 err); 2404 return err; 2405 } 2406 2407 /** 2408 * Set the writer max video chunk size */ 2409 temp.streamID = M4VSS3GPP_WRITER_VIDEO_STREAM_ID; 2410 temp.value = (M4OSA_UInt32)(pC_ewc->uiVideoMaxAuSize \ 2411 * M4VSS3GPP_VIDEO_AU_SIZE_TO_CHUNCK_SIZE_RATIO); /**< from max AU size to 2412 max Chunck size */ 2413 err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( 2414 pC_ewc->p3gpWriterContext, 2415 (M4OSA_UInt32)M4WRITER_kMaxChunckSize, 2416 (M4OSA_DataOption) &temp); 2417 2418 if( M4NO_ERROR != err ) 2419 { 2420 M4OSA_TRACE1_1( 2421 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2422 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!", 2423 err); 2424 return err; 2425 } 2426 } 2427 2428 if( M4SYS_kAudioUnknown != pC_ewc->AudioStreamType ) 2429 { 2430 M4WRITER_StreamAudioInfos streamAudioInfo; 2431 2432 streamAudioInfo.nbSamplesPerSec = 0; /**< unused by our shell writer */ 2433 streamAudioInfo.nbBitsPerSample = 0; /**< unused by our shell writer */ 2434 streamAudioInfo.nbChannels = 1; /**< unused by our shell writer */ 2435 2436 if( pC_ewc->pAudioOutputDsi != M4OSA_NULL ) 2437 { 2438 /* If we copy the stream from the input, we copy its DSI */ 2439 streamAudioInfo.Header.Size = pC_ewc->uiAudioOutputDsiSize; 2440 streamAudioInfo.Header.pBuf = pC_ewc->pAudioOutputDsi; 2441 } 2442 else 2443 { 2444 /* Writer will put a default DSI */ 2445 streamAudioInfo.Header.Size = 0; 2446 streamAudioInfo.Header.pBuf = M4OSA_NULL; 2447 } 2448 2449 pC_ewc->WriterAudioStream.streamID = M4VSS3GPP_WRITER_AUDIO_STREAM_ID; 2450 pC_ewc->WriterAudioStream.streamType = pC_ewc->AudioStreamType; 2451 pC_ewc->WriterAudioStream.duration = 2452 0; /**< Not used by the shell/core writer */ 2453 pC_ewc->WriterAudioStream.profileLevel = 2454 0; /**< Not used by the shell/core writer */ 2455 pC_ewc->WriterAudioStreamInfo.nbSamplesPerSec = 2456 pC_ewc->uiSamplingFrequency; 2457 pC_ewc->WriterAudioStream.timeScale = pC_ewc->uiSamplingFrequency; 2458 pC_ewc->WriterAudioStreamInfo.nbChannels = 2459 (M4OSA_UInt16)pC_ewc->uiNbChannels; 2460 pC_ewc->WriterAudioStreamInfo.nbBitsPerSample = 2461 0; /**< Not used by the shell/core writer */ 2462 2463 /** 2464 * Add the audio stream */ 2465 switch( pC_ewc->AudioStreamType ) 2466 { 2467 case M4SYS_kAMR: 2468 pC_ewc->WriterAudioStream.averageBitrate = 2469 0; /**< It is not used by the shell, the DSI is taken into account instead */ 2470 pC_ewc->WriterAudioStream.maxBitrate = 2471 0; /**< Not used by the shell/core writer */ 2472 break; 2473 2474 case M4SYS_kAAC: 2475 pC_ewc->WriterAudioStream.averageBitrate = 2476 pC_ewc->uiAudioBitrate; 2477 pC_ewc->WriterAudioStream.maxBitrate = pC_ewc->uiAudioBitrate; 2478 break; 2479 2480 case M4SYS_kEVRC: 2481 pC_ewc->WriterAudioStream.averageBitrate = 2482 0; /**< It is not used by the shell, the DSI is taken into account instead */ 2483 pC_ewc->WriterAudioStream.maxBitrate = 2484 0; /**< Not used by the shell/core writer */ 2485 break; 2486 2487 case M4SYS_kMP3: /**< there can't be MP3 track in 3GPP file -> error */ 2488 default: 2489 M4OSA_TRACE1_1( 2490 "M4VSS3GPP_intCreate3GPPOutputFile: unknown output audio format (0x%x),\ 2491 returning M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT!", 2492 pC_ewc->AudioStreamType); 2493 return M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT; 2494 } 2495 2496 /** 2497 * Our writer shell interface is a little tricky: we put M4WRITER_StreamAudioInfos 2498 in the DSI pointer... */ 2499 pC_ewc->WriterAudioStream.decoderSpecificInfo = 2500 (M4OSA_MemAddr32) &streamAudioInfo; 2501 2502 /** 2503 * Link the AU and the stream */ 2504 pC_ewc->WriterAudioAU.stream = &(pC_ewc->WriterAudioStream); 2505 pC_ewc->WriterAudioAU.dataAddress = M4OSA_NULL; 2506 pC_ewc->WriterAudioAU.size = 0; 2507 pC_ewc->WriterAudioAU.CTS = 2508 -pC_ewc->iSilenceFrameDuration; /** Reset time */ 2509 pC_ewc->WriterAudioAU.DTS = 0; 2510 pC_ewc->WriterAudioAU.attribute = 0; 2511 pC_ewc->WriterAudioAU.nbFrag = 0; /** No fragment */ 2512 pC_ewc->WriterAudioAU.frag = M4OSA_NULL; 2513 2514 err = pC_ShellAPI->pWriterGlobalFcts->pFctAddStream( 2515 pC_ewc->p3gpWriterContext, &pC_ewc->WriterAudioStream); 2516 2517 if( M4NO_ERROR != err ) 2518 { 2519 M4OSA_TRACE1_1( 2520 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2521 pWriterGlobalFcts->pFctAddStream(audio) returns 0x%x!", 2522 err); 2523 return err; 2524 } 2525 2526 /** 2527 * Set the writer max audio AU size */ 2528 pC_ewc->uiAudioMaxAuSize = M4VSS3GPP_AUDIO_MAX_AU_SIZE; 2529 temp.streamID = M4VSS3GPP_WRITER_AUDIO_STREAM_ID; 2530 temp.value = pC_ewc->uiAudioMaxAuSize; 2531 err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( 2532 pC_ewc->p3gpWriterContext, (M4OSA_UInt32)M4WRITER_kMaxAUSize, 2533 (M4OSA_DataOption) &temp); 2534 2535 if( M4NO_ERROR != err ) 2536 { 2537 M4OSA_TRACE1_1( 2538 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2539 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, audio) returns 0x%x!", 2540 err); 2541 return err; 2542 } 2543 2544 /** 2545 * Set the writer max audio chunck size */ 2546 temp.streamID = M4VSS3GPP_WRITER_AUDIO_STREAM_ID; 2547 temp.value = M4VSS3GPP_AUDIO_MAX_CHUNCK_SIZE; 2548 err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( 2549 pC_ewc->p3gpWriterContext, 2550 (M4OSA_UInt32)M4WRITER_kMaxChunckSize, 2551 (M4OSA_DataOption) &temp); 2552 2553 if( M4NO_ERROR != err ) 2554 { 2555 M4OSA_TRACE1_1( 2556 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2557 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, audio) returns 0x%x!", 2558 err); 2559 return err; 2560 } 2561 } 2562 2563 /** 2564 * All streams added, we're now ready to write */ 2565 err = pC_ShellAPI->pWriterGlobalFcts->pFctStartWriting( 2566 pC_ewc->p3gpWriterContext); 2567 2568 if( M4NO_ERROR != err ) 2569 { 2570 M4OSA_TRACE1_1( 2571 "M4VSS3GPP_intCreate3GPPOutputFile:\ 2572 pWriterGlobalFcts->pFctStartWriting() returns 0x%x!", 2573 err); 2574 return err; 2575 } 2576 2577 /** 2578 * Return with no error */ 2579 M4OSA_TRACE3_0("M4VSS3GPP_intCreate3GPPOutputFile(): returning M4NO_ERROR"); 2580 return M4NO_ERROR; 2581} 2582 2583/** 2584 ****************************************************************************** 2585 * M4OSA_ERR M4VSS3GPP_intComputeOutputVideoAndAudioDsi() 2586 * @brief Generate a H263 or MPEG-4 decoder specific info compatible with all input video 2587 * tracks. Copy audio dsi from master clip. 2588 * @param pC (IN/OUT) Internal edit context 2589 ****************************************************************************** 2590 */ 2591static M4OSA_ERR 2592M4VSS3GPP_intComputeOutputVideoAndAudioDsi( M4VSS3GPP_InternalEditContext *pC, 2593 M4OSA_UInt8 uiMasterClip ) 2594{ 2595 M4OSA_Int32 iResynchMarkerDsiIndex; 2596 M4_StreamHandler *pStreamForDsi; 2597 M4VSS3GPP_ClipContext *pClip; 2598 M4OSA_ERR err; 2599 M4OSA_UInt32 i; 2600 M4DECODER_MPEG4_DecoderConfigInfo DecConfigInfo; 2601 M4DECODER_VideoSize dummySize; 2602 M4OSA_Bool bGetDSiFromEncoder = M4OSA_FALSE; 2603 2604 M4ENCODER_Header *encHeader; 2605 M4SYS_StreamIDmemAddr streamHeader; 2606 2607 pStreamForDsi = M4OSA_NULL; 2608 pClip = M4OSA_NULL; 2609 2610 /** 2611 * H263 case */ 2612 if( M4SYS_kH263 == pC->ewc.VideoStreamType ) 2613 { 2614 /** 2615 * H263 output DSI is always 7 bytes */ 2616 pC->ewc.uiVideoOutputDsiSize = 7; 2617 pC->ewc.pVideoOutputDsi = 2618 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ewc.uiVideoOutputDsiSize, 2619 M4VSS3GPP, (M4OSA_Char *)"pC->ewc.pVideoOutputDsi (H263)"); 2620 2621 if( M4OSA_NULL == pC->ewc.pVideoOutputDsi ) 2622 { 2623 M4OSA_TRACE1_0( 2624 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi():\ 2625 unable to allocate pVideoOutputDsi (H263), returning M4ERR_ALLOC"); 2626 return M4ERR_ALLOC; 2627 } 2628 2629 /** 2630 * (We override the input vendor info. 2631 * At least we know that nothing special will be tried with PHLP-stamped 2632 edited streams...) */ 2633 pC->ewc.pVideoOutputDsi[0] = 'P'; 2634 pC->ewc.pVideoOutputDsi[1] = 'H'; 2635 pC->ewc.pVideoOutputDsi[2] = 'L'; 2636 pC->ewc.pVideoOutputDsi[3] = 'P'; 2637 2638 /** 2639 * Decoder version is 0 */ 2640 pC->ewc.pVideoOutputDsi[4] = 0; 2641 2642 /** 2643 * Level is the sixth byte in the DSI */ 2644 pC->ewc.pVideoOutputDsi[5] = pC->xVSS.outputVideoLevel; 2645 2646 /** 2647 * Profile is the seventh byte in the DSI*/ 2648 pC->ewc.pVideoOutputDsi[6] = pC->xVSS.outputVideoProfile; 2649 } 2650 2651 /** 2652 * MPEG-4 case */ 2653 else if( M4SYS_kMPEG_4 == pC->ewc.VideoStreamType || 2654 M4SYS_kH264 == pC->ewc.VideoStreamType) { 2655 2656 /* For MPEG4 and H.264 encoder case 2657 * Fetch the DSI from the shell video encoder, and feed it to the writer before 2658 closing it. */ 2659 2660 M4OSA_TRACE1_0( 2661 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi: get DSI for H264 stream"); 2662 2663 if( M4OSA_NULL == pC->ewc.pEncContext ) 2664 { 2665 M4OSA_TRACE1_0( 2666 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi: pC->ewc.pEncContext is NULL"); 2667 err = M4VSS3GPP_intCreateVideoEncoder(pC); 2668 2669 if( M4NO_ERROR != err ) 2670 { 2671 M4OSA_TRACE1_1( 2672 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2673 M4VSS3GPP_intCreateVideoEncoder returned error 0x%x", 2674 err); 2675 } 2676 } 2677 2678 if( M4OSA_NULL != pC->ewc.pEncContext ) 2679 { 2680 err = pC->ShellAPI.pVideoEncoderGlobalFcts->pFctGetOption( 2681 pC->ewc.pEncContext, M4ENCODER_kOptionID_EncoderHeader, 2682 (M4OSA_DataOption) &encHeader); 2683 2684 if( ( M4NO_ERROR != err) || (M4OSA_NULL == encHeader->pBuf) ) 2685 { 2686 M4OSA_TRACE1_1( 2687 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2688 failed to get the encoder header (err 0x%x)", 2689 err); 2690 M4OSA_TRACE1_2( 2691 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi: encHeader->pBuf=0x%x, size=0x%x", 2692 encHeader->pBuf, encHeader->Size); 2693 } 2694 else 2695 { 2696 M4OSA_TRACE1_0( 2697 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2698 send DSI for video stream to 3GP writer"); 2699 2700 /** 2701 * Allocate and copy the new DSI */ 2702 pC->ewc.pVideoOutputDsi = 2703 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(encHeader->Size, M4VSS3GPP, 2704 (M4OSA_Char *)"pC->ewc.pVideoOutputDsi (H264)"); 2705 2706 if( M4OSA_NULL == pC->ewc.pVideoOutputDsi ) 2707 { 2708 M4OSA_TRACE1_0( 2709 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi():\ 2710 unable to allocate pVideoOutputDsi, returning M4ERR_ALLOC"); 2711 return M4ERR_ALLOC; 2712 } 2713 pC->ewc.uiVideoOutputDsiSize = (M4OSA_UInt16)encHeader->Size; 2714 memcpy((void *)pC->ewc.pVideoOutputDsi, (void *)encHeader->pBuf, 2715 encHeader->Size); 2716 } 2717 2718 err = M4VSS3GPP_intDestroyVideoEncoder(pC); 2719 2720 if( M4NO_ERROR != err ) 2721 { 2722 M4OSA_TRACE1_1( 2723 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2724 M4VSS3GPP_intDestroyVideoEncoder returned error 0x%x", 2725 err); 2726 } 2727 } 2728 else 2729 { 2730 M4OSA_TRACE1_0( 2731 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2732 pC->ewc.pEncContext is NULL, cannot get the DSI"); 2733 } 2734 } 2735 2736 pStreamForDsi = M4OSA_NULL; 2737 pClip = M4OSA_NULL; 2738 2739 /* Compute Audio DSI */ 2740 if( M4SYS_kAudioUnknown != pC->ewc.AudioStreamType ) 2741 { 2742 if( uiMasterClip == 0 ) 2743 { 2744 /* Clip is already opened */ 2745 pStreamForDsi = &(pC->pC1->pAudioStream->m_basicProperties); 2746 } 2747 else 2748 { 2749 /** 2750 * We can use the fast open mode to get the DSI */ 2751 err = M4VSS3GPP_intClipInit(&pClip, pC->pOsaFileReadPtr); 2752 2753 if( M4NO_ERROR != err ) 2754 { 2755 M4OSA_TRACE1_1( 2756 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2757 M4VSS3GPP_intClipInit() returns 0x%x!", 2758 err); 2759 2760 if( pClip != M4OSA_NULL ) 2761 { 2762 M4VSS3GPP_intClipCleanUp(pClip); 2763 } 2764 return err; 2765 } 2766 2767 err = M4VSS3GPP_intClipOpen(pClip, &pC->pClipList[uiMasterClip], 2768 M4OSA_FALSE, M4OSA_TRUE, M4OSA_TRUE); 2769 2770 if( M4NO_ERROR != err ) 2771 { 2772 M4OSA_TRACE1_1( 2773 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2774 M4VSS3GPP_intClipOpen() returns 0x%x!", 2775 err); 2776 M4VSS3GPP_intClipCleanUp(pClip); 2777 return err; 2778 } 2779 2780 pStreamForDsi = &(pClip->pAudioStream->m_basicProperties); 2781 } 2782 2783 /** 2784 * Allocate and copy the new DSI */ 2785 pC->ewc.pAudioOutputDsi = (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc( 2786 pStreamForDsi->m_decoderSpecificInfoSize, 2787 M4VSS3GPP, (M4OSA_Char *)"pC->ewc.pAudioOutputDsi"); 2788 2789 if( M4OSA_NULL == pC->ewc.pAudioOutputDsi ) 2790 { 2791 M4OSA_TRACE1_0( 2792 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi():\ 2793 unable to allocate pAudioOutputDsi, returning M4ERR_ALLOC"); 2794 return M4ERR_ALLOC; 2795 } 2796 pC->ewc.uiAudioOutputDsiSize = 2797 (M4OSA_UInt16)pStreamForDsi->m_decoderSpecificInfoSize; 2798 memcpy((void *)pC->ewc.pAudioOutputDsi, 2799 (void *)pStreamForDsi->m_pDecoderSpecificInfo, 2800 pC->ewc.uiAudioOutputDsiSize); 2801 2802 /** 2803 * If a clip has been temporarily opened to get its DSI, close it */ 2804 if( M4OSA_NULL != pClip ) 2805 { 2806 err = M4VSS3GPP_intClipCleanUp(pClip); 2807 2808 if( M4NO_ERROR != err ) 2809 { 2810 M4OSA_TRACE1_1( 2811 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ 2812 M4VSS3GPP_intClipCleanUp() returns 0x%x!", 2813 err); 2814 return err; 2815 } 2816 } 2817 } 2818 2819 /** 2820 * Return with no error */ 2821 M4OSA_TRACE3_0( 2822 "M4VSS3GPP_intComputeOutputVideoAndAudioDsi(): returning M4NO_ERROR"); 2823 return M4NO_ERROR; 2824} 2825 2826/** 2827 ****************************************************************************** 2828 * M4OSA_ERR M4VSS3GPP_intSwitchToNextClip() 2829 * @brief Switch from the current clip to the next one 2830 * @param pC (IN/OUT) Internal edit context 2831 ****************************************************************************** 2832 */ 2833static M4OSA_ERR M4VSS3GPP_intSwitchToNextClip( 2834 M4VSS3GPP_InternalEditContext *pC ) 2835{ 2836 M4OSA_ERR err; 2837 2838 if( M4OSA_NULL != pC->pC1 ) 2839 { 2840 if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame) { 2841 if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame[0].pac_data) { 2842 free(pC->pC1->m_pPreResizeFrame[0].pac_data); 2843 pC->pC1->m_pPreResizeFrame[0].pac_data = M4OSA_NULL; 2844 } 2845 if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame[1].pac_data) { 2846 free(pC->pC1->m_pPreResizeFrame[1].pac_data); 2847 pC->pC1->m_pPreResizeFrame[1].pac_data = M4OSA_NULL; 2848 } 2849 if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame[2].pac_data) { 2850 free(pC->pC1->m_pPreResizeFrame[2].pac_data); 2851 pC->pC1->m_pPreResizeFrame[2].pac_data = M4OSA_NULL; 2852 } 2853 free(pC->pC1->m_pPreResizeFrame); 2854 pC->pC1->m_pPreResizeFrame = M4OSA_NULL; 2855 } 2856 /** 2857 * Close the current first clip */ 2858 err = M4VSS3GPP_intClipCleanUp(pC->pC1); 2859 2860 if( M4NO_ERROR != err ) 2861 { 2862 M4OSA_TRACE1_1( 2863 "M4VSS3GPP_intSwitchToNextClip: M4VSS3GPP_intClipCleanUp(C1) returns 0x%x!", 2864 err); 2865 return err; 2866 } 2867 2868 /** 2869 * increment clip counter */ 2870 pC->uiCurrentClip++; 2871 } 2872 2873 /** 2874 * Check if we reached the last clip */ 2875 if( pC->uiCurrentClip >= pC->uiClipNumber ) 2876 { 2877 pC->pC1 = M4OSA_NULL; 2878 pC->State = M4VSS3GPP_kEditState_FINISHED; 2879 2880 M4OSA_TRACE1_0( 2881 "M4VSS3GPP_intSwitchToNextClip:\ 2882 M4VSS3GPP_intClipClose(C1) returns M4VSS3GPP_WAR_EDITING_DONE"); 2883 return M4VSS3GPP_WAR_EDITING_DONE; 2884 } 2885 2886 /** 2887 * If the next clip has already be opened, set it as first clip */ 2888 if( M4OSA_NULL != pC->pC2 ) 2889 { 2890 pC->pC1 = pC->pC2; 2891 if(M4OSA_NULL != pC->pC2->m_pPreResizeFrame) { 2892 pC->pC1->m_pPreResizeFrame = pC->pC2->m_pPreResizeFrame; 2893 } 2894 pC->pC2 = M4OSA_NULL; 2895 } 2896 /** 2897 * else open it */ 2898 else 2899 { 2900 err = M4VSS3GPP_intOpenClip(pC, &pC->pC1, 2901 &pC->pClipList[pC->uiCurrentClip]); 2902 2903 if( M4NO_ERROR != err ) 2904 { 2905 M4OSA_TRACE1_1( 2906 "M4VSS3GPP_intSwitchToNextClip: M4VSS3GPP_intOpenClip() returns 0x%x!", 2907 err); 2908 return err; 2909 } 2910 2911 /** 2912 * If the second clip has not been opened yet, 2913 that means that there has been no transition. 2914 * So both output video and audio times are OK. 2915 * So we can set both video2 and audio offsets */ 2916 2917 /** 2918 * Add current video output CTS to the clip video offset */ 2919 2920 // Decorrelate input and output encoding timestamp to handle encoder prefetch 2921 pC->pC1->iVoffset += (M4OSA_UInt32)pC->ewc.dInputVidCts; 2922 /** 2923 * Add current audio output CTS to the clip audio offset */ 2924 pC->pC1->iAoffset += 2925 (M4OSA_UInt32)(pC->ewc.dATo * pC->ewc.scale_audio + 0.5); 2926 2927 /** 2928 * 2005-03-24: BugFix for audio-video synchro: 2929 * There may be a portion of the duration of an audio AU of desynchro at each assembly. 2930 * It leads to an audible desynchro when there are a lot of clips assembled. 2931 * This bug fix allows to resynch the audio track when the delta is higher 2932 * than one audio AU duration. 2933 * We Step one AU in the second clip and we change the audio offset accordingly. */ 2934 if( ( pC->pC1->iAoffset 2935 - (M4OSA_Int32)(pC->pC1->iVoffset *pC->pC1->scale_audio + 0.5)) 2936 > pC->ewc.iSilenceFrameDuration ) 2937 { 2938 /** 2939 * Advance one AMR frame */ 2940 err = M4VSS3GPP_intClipReadNextAudioFrame(pC->pC1); 2941 2942 if( M4OSA_ERR_IS_ERROR(err) ) 2943 { 2944 M4OSA_TRACE1_1( 2945 "M4VSS3GPP_intSwitchToNextClip:\ 2946 M4VSS3GPP_intClipReadNextAudioFrame returns 0x%x!", 2947 err); 2948 return err; 2949 } 2950 /** 2951 * Update audio offset accordingly*/ 2952 pC->pC1->iAoffset -= pC->ewc.iSilenceFrameDuration; 2953 } 2954 } 2955 2956 /** 2957 * Init starting state for this clip processing */ 2958 if( M4SYS_kMP3 == pC->ewc.AudioStreamType ) 2959 { 2960 /** 2961 * In the MP3 case we use a special audio state */ 2962 pC->State = M4VSS3GPP_kEditState_MP3_JUMP; 2963 } 2964 else 2965 { 2966 /** 2967 * We start with the video processing */ 2968 pC->State = M4VSS3GPP_kEditState_VIDEO; 2969 2970 if( pC->Vstate != M4VSS3GPP_kEditVideoState_TRANSITION ) 2971 { 2972 /* if not a transition then reset previous video state */ 2973 pC->Vstate = M4VSS3GPP_kEditVideoState_READ_WRITE; 2974 } 2975 } 2976 /* The flags are set to false at the beginning of every clip */ 2977 pC->m_bClipExternalHasStarted = M4OSA_FALSE; 2978 pC->bEncodeTillEoF = M4OSA_FALSE; 2979 2980 /** 2981 * Return with no error */ 2982 M4OSA_TRACE3_0("M4VSS3GPP_intSwitchToNextClip(): returning M4NO_ERROR"); 2983 /* RC: to know when a file has been processed */ 2984 return M4VSS3GPP_WAR_SWITCH_CLIP; 2985} 2986 2987/** 2988 ****************************************************************************** 2989 * M4OSA_ERR M4VSS3GPP_intReachedEndOfVideo() 2990 * @brief Do what to do when the end of a clip video track is reached 2991 * @note If there is audio on the current clip, process it, else switch to the next clip 2992 * @param pC (IN/OUT) Internal edit context 2993 ****************************************************************************** 2994 */ 2995M4OSA_ERR M4VSS3GPP_intReachedEndOfVideo( M4VSS3GPP_InternalEditContext *pC ) 2996{ 2997 M4OSA_ERR err; 2998 2999 /** 3000 * Video is done for this clip, now we do the audio */ 3001 if( M4SYS_kAudioUnknown != pC->ewc.AudioStreamType ) 3002 { 3003 pC->State = M4VSS3GPP_kEditState_AUDIO; 3004 } 3005 else 3006 { 3007 /** 3008 * Clip done, do the next one */ 3009 err = M4VSS3GPP_intSwitchToNextClip(pC); 3010 3011 if( M4NO_ERROR != err ) 3012 { 3013 M4OSA_TRACE1_1( 3014 "M4VSS3GPP_intReachedEndOfVideo: M4VSS3GPP_intSwitchToNextClip() returns 0x%x", 3015 err); 3016 return err; 3017 } 3018 } 3019 3020 /** 3021 * Return with no error */ 3022 M4OSA_TRACE3_0("M4VSS3GPP_intReachedEndOfVideo(): returning M4NO_ERROR"); 3023 return M4NO_ERROR; 3024} 3025 3026/** 3027 ****************************************************************************** 3028 * M4OSA_ERR M4VSS3GPP_intReachedEndOfAudio() 3029 * @brief Do what to do when the end of a clip audio track is reached 3030 * @param pC (IN/OUT) Internal edit context 3031 ****************************************************************************** 3032 */ 3033M4OSA_ERR M4VSS3GPP_intReachedEndOfAudio( M4VSS3GPP_InternalEditContext *pC ) 3034{ 3035 M4OSA_ERR err; 3036 3037 /** 3038 * Clip done, do the next one */ 3039 err = M4VSS3GPP_intSwitchToNextClip(pC); 3040 3041 if( M4NO_ERROR != err ) 3042 { 3043 M4OSA_TRACE1_1( 3044 "M4VSS3GPP_intReachedEndOfAudio: M4VSS3GPP_intSwitchToNextClip() returns 0x%x", 3045 err); 3046 return err; 3047 } 3048 3049 /** 3050 * Start with the video */ 3051 if( M4SYS_kVideoUnknown != pC->ewc.VideoStreamType ) 3052 { 3053 pC->State = M4VSS3GPP_kEditState_VIDEO; 3054 } 3055 3056 /** 3057 * Return with no error */ 3058 M4OSA_TRACE3_0("M4VSS3GPP_intReachedEndOfAudio(): returning M4NO_ERROR"); 3059 return M4NO_ERROR; 3060} 3061 3062/** 3063 ****************************************************************************** 3064 * M4OSA_ERR M4VSS3GPP_intOpenClip() 3065 * @brief Open next clip 3066 * @param pC (IN/OUT) Internal edit context 3067 ****************************************************************************** 3068 */ 3069M4OSA_ERR M4VSS3GPP_intOpenClip( M4VSS3GPP_InternalEditContext *pC, 3070 M4VSS3GPP_ClipContext ** hClip, 3071 M4VSS3GPP_ClipSettings *pClipSettings ) 3072{ 3073 M4OSA_ERR err; 3074 M4VSS3GPP_ClipContext *pClip; /**< shortcut */ 3075 M4VIDEOEDITING_ClipProperties *pClipProperties = M4OSA_NULL; 3076 M4OSA_Int32 iCts; 3077 M4OSA_UInt32 i; 3078 3079 M4OSA_TRACE2_1("M4VSS3GPP_intOpenClip: \"%s\"", 3080 (M4OSA_Char *)pClipSettings->pFile); 3081 3082 err = M4VSS3GPP_intClipInit(hClip, pC->pOsaFileReadPtr); 3083 3084 if( M4NO_ERROR != err ) 3085 { 3086 M4OSA_TRACE1_1( 3087 "M4VSS3GPP_intOpenClip: M4VSS3GPP_intClipInit() returns 0x%x!", 3088 err); 3089 3090 if( *hClip != M4OSA_NULL ) 3091 { 3092 M4VSS3GPP_intClipCleanUp(*hClip); 3093 } 3094 return err; 3095 } 3096 3097 /** 3098 * Set shortcut */ 3099 pClip = *hClip; 3100 3101 if (pClipSettings->FileType == M4VIDEOEDITING_kFileType_ARGB8888 ) { 3102 pClipProperties = &pClipSettings->ClipProperties; 3103 pClip->pSettings = pClipSettings; 3104 pClip->iEndTime = pClipSettings->uiEndCutTime; 3105 } 3106 3107 err = M4VSS3GPP_intClipOpen(pClip, pClipSettings, 3108 M4OSA_FALSE, M4OSA_FALSE, M4OSA_FALSE); 3109 if (M4NO_ERROR != err) { 3110 M4OSA_TRACE1_1("M4VSS3GPP_intOpenClip: \ 3111 M4VSS3GPP_intClipOpen() returns 0x%x!", err); 3112 M4VSS3GPP_intClipCleanUp(pClip); 3113 *hClip = M4OSA_NULL; 3114 return err; 3115 } 3116 3117 if (pClipSettings->FileType != M4VIDEOEDITING_kFileType_ARGB8888 ) { 3118 pClipProperties = &pClip->pSettings->ClipProperties; 3119 } 3120 3121 /** 3122 * Copy common 'silence frame stuff' to ClipContext */ 3123 pClip->uiSilencePcmSize = pC->ewc.uiSilencePcmSize; 3124 pClip->pSilenceFrameData = pC->ewc.pSilenceFrameData; 3125 pClip->uiSilenceFrameSize = pC->ewc.uiSilenceFrameSize; 3126 pClip->iSilenceFrameDuration = pC->ewc.iSilenceFrameDuration; 3127 pClip->scale_audio = pC->ewc.scale_audio; 3128 3129 pClip->iAudioFrameCts = -pClip->iSilenceFrameDuration; /* Reset time */ 3130 3131 /** 3132 * If the audio track is not compatible with the output audio format, 3133 * we remove it. So it will be replaced by silence */ 3134 if( M4OSA_FALSE == pClipProperties->bAudioIsCompatibleWithMasterClip ) 3135 { 3136 M4VSS3GPP_intClipDeleteAudioTrack(pClip); 3137 } 3138 3139 /** 3140 * Actual begin cut */ 3141 if( 0 == pClipSettings->uiBeginCutTime ) 3142 { 3143 pClip->iVoffset = 0; 3144 pClip->iAoffset = 0; 3145 pClip->iActualVideoBeginCut = 0; 3146 pClip->iActualAudioBeginCut = 0; 3147 } 3148 else if(pClipSettings->FileType != M4VIDEOEDITING_kFileType_ARGB8888) { 3149 if( M4SYS_kVideoUnknown != pC->ewc.VideoStreamType ) 3150 { 3151 /** 3152 * Jump the video to the target begin cut to get the actual begin cut value */ 3153 pClip->iActualVideoBeginCut = 3154 (M4OSA_Int32)pClipSettings->uiBeginCutTime; 3155 iCts = pClip->iActualVideoBeginCut; 3156 3157 err = pClip->ShellAPI.m_pReader->m_pFctJump(pClip->pReaderContext, 3158 (M4_StreamHandler *)pClip->pVideoStream, &iCts); 3159 3160 if( M4NO_ERROR != err ) 3161 { 3162 M4OSA_TRACE1_1( 3163 "M4VSS3GPP_intOpenClip: m_pFctJump(V) returns 0x%x!", err); 3164 return err; 3165 } 3166 3167 /** 3168 * Update clip offset with the video begin cut */ 3169 pClip->iVoffset = -pClip->iActualVideoBeginCut; 3170 } 3171 3172 if( M4SYS_kAudioUnknown != pC->ewc.AudioStreamType ) 3173 { 3174 /** 3175 * Jump the audio to the video actual begin cut */ 3176 if( M4VIDEOEDITING_kMP3 != pClipProperties->AudioStreamType ) 3177 { 3178 pClip->iActualAudioBeginCut = pClip->iActualVideoBeginCut; 3179 iCts = (M4OSA_Int32)(pClip->iActualAudioBeginCut 3180 * pClip->scale_audio + 0.5); 3181 3182 err = M4VSS3GPP_intClipJumpAudioAt(pClip, &iCts); 3183 3184 if( M4NO_ERROR != err ) 3185 { 3186 M4OSA_TRACE1_1( 3187 "M4VSS3GPP_intOpenClip: M4VSS3GPP_intClipJumpAudioAt(A) returns 0x%x!", 3188 err); 3189 return err; 3190 } 3191 /** 3192 * Update clip offset with the audio begin cut */ 3193 pClip->iAoffset = -iCts; 3194 } 3195 else 3196 { 3197 /** 3198 * For the MP3, the jump is not done because of the VBR, 3199 it could be not enough accurate */ 3200 pClip->iActualAudioBeginCut = 3201 (M4OSA_Int32)pClipSettings->uiBeginCutTime; 3202 } 3203 } 3204 } 3205 3206 if( M4SYS_kVideoUnknown != pC->ewc.VideoStreamType ) 3207 { 3208 if ((pClipSettings->FileType != M4VIDEOEDITING_kFileType_ARGB8888 )) { 3209 3210 /** 3211 * Read the first Video AU of the clip */ 3212 err = pClip->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu( 3213 pClip->pReaderContext, 3214 (M4_StreamHandler *)pClip->pVideoStream, &pClip->VideoAU); 3215 3216 if( M4WAR_NO_MORE_AU == err ) 3217 { 3218 /** 3219 * If we (already!) reach the end of the clip, we filter the error. 3220 * It will be correctly managed at the first step. */ 3221 err = M4NO_ERROR; 3222 } 3223 else if( M4NO_ERROR != err ) 3224 { 3225 M4OSA_TRACE1_1("M4VSS3GPP_intOpenClip: \ 3226 m_pReaderDataIt->m_pFctGetNextAu() returns 0x%x!", err); 3227 return err; 3228 } 3229 } else { 3230 pClipProperties->uiVideoWidth = pClipProperties->uiStillPicWidth; 3231 pClipProperties->uiVideoHeight = pClipProperties->uiStillPicHeight; 3232 } 3233 /* state check not to allocate buffer during save start */ 3234 3235 3236 /******************************/ 3237 /* Video resize management */ 3238 /******************************/ 3239 /** 3240 * Compare input video size with output video size 3241 to check if resize needed */ 3242 if (((M4OSA_UInt32)pC->ewc.uiVideoWidth != 3243 pClipProperties->uiVideoWidth) || 3244 ((M4OSA_UInt32)pC->ewc.uiVideoHeight != 3245 pClipProperties->uiVideoHeight)) { 3246 if(pClip->m_pPreResizeFrame == M4OSA_NULL) { 3247 /** 3248 * Allocate the intermediate video plane that will 3249 receive the decoded image before resizing */ 3250 pClip->m_pPreResizeFrame = 3251 (M4VIFI_ImagePlane*)M4OSA_32bitAlignedMalloc( 3252 3*sizeof(M4VIFI_ImagePlane), M4VSS3GPP, 3253 (M4OSA_Char *)"pPreResizeFrame"); 3254 if (M4OSA_NULL == pClip->m_pPreResizeFrame) { 3255 M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder(): \ 3256 unable to allocate m_pPreResizeFrame"); 3257 return M4ERR_ALLOC; 3258 } 3259 3260 pClip->m_pPreResizeFrame[0].pac_data = M4OSA_NULL; 3261 pClip->m_pPreResizeFrame[1].pac_data = M4OSA_NULL; 3262 pClip->m_pPreResizeFrame[2].pac_data = M4OSA_NULL; 3263 3264 /** 3265 * Allocate the Y plane */ 3266 pClip->m_pPreResizeFrame[0].u_topleft = 0; 3267 pClip->m_pPreResizeFrame[0].u_width = 3268 pClipProperties->uiVideoWidth; 3269 pClip->m_pPreResizeFrame[0].u_height = 3270 pClipProperties->uiVideoHeight; 3271 pClip->m_pPreResizeFrame[0].u_stride = 3272 pClip->m_pPreResizeFrame[0].u_width; 3273 3274 pClip->m_pPreResizeFrame[0].pac_data = 3275 (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc ( 3276 pClip->m_pPreResizeFrame[0].u_stride * pClip->m_pPreResizeFrame[0].u_height, 3277 M4MCS, (M4OSA_Char *)"m_pPreResizeFrame[0].pac_data"); 3278 if (M4OSA_NULL == pClip->m_pPreResizeFrame[0].pac_data) { 3279 M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder(): \ 3280 unable to allocate m_pPreResizeFrame[0].pac_data"); 3281 free(pClip->m_pPreResizeFrame); 3282 return M4ERR_ALLOC; 3283 } 3284 3285 /** 3286 * Allocate the U plane */ 3287 pClip->m_pPreResizeFrame[1].u_topleft = 0; 3288 pClip->m_pPreResizeFrame[1].u_width = 3289 pClip->m_pPreResizeFrame[0].u_width >> 1; 3290 pClip->m_pPreResizeFrame[1].u_height = 3291 pClip->m_pPreResizeFrame[0].u_height >> 1; 3292 pClip->m_pPreResizeFrame[1].u_stride = 3293 pClip->m_pPreResizeFrame[1].u_width; 3294 3295 pClip->m_pPreResizeFrame[1].pac_data = 3296 (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc ( 3297 pClip->m_pPreResizeFrame[1].u_stride * pClip->m_pPreResizeFrame[1].u_height, 3298 M4MCS, (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data"); 3299 if (M4OSA_NULL == pClip->m_pPreResizeFrame[1].pac_data) { 3300 M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder(): \ 3301 unable to allocate m_pPreResizeFrame[1].pac_data"); 3302 free(pClip->m_pPreResizeFrame[0].pac_data); 3303 free(pClip->m_pPreResizeFrame); 3304 return M4ERR_ALLOC; 3305 } 3306 3307 /** 3308 * Allocate the V plane */ 3309 pClip->m_pPreResizeFrame[2].u_topleft = 0; 3310 pClip->m_pPreResizeFrame[2].u_width = 3311 pClip->m_pPreResizeFrame[1].u_width; 3312 pClip->m_pPreResizeFrame[2].u_height = 3313 pClip->m_pPreResizeFrame[1].u_height; 3314 pClip->m_pPreResizeFrame[2].u_stride = 3315 pClip->m_pPreResizeFrame[2].u_width; 3316 3317 pClip->m_pPreResizeFrame[2].pac_data = 3318 (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc ( 3319 pClip->m_pPreResizeFrame[2].u_stride * pClip->m_pPreResizeFrame[2].u_height, 3320 M4MCS, (M4OSA_Char *)"m_pPreResizeFrame[2].pac_data"); 3321 if (M4OSA_NULL == pClip->m_pPreResizeFrame[2].pac_data) { 3322 M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder(): \ 3323 unable to allocate m_pPreResizeFrame[2].pac_data"); 3324 free(pClip->m_pPreResizeFrame[0].pac_data); 3325 free(pClip->m_pPreResizeFrame[1].pac_data); 3326 free(pClip->m_pPreResizeFrame); 3327 return M4ERR_ALLOC; 3328 } 3329 } 3330 } 3331 3332 /** 3333 * The video is currently in reading mode */ 3334 pClip->Vstatus = M4VSS3GPP_kClipStatus_READ; 3335 } 3336 3337 if( ( M4SYS_kAudioUnknown != pC->ewc.AudioStreamType) 3338 && (M4VIDEOEDITING_kMP3 != pClipProperties->AudioStreamType) ) 3339 { 3340 /** 3341 * Read the first Audio AU of the clip */ 3342 err = M4VSS3GPP_intClipReadNextAudioFrame(pClip); 3343 3344 if( M4OSA_ERR_IS_ERROR(err) ) 3345 { 3346 M4OSA_TRACE1_1( 3347 "M4VSS3GPP_intOpenClip: M4VSS3GPP_intClipReadNextAudioFrame returns 0x%x!", 3348 err); 3349 return err; 3350 } 3351 3352 /** 3353 * The audio is currently in reading mode */ 3354 pClip->Astatus = M4VSS3GPP_kClipStatus_READ; 3355 } 3356 3357 /** 3358 * Return with no error */ 3359 M4OSA_TRACE3_0("M4VSS3GPP_intOpenClip(): returning M4NO_ERROR"); 3360 return M4NO_ERROR; 3361} 3362 3363/** 3364 ****************************************************************************** 3365 * M4OSA_ERR M4VSS3GPP_intComputeOutputAverageVideoBitrate() 3366 * @brief Average bitrate of the output file, computed from input bitrates, 3367 * durations, transitions and cuts. 3368 * @param pC (IN/OUT) Internal edit context 3369 ****************************************************************************** 3370 */ 3371static M4OSA_Void M4VSS3GPP_intComputeOutputAverageVideoBitrate( 3372 M4VSS3GPP_InternalEditContext *pC ) 3373{ 3374 M4VSS3GPP_ClipSettings *pCS_0, *pCS_1, *pCS_2; 3375 M4VSS3GPP_TransitionSettings *pT0, *pT2; 3376 M4OSA_Int32 i; 3377 3378 M4OSA_UInt32 t0_duration, t2_duration; 3379 M4OSA_UInt32 t0_bitrate, t2_bitrate; 3380 M4OSA_UInt32 c1_duration; 3381 3382 M4OSA_UInt32 total_duration; 3383 M4OSA_UInt32 total_bitsum; 3384 3385 total_duration = 0; 3386 total_bitsum = 0; 3387 3388 /* Loop on the number of clips */ 3389 for ( i = 0; i < pC->uiClipNumber; i++ ) 3390 { 3391 pCS_1 = &pC->pClipList[i]; 3392 3393 t0_duration = 0; 3394 t0_bitrate = pCS_1->ClipProperties.uiVideoBitrate; 3395 t2_duration = 0; 3396 t2_bitrate = pCS_1->ClipProperties.uiVideoBitrate; 3397 3398 /* Transition with the previous clip */ 3399 if( i > 0 ) 3400 { 3401 pCS_0 = &pC->pClipList[i - 1]; 3402 pT0 = &pC->pTransitionList[i - 1]; 3403 3404 if( pT0->VideoTransitionType 3405 != M4VSS3GPP_kVideoTransitionType_None ) 3406 { 3407 t0_duration = pT0->uiTransitionDuration; 3408 3409 if( pCS_0->ClipProperties.uiVideoBitrate > t0_bitrate ) 3410 { 3411 t0_bitrate = pCS_0->ClipProperties.uiVideoBitrate; 3412 } 3413 } 3414 } 3415 3416 /* Transition with the next clip */ 3417 if( i < pC->uiClipNumber - 1 ) 3418 { 3419 pCS_2 = &pC->pClipList[i + 1]; 3420 pT2 = &pC->pTransitionList[i]; 3421 3422 if( pT2->VideoTransitionType 3423 != M4VSS3GPP_kVideoTransitionType_None ) 3424 { 3425 t2_duration = pT2->uiTransitionDuration; 3426 3427 if( pCS_2->ClipProperties.uiVideoBitrate > t2_bitrate ) 3428 { 3429 t2_bitrate = pCS_2->ClipProperties.uiVideoBitrate; 3430 } 3431 } 3432 } 3433 3434 /* Check for cut times */ 3435 if( pCS_1->uiEndCutTime > 0 ) 3436 c1_duration = pCS_1->uiEndCutTime; 3437 else 3438 c1_duration = pCS_1->ClipProperties.uiClipVideoDuration; 3439 3440 if( pCS_1->uiBeginCutTime > 0 ) 3441 c1_duration -= pCS_1->uiBeginCutTime; 3442 3443 c1_duration -= t0_duration + t2_duration; 3444 3445 /* Compute bitsum and duration */ 3446 total_duration += c1_duration + t0_duration / 2 + t2_duration / 2; 3447 3448 total_bitsum += 3449 c1_duration * (pCS_1->ClipProperties.uiVideoBitrate / 1000) 3450 + (t0_bitrate / 1000) * t0_duration / 2 3451 + (t2_bitrate / 1000) * t2_duration / 2; 3452 } 3453 3454 pC->ewc.uiVideoBitrate = ( total_bitsum / total_duration) * 1000; 3455} 3456 3457