diff options
Diffstat (limited to 'libvideoeditor/vss/src/M4VSS3GPP_Edit.c')
-rwxr-xr-x | libvideoeditor/vss/src/M4VSS3GPP_Edit.c | 3475 |
1 files changed, 0 insertions, 3475 deletions
diff --git a/libvideoeditor/vss/src/M4VSS3GPP_Edit.c b/libvideoeditor/vss/src/M4VSS3GPP_Edit.c deleted file mode 100755 index df8b7d5..0000000 --- a/libvideoeditor/vss/src/M4VSS3GPP_Edit.c +++ /dev/null @@ -1,3475 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - ****************************************************************************** - * @file M4VSS3GPP_Edit.c - * @brief Video Studio Service 3GPP edit API implementation. - * @note - ****************************************************************************** - */ - -/****************/ -/*** Includes ***/ -/****************/ - -#include "NXPSW_CompilerSwitches.h" -/** - * Our headers */ -#include "M4VSS3GPP_API.h" -#include "M4VSS3GPP_InternalTypes.h" -#include "M4VSS3GPP_InternalFunctions.h" -#include "M4VSS3GPP_InternalConfig.h" -#include "M4VSS3GPP_ErrorCodes.h" - - -/** - * OSAL headers */ -#include "M4OSA_Memory.h" /**< OSAL memory management */ -#include "M4OSA_Debug.h" /**< OSAL debug management */ -#include "M4OSA_CharStar.h" /**< OSAL string management */ - -#ifdef WIN32 -#include "string.h" /**< for strcpy (Don't want to get dependencies - with M4OSA_String...) */ - -#endif /* WIN32 */ -#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS -#include "M4VD_EXTERNAL_Interface.h" -#endif - -/************************************************************************/ -/* Static local functions */ -/************************************************************************/ -static M4OSA_ERR M4VSS3GPP_intClipSettingsSanityCheck( - M4VSS3GPP_ClipSettings *pClip ); -static M4OSA_ERR M4VSS3GPP_intTransitionSettingsSanityCheck( - M4VSS3GPP_TransitionSettings *pTransition ); -static M4OSA_Void M4VSS3GPP_intFreeSettingsList( - M4VSS3GPP_InternalEditContext *pC ); -static M4OSA_ERR -M4VSS3GPP_intCreateMP3OutputFile( M4VSS3GPP_InternalEditContext *pC, - M4OSA_Void *pOutputFile ); -static M4OSA_ERR M4VSS3GPP_intSwitchToNextClip( - M4VSS3GPP_InternalEditContext *pC ); -static M4OSA_ERR -M4VSS3GPP_intComputeOutputVideoAndAudioDsi( M4VSS3GPP_InternalEditContext *pC, - M4OSA_UInt8 uiMasterClip ); -static M4OSA_Void M4VSS3GPP_intComputeOutputAverageVideoBitrate( - M4VSS3GPP_InternalEditContext *pC ); - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_GetVersion() - * @brief Get the VSS 3GPP version. - * @note Can be called anytime. Do not need any context. - * @param pVersionInfo (OUT) Pointer to a version info structure - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pVersionInfo is M4OSA_NULL (If Debug Level >= 2) - ****************************************************************************** - */ -M4OSA_ERR M4VSS3GPP_GetVersion( M4_VersionInfo *pVersionInfo ) -{ - M4OSA_TRACE3_1("M4VSS3GPP_GetVersion called with pVersionInfo=0x%x", - pVersionInfo); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pVersionInfo), M4ERR_PARAMETER, - "M4VSS3GPP_GetVersion: pVersionInfo is M4OSA_NULL"); - - pVersionInfo->m_major = M4VSS_VERSION_MAJOR; - pVersionInfo->m_minor = M4VSS_VERSION_MINOR; - pVersionInfo->m_revision = M4VSS_VERSION_REVISION; - - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_editInit() - * @brief Initializes the VSS 3GPP edit operation (allocates an execution context). - * @note - * @param pContext (OUT) Pointer on the VSS 3GPP edit context to allocate - * @param pFileReadPtrFct (IN) Pointer to OSAL file reader functions - * @param pFileWritePtrFct (IN) Pointer to OSAL file writer functions - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL - * @return M4ERR_ALLOC: There is no more available memory - ****************************************************************************** - */ -M4OSA_ERR M4VSS3GPP_editInit( M4VSS3GPP_EditContext *pContext, - M4OSA_FileReadPointer *pFileReadPtrFct, - M4OSA_FileWriterPointer *pFileWritePtrFct ) -{ - M4VSS3GPP_InternalEditContext *pC; - M4OSA_ERR err; - M4OSA_UInt32 i; - - M4OSA_TRACE3_3( - "M4VSS3GPP_editInit called with pContext=0x%x, \ - pFileReadPtrFct=0x%x, pFileWritePtrFct=0x%x", - pContext, pFileReadPtrFct, pFileWritePtrFct); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4VSS3GPP_editInit: pContext is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pFileReadPtrFct), M4ERR_PARAMETER, - "M4VSS3GPP_editInit: pFileReadPtrFct is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pFileWritePtrFct), M4ERR_PARAMETER, - "M4VSS3GPP_editInit: pFileWritePtrFct is M4OSA_NULL"); - - /** - * Allocate the VSS context and return it to the user */ - pC = (M4VSS3GPP_InternalEditContext - *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_InternalEditContext), - M4VSS3GPP, (M4OSA_Char *)"M4VSS3GPP_InternalContext"); - *pContext = pC; - /* Inialization of context Variables */ - memset((void *)pC, 0,sizeof(M4VSS3GPP_InternalEditContext)); - - if( M4OSA_NULL == pC ) - { - M4OSA_TRACE1_0( - "M4VSS3GPP_editInit(): unable to allocate M4VSS3GPP_InternalContext,\ - returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - - - /* Init the context. */ - pC->uiClipNumber = 0; - pC->pClipList = M4OSA_NULL; - pC->pTransitionList = M4OSA_NULL; - pC->pEffectsList = M4OSA_NULL; - pC->pActiveEffectsList = M4OSA_NULL; - pC->pActiveEffectsList1 = M4OSA_NULL; - pC->bClip1ActiveFramingEffect = M4OSA_FALSE; - pC->bClip2ActiveFramingEffect = M4OSA_FALSE; - pC->uiCurrentClip = 0; - pC->pC1 = M4OSA_NULL; - pC->pC2 = M4OSA_NULL; - pC->yuv1[0].pac_data = pC->yuv1[1].pac_data = pC-> - yuv1[2].pac_data = M4OSA_NULL; - pC->yuv2[0].pac_data = pC->yuv2[1].pac_data = pC-> - yuv2[2].pac_data = M4OSA_NULL; - pC->yuv3[0].pac_data = pC->yuv3[1].pac_data = pC-> - yuv3[2].pac_data = M4OSA_NULL; - pC->yuv4[0].pac_data = pC->yuv4[1].pac_data = pC-> - yuv4[2].pac_data = M4OSA_NULL; - pC->bClip1AtBeginCut = M4OSA_FALSE; - pC->iClip1ActiveEffect = 0; - pC->iClip2ActiveEffect = 0; - pC->bTransitionEffect = M4OSA_FALSE; - pC->bSupportSilence = M4OSA_FALSE; - - /** - * Init PC->ewc members */ - // Decorrelate input and output encoding timestamp to handle encoder prefetch - pC->ewc.dInputVidCts = 0.0; - pC->ewc.dOutputVidCts = 0.0; - pC->ewc.dATo = 0.0; - pC->ewc.iOutputDuration = 0; - pC->ewc.VideoStreamType = M4SYS_kVideoUnknown; - pC->ewc.uiVideoBitrate = 0; - pC->ewc.uiVideoWidth = 0; - pC->ewc.uiVideoHeight = 0; - pC->ewc.uiVideoTimeScale = 0; - pC->ewc.bVideoDataPartitioning = M4OSA_FALSE; - pC->ewc.pVideoOutputDsi = M4OSA_NULL; - pC->ewc.uiVideoOutputDsiSize = 0; - pC->ewc.AudioStreamType = M4SYS_kAudioUnknown; - pC->ewc.uiNbChannels = 1; - pC->ewc.uiAudioBitrate = 0; - pC->ewc.uiSamplingFrequency = 0; - pC->ewc.pAudioOutputDsi = M4OSA_NULL; - pC->ewc.uiAudioOutputDsiSize = 0; - pC->ewc.pAudioEncCtxt = M4OSA_NULL; - pC->ewc.pAudioEncDSI.infoSize = 0; - pC->ewc.pAudioEncDSI.pInfo = M4OSA_NULL; - pC->ewc.uiSilencePcmSize = 0; - pC->ewc.pSilenceFrameData = M4OSA_NULL; - pC->ewc.uiSilenceFrameSize = 0; - pC->ewc.iSilenceFrameDuration = 0; - pC->ewc.scale_audio = 0.0; - pC->ewc.pEncContext = M4OSA_NULL; - pC->ewc.pDummyAuBuffer = M4OSA_NULL; - pC->ewc.iMpeg4GovOffset = 0; - pC->ewc.VppError = 0; - pC->ewc.encoderState = M4VSS3GPP_kNoEncoder; - pC->ewc.p3gpWriterContext = M4OSA_NULL; - pC->ewc.uiVideoMaxAuSize = 0; - pC->ewc.uiAudioMaxAuSize = 0; - /** - * Keep the OSAL file functions pointer set in our context */ - pC->pOsaFileReadPtr = pFileReadPtrFct; - pC->pOsaFileWritPtr = pFileWritePtrFct; - - /* - * Reset pointers for media and codecs interfaces */ - - err = M4VSS3GPP_clearInterfaceTables(&pC->ShellAPI); - M4ERR_CHECK_RETURN(err); - - /* - * Call the media and codecs subscription module */ - err = M4VSS3GPP_subscribeMediaAndCodec(&pC->ShellAPI); - M4ERR_CHECK_RETURN(err); - - /** - * Update main state automaton */ - pC->State = M4VSS3GPP_kEditState_CREATED; - pC->Vstate = M4VSS3GPP_kEditVideoState_READ_WRITE; - pC->Astate = M4VSS3GPP_kEditAudioState_READ_WRITE; - /* The flag is set to false at the beginning of every clip */ - pC->m_bClipExternalHasStarted = M4OSA_FALSE; - - pC->bIsMMS = M4OSA_FALSE; - - pC->iInOutTimeOffset = 0; - pC->bEncodeTillEoF = M4OSA_FALSE; - pC->nbActiveEffects = 0; - pC->nbActiveEffects1 = 0; - pC->bIssecondClip = M4OSA_FALSE; - pC->m_air_context = M4OSA_NULL; - /** - * Return with no error */ - M4OSA_TRACE3_0("M4VSS3GPP_editInit(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_editCreateClipSettings() - * @brief Allows filling a clip settings structure with default values - * - * @note WARNING: pClipSettings->Effects[ ] will be allocated in this function. - * pClipSettings->pFile will be allocated in this function. - * - * @param pClipSettings (IN) Pointer to a valid M4VSS3GPP_ClipSettings structure - * @param pFile (IN) Clip file name - * @param filePathSize (IN) Clip path size (needed for UTF 16 conversion) - * @param nbEffects (IN) Nb of effect settings to allocate - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pClipSettings is M4OSA_NULL (debug only) - ****************************************************************************** - */ -M4OSA_ERR -M4VSS3GPP_editCreateClipSettings( M4VSS3GPP_ClipSettings *pClipSettings, - M4OSA_Void *pFile, M4OSA_UInt32 filePathSize, - M4OSA_UInt8 nbEffects ) -{ - M4OSA_UInt8 uiFx; - - M4OSA_TRACE3_1( - "M4VSS3GPP_editCreateClipSettings called with pClipSettings=0x%p", - pClipSettings); - - /** - * Check input parameter */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettings), M4ERR_PARAMETER, - "M4VSS3GPP_editCreateClipSettings: pClipSettings is NULL"); - - /** - * Set the clip settings to default */ - pClipSettings->pFile = M4OSA_NULL; /**< no file */ - pClipSettings->FileType = - M4VIDEOEDITING_kFileType_Unsupported; /**< undefined */ - - if( M4OSA_NULL != pFile ) - { - //pClipSettings->pFile = (M4OSA_Char*) M4OSA_32bitAlignedMalloc(strlen(pFile)+1, M4VSS3GPP, - // "pClipSettings->pFile"); - /*FB: add clip path size because of utf 16 conversion*/ - pClipSettings->pFile = - (M4OSA_Void *)M4OSA_32bitAlignedMalloc(filePathSize + 1, M4VSS3GPP, - (M4OSA_Char *)"pClipSettings->pFile"); - - if( M4OSA_NULL == pClipSettings->pFile ) - { - M4OSA_TRACE1_0( - "M4VSS3GPP_editCreateClipSettings : ERROR allocating filename"); - return M4ERR_ALLOC; - } - //memcpy(pClipSettings->pFile, pFile, strlen(pFile)+1); - /*FB: add clip path size because of utf 16 conversion*/ - memcpy((void *)pClipSettings->pFile, (void *)pFile, filePathSize + 1); - } - - /*FB: add file path size to support UTF16 conversion*/ - pClipSettings->filePathSize = filePathSize + 1; - /**/ - pClipSettings->ClipProperties.bAnalysed = M4OSA_FALSE; - pClipSettings->ClipProperties.FileType = 0; - pClipSettings->ClipProperties.Version[0] = 0; - pClipSettings->ClipProperties.Version[1] = 0; - pClipSettings->ClipProperties.Version[2] = 0; - pClipSettings->ClipProperties.uiClipDuration = 0; - - pClipSettings->uiBeginCutTime = 0; /**< no begin cut */ - pClipSettings->uiEndCutTime = 0; /**< no end cut */ - pClipSettings->ClipProperties.bSetImageData = M4OSA_FALSE; - - /** - * Reset video characteristics */ - pClipSettings->ClipProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo; - pClipSettings->ClipProperties.uiClipVideoDuration = 0; - pClipSettings->ClipProperties.uiVideoBitrate = 0; - pClipSettings->ClipProperties.uiVideoMaxAuSize = 0; - pClipSettings->ClipProperties.uiVideoWidth = 0; - pClipSettings->ClipProperties.uiVideoHeight = 0; - pClipSettings->ClipProperties.uiVideoTimeScale = 0; - pClipSettings->ClipProperties.fAverageFrameRate = 0.0; - pClipSettings->ClipProperties.uiVideoProfile = - M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE; - pClipSettings->ClipProperties.uiVideoLevel = - M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL; - pClipSettings->ClipProperties.bMPEG4dataPartition = M4OSA_FALSE; - pClipSettings->ClipProperties.bMPEG4rvlc = M4OSA_FALSE; - pClipSettings->ClipProperties.bMPEG4resynchMarker = M4OSA_FALSE; - - /** - * Reset audio characteristics */ - pClipSettings->ClipProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio; - pClipSettings->ClipProperties.uiClipAudioDuration = 0; - pClipSettings->ClipProperties.uiAudioBitrate = 0; - pClipSettings->ClipProperties.uiAudioMaxAuSize = 0; - pClipSettings->ClipProperties.uiNbChannels = 0; - pClipSettings->ClipProperties.uiSamplingFrequency = 0; - pClipSettings->ClipProperties.uiExtendedSamplingFrequency = 0; - pClipSettings->ClipProperties.uiDecodedPcmSize = 0; - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4VSS3GPP_editSetDefaultSettings(): returning M4NO_ERROR"); - - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_editDuplicateClipSettings() - * @brief Duplicates a clip settings structure, performing allocations if required - * - * @param pClipSettingsDest (IN) Pointer to a valid M4VSS3GPP_ClipSettings structure - * @param pClipSettingsOrig (IN) Pointer to a valid M4VSS3GPP_ClipSettings structure - * @param bCopyEffects (IN) Flag to know if we have to duplicate effects - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pClipSettings is M4OSA_NULL (debug only) - ****************************************************************************** - */ -M4OSA_ERR -M4VSS3GPP_editDuplicateClipSettings( M4VSS3GPP_ClipSettings *pClipSettingsDest, - M4VSS3GPP_ClipSettings *pClipSettingsOrig, - M4OSA_Bool bCopyEffects ) -{ - M4OSA_UInt8 uiFx; - - M4OSA_TRACE3_2( - "M4VSS3GPP_editDuplicateClipSettings called with dest=0x%p src=0x%p", - pClipSettingsDest, pClipSettingsOrig); - - /* Check input parameter */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettingsDest), M4ERR_PARAMETER, - "M4VSS3GPP_editDuplicateClipSettings: pClipSettingsDest is NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettingsOrig), M4ERR_PARAMETER, - "M4VSS3GPP_editDuplicateClipSettings: pClipSettingsOrig is NULL"); - - /* Copy plain structure */ - memcpy((void *)pClipSettingsDest, - (void *)pClipSettingsOrig, sizeof(M4VSS3GPP_ClipSettings)); - - /* Duplicate filename */ - if( M4OSA_NULL != pClipSettingsOrig->pFile ) - { - //pClipSettingsDest->pFile = - // (M4OSA_Char*) M4OSA_32bitAlignedMalloc(strlen(pClipSettingsOrig->pFile)+1, M4VSS3GPP, - // "pClipSettingsDest->pFile"); - /*FB: clip path size is needed for utf 16 conversion*/ - /*FB 2008/10/16: bad allocation size which raises a crash*/ - pClipSettingsDest->pFile = - (M4OSA_Char *)M4OSA_32bitAlignedMalloc(pClipSettingsOrig->filePathSize + 1, - M4VSS3GPP, (M4OSA_Char *)"pClipSettingsDest->pFile"); - - if( M4OSA_NULL == pClipSettingsDest->pFile ) - { - M4OSA_TRACE1_0( - "M4VSS3GPP_editDuplicateClipSettings : ERROR allocating filename"); - return M4ERR_ALLOC; - } - /*FB: clip path size is needed for utf 16 conversion*/ - //memcpy(pClipSettingsDest->pFile, pClipSettingsOrig->pFile, - // strlen(pClipSettingsOrig->pFile)+1); - /*FB 2008/10/16: bad allocation size which raises a crash*/ - memcpy((void *)pClipSettingsDest->pFile, (void *)pClipSettingsOrig->pFile, - pClipSettingsOrig->filePathSize/*+1*/); - ( (M4OSA_Char - *)pClipSettingsDest->pFile)[pClipSettingsOrig->filePathSize] = '\0'; - } - - /* Duplicate effects */ - /* Return with no error */ - - M4OSA_TRACE3_0( - "M4VSS3GPP_editDuplicateClipSettings(): returning M4NO_ERROR"); - - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_editFreeClipSettings() - * @brief Free the pointers allocated in the ClipSetting structure (pFile, Effects). - * - * @param pClipSettings (IN) Pointer to a valid M4VSS3GPP_ClipSettings structure - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pClipSettings is M4OSA_NULL (debug only) - ****************************************************************************** - */ -M4OSA_ERR M4VSS3GPP_editFreeClipSettings( - M4VSS3GPP_ClipSettings *pClipSettings ) -{ - /** - * Check input parameter */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettings), M4ERR_PARAMETER, - "M4VSS3GPP_editFreeClipSettings: pClipSettings is NULL"); - - /* free filename */ - if( M4OSA_NULL != pClipSettings->pFile ) - { - free(pClipSettings->pFile); - pClipSettings->pFile = M4OSA_NULL; - } - - /* free effects settings */ - /* if(M4OSA_NULL != pClipSettings->Effects) - { - free(pClipSettings->Effects); - pClipSettings->Effects = M4OSA_NULL; - pClipSettings->nbEffects = 0; - } RC */ - - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_editOpen() - * @brief Set the VSS input and output files. - * @note It opens the input file, but the output file may not be created yet. - * @param pContext (IN) VSS edit context - * @param pSettings (IN) Edit settings - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL (debug only) - * @return M4ERR_STATE: VSS is not in an appropriate state for this function to be called - * @return M4ERR_ALLOC: There is no more available memory - ****************************************************************************** - */ -M4OSA_ERR M4VSS3GPP_editOpen( M4VSS3GPP_EditContext pContext, - M4VSS3GPP_EditSettings *pSettings ) -{ - M4VSS3GPP_InternalEditContext *pC = - (M4VSS3GPP_InternalEditContext *)pContext; - - M4OSA_ERR err; - M4OSA_Int32 i; - M4VIDEOEDITING_FileType outputFileType = - M4VIDEOEDITING_kFileType_Unsupported; /**< 3GPP or MP3 (we don't do AMR output) */ - M4OSA_UInt32 uiC1duration, uiC2duration; - - M4OSA_TRACE3_2( - "M4VSS3GPP_editOpen called with pContext=0x%x, pSettings=0x%x", - pContext, pSettings); - - /** - * Check input parameters */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4VSS3GPP_editOpen: pContext is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pSettings), M4ERR_PARAMETER, - "M4VSS3GPP_editOpen: pSettings is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pSettings->pClipList), M4ERR_PARAMETER, - "M4VSS3GPP_editOpen: pSettings->pClipList is M4OSA_NULL"); - M4OSA_DEBUG_IF2(( pSettings->uiClipNumber > 1) - && (M4OSA_NULL == pSettings->pTransitionList), M4ERR_PARAMETER, - "M4VSS3GPP_editOpen: pSettings->pTransitionList is M4OSA_NULL"); - - /** - * Check state automaton */ - if( ( pC->State != M4VSS3GPP_kEditState_CREATED) - && (pC->State != M4VSS3GPP_kEditState_CLOSED) ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editOpen: State error (0x%x)! Returning M4ERR_STATE", - pC->State); - return M4ERR_STATE; - } - - /** - * Free any previously allocated internal settings list */ - M4VSS3GPP_intFreeSettingsList(pC); - - /** - * Copy the user settings in our context */ - pC->uiClipNumber = pSettings->uiClipNumber; - - /** - * Copy the clip list */ - pC->pClipList = - (M4VSS3GPP_ClipSettings *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_ClipSettings) - * pC->uiClipNumber, M4VSS3GPP, (M4OSA_Char *)"pC->pClipList"); - - if( M4OSA_NULL == pC->pClipList ) - { - M4OSA_TRACE1_0( - "M4VSS3GPP_editOpen: unable to allocate pC->Settings.pClipList,\ - returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - - for ( i = 0; i < pSettings->uiClipNumber; i++ ) - { - M4VSS3GPP_editDuplicateClipSettings(&(pC->pClipList[i]), - pSettings->pClipList[i], M4OSA_TRUE); - } - - /** - * Copy effects list RC */ - - /*FB bug fix 19.03.2008 if the number of effects is 0 -> crash*/ - if( pSettings->nbEffects > 0 ) - { - pC->nbEffects = pSettings->nbEffects; - pC->pEffectsList = (M4VSS3GPP_EffectSettings - *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_EffectSettings) * pC->nbEffects, - M4VSS3GPP, (M4OSA_Char *)"pC->pEffectsList"); - - if( M4OSA_NULL == pC->pEffectsList ) - { - M4OSA_TRACE1_0( - "M4VSS3GPP_editOpen: unable to allocate pC->pEffectsList, returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - - for ( i = 0; i < pC->nbEffects; i++ ) - { - memcpy((void *) &(pC->pEffectsList[i]), - (void *) &(pSettings->Effects[i]), - sizeof(M4VSS3GPP_EffectSettings)); - } - - /** - * Allocate active effects list RC */ - pC->pActiveEffectsList = - (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(sizeof(M4OSA_UInt8) * pC->nbEffects, - M4VSS3GPP, (M4OSA_Char *)"pC->pActiveEffectsList"); - - if( M4OSA_NULL == pC->pActiveEffectsList ) - { - M4OSA_TRACE1_0( - "M4VSS3GPP_editOpen: unable to allocate pC->pActiveEffectsList,\ - returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - /** - * Allocate active effects list */ - pC->pActiveEffectsList1 = - (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(sizeof(M4OSA_UInt8) * pC->nbEffects, - M4VSS3GPP, (M4OSA_Char *)"pC->pActiveEffectsList"); - if (M4OSA_NULL == pC->pActiveEffectsList1) - { - M4OSA_TRACE1_0("M4VSS3GPP_editOpen: unable to allocate pC->pActiveEffectsList, \ - returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - - } - else - { - pC->nbEffects = 0; - pC->nbActiveEffects = 0; - pC->nbActiveEffects1 = 0; - pC->pEffectsList = M4OSA_NULL; - pC->pActiveEffectsList = M4OSA_NULL; - pC->pActiveEffectsList1 = M4OSA_NULL; - pC->bClip1ActiveFramingEffect = M4OSA_FALSE; - pC->bClip2ActiveFramingEffect = M4OSA_FALSE; - } - - /** - * Test the clip analysis data, if it is not provided, analyse the clips by ourselves. */ - for ( i = 0; i < pC->uiClipNumber; i++ ) - { - if( M4OSA_FALSE == pC->pClipList[i].ClipProperties.bAnalysed ) - { - /**< Analysis not provided by the integrator */ - err = M4VSS3GPP_editAnalyseClip(pC->pClipList[i].pFile, - pC->pClipList[i].FileType, &pC->pClipList[i].ClipProperties, - pC->pOsaFileReadPtr); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editOpen: M4VSS3GPP_editAnalyseClip returns 0x%x!", - err); - return err; - } - } - } - - /** - * Check clip compatibility */ - for ( i = 0; i < pC->uiClipNumber; i++ ) - { - if (pC->pClipList[i].FileType !=M4VIDEOEDITING_kFileType_ARGB8888) { - /** - * Check all the clips are compatible with VSS 3GPP */ - err = M4VSS3GPP_intCheckClipCompatibleWithVssEditing( - &pC->pClipList[i].ClipProperties); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_2( - "M4VSS3GPP_editOpen:\ - M4VSS3GPP_intCheckClipCompatibleWithVssEditing(%d) returns 0x%x!", - i, err); - return err; - } - } - - /** - * Check the master clip versus all the other ones. - (including master clip with itself, else variables for master clip - are not properly setted) */ - if(pC->pClipList[i].FileType != M4VIDEOEDITING_kFileType_ARGB8888) { - - err = M4VSS3GPP_editCheckClipCompatibility( - &pC->pClipList[pSettings->uiMasterClip].ClipProperties, - &pC->pClipList[i].ClipProperties); - /* in case of warning regarding audio incompatibility, - editing continues */ - if( M4OSA_ERR_IS_ERROR(err) ) - { - M4OSA_TRACE1_2( - "M4VSS3GPP_editOpen: M4VSS3GPP_editCheckClipCompatibility \ - (%d) returns 0x%x!", i, err); - return err; - } - } else { - pC->pClipList[i].ClipProperties.bAudioIsCompatibleWithMasterClip = - M4OSA_FALSE; - } - } - /* Search audio tracks that cannot be edited : - * - delete all audio effects for the clip - * - if master clip is editable let the transition - (bad track will be replaced later with silence) - * - if master clip is not editable switch to a dummy transition (only copy/paste) */ - for ( i = 0; i < pC->uiClipNumber; i++ ) - { - if( M4OSA_FALSE == pC->pClipList[i].ClipProperties.bAudioIsEditable ) - { - M4OSA_UInt8 uiFx; - - for ( uiFx = 0; uiFx < pC->nbEffects; uiFx++ ) - { - pC->pEffectsList[uiFx].AudioEffectType - = M4VSS3GPP_kAudioEffectType_None; - } - - if( ( i < (pC->uiClipNumber - 1)) - && (M4OSA_NULL != pSettings->pTransitionList[i]) - && (M4OSA_FALSE == pC->pClipList[pSettings-> - uiMasterClip].ClipProperties.bAudioIsEditable) ) - { - pSettings->pTransitionList[i]->AudioTransitionType - = M4VSS3GPP_kAudioTransitionType_None; - } - } - } - - /** - * We add a transition of duration 0 at the end of the last clip. - * It will suppress a whole bunch a test latter in the processing... */ - pC->pTransitionList = (M4VSS3GPP_TransitionSettings - *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_TransitionSettings) - * (pC->uiClipNumber), M4VSS3GPP, (M4OSA_Char *)"pC->pTransitionList"); - - if( M4OSA_NULL == pC->pTransitionList ) - { - M4OSA_TRACE1_0( - "M4VSS3GPP_editOpen: unable to allocate pC->Settings.pTransitionList,\ - returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - - /**< copy transition settings */ - for ( i = 0; i < (pSettings->uiClipNumber - 1); i++ ) - { - memcpy((void *) &(pC->pTransitionList[i]), - (void *)pSettings->pTransitionList[i], - sizeof(M4VSS3GPP_TransitionSettings)); - } - - /**< We fill the last "dummy" transition */ - pC->pTransitionList[pC->uiClipNumber - 1].uiTransitionDuration = 0; - pC->pTransitionList[pC->uiClipNumber - - 1].VideoTransitionType = M4VSS3GPP_kVideoTransitionType_None; - pC->pTransitionList[pC->uiClipNumber - - 1].AudioTransitionType = M4VSS3GPP_kAudioTransitionType_None; - - /** - * Avoid weird clip settings */ - for ( i = 0; i < pSettings->uiClipNumber; i++ ) - { - if (pC->pClipList[i].FileType !=M4VIDEOEDITING_kFileType_ARGB8888) { - err = M4VSS3GPP_intClipSettingsSanityCheck(&pC->pClipList[i]); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editOpen: M4VSS3GPP_intClipSettingsSanityCheck returns 0x%x!", - err); - return err; - } - } - } - - for ( i = 0; i < (pSettings->uiClipNumber - 1); i++ ) - { - if (pC->pTransitionList[i].uiTransitionDuration != 0) { - if (pC->pClipList[i].FileType == M4VIDEOEDITING_kFileType_ARGB8888) { - pC->pClipList[i].uiBeginCutTime = 0; - pC->pClipList[i].uiEndCutTime = - pC->pTransitionList[i].uiTransitionDuration; - } - - if (pC->pClipList[i+1].FileType == M4VIDEOEDITING_kFileType_ARGB8888) { - pC->pClipList[i+1].uiBeginCutTime = 0; - pC->pClipList[i+1].uiEndCutTime = - pC->pTransitionList[i].uiTransitionDuration; - } - } else { - - if (pC->pClipList[i].FileType == M4VIDEOEDITING_kFileType_ARGB8888) { - pC->pClipList[i].uiEndCutTime = - pC->pClipList[i].uiEndCutTime - pC->pClipList[i].uiBeginCutTime; - pC->pClipList[i].uiBeginCutTime = 0; - } - - if (pC->pClipList[i+1].FileType == M4VIDEOEDITING_kFileType_ARGB8888) { - pC->pClipList[i+1].uiEndCutTime = - pC->pClipList[i+1].uiEndCutTime - pC->pClipList[i+1].uiBeginCutTime; - pC->pClipList[i+1].uiBeginCutTime = 0; - } - - } - - /** - * Maximum transition duration between clip n and clip n+1 is the duration - * of the shortest clip */ - if( 0 == pC->pClipList[i].uiEndCutTime ) - { - uiC1duration = pC->pClipList[i].ClipProperties.uiClipVideoDuration; - } - else - { - /**< duration of clip n is the end cut time */ - uiC1duration = pC->pClipList[i].uiEndCutTime; - } - - /**< Substract begin cut */ - uiC1duration -= pC->pClipList[i].uiBeginCutTime; - - /**< Check that the transition is shorter than clip n */ - if( pC->pTransitionList[i].uiTransitionDuration > uiC1duration ) - { - pC->pTransitionList[i].uiTransitionDuration = uiC1duration - 1; - } - - if( 0 == pC->pClipList[i + 1].uiEndCutTime ) - { - uiC2duration = - pC->pClipList[i + 1].ClipProperties.uiClipVideoDuration; - } - else - { - /**< duration of clip n+1 is the end cut time */ - uiC2duration = pC->pClipList[i + 1].uiEndCutTime; - } - - /**< Substract begin cut */ - uiC2duration -= pC->pClipList[i + 1].uiBeginCutTime; - - /**< Check that the transition is shorter than clip n+1 */ - if( pC->pTransitionList[i].uiTransitionDuration > uiC2duration ) - { - pC->pTransitionList[i].uiTransitionDuration = uiC2duration - 1; - } - - /** - * Avoid weird transition settings */ - err = - M4VSS3GPP_intTransitionSettingsSanityCheck(&pC->pTransitionList[i]); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editOpen: M4VSS3GPP_intClipSettingsSanityCheck returns 0x%x!", - err); - return err; - } - - /** - * Check that two transitions are not overlapping - (no overlapping possible for first clip) */ - if( i > 0 ) - { - /** - * There is a transition overlap if the sum of the duration of - two consecutive transitions - * is higher than the duration of the clip in-between. */ - if( ( pC->pTransitionList[i - 1].uiTransitionDuration - + pC->pTransitionList[i].uiTransitionDuration) >= uiC1duration ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editOpen: Overlapping transitions on clip %d,\ - returning M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS", - i); - return M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS; - } - } - } - - /** - * Output clip duration */ - for ( i = 0; i < pC->uiClipNumber; i++ ) - { - /** - * Compute the sum of the clip duration */ - if( 0 == pC->pClipList[i].uiEndCutTime ) - { - pC->ewc.iOutputDuration += - pC-> - pClipList[ - i].ClipProperties. - uiClipVideoDuration; /* Only video track duration is important to - avoid deviation if audio track is longer */ - } - else - { - pC->ewc.iOutputDuration += - pC->pClipList[i].uiEndCutTime; /**< Add end cut */ - } - - pC->ewc.iOutputDuration -= - pC->pClipList[i].uiBeginCutTime; /**< Remove begin cut */ - - /** - * Remove the duration of the transition (it is counted twice) */ - pC->ewc.iOutputDuration -= pC->pTransitionList[i].uiTransitionDuration; - } - - /* Get video properties from output properties */ - - /* Get output width and height */ - switch(pC->xVSS.outputVideoSize) { - case M4VIDEOEDITING_kSQCIF: - pC->ewc.uiVideoWidth = 128; - pC->ewc.uiVideoHeight = 96; - break; - case M4VIDEOEDITING_kQQVGA: - pC->ewc.uiVideoWidth = 160; - pC->ewc.uiVideoHeight = 120; - break; - case M4VIDEOEDITING_kQCIF: - pC->ewc.uiVideoWidth = 176; - pC->ewc.uiVideoHeight = 144; - break; - case M4VIDEOEDITING_kQVGA: - pC->ewc.uiVideoWidth = 320; - pC->ewc.uiVideoHeight = 240; - break; - case M4VIDEOEDITING_kCIF: - pC->ewc.uiVideoWidth = 352; - pC->ewc.uiVideoHeight = 288; - break; - case M4VIDEOEDITING_kVGA: - pC->ewc.uiVideoWidth = 640; - pC->ewc.uiVideoHeight = 480; - break; - /* +PR LV5807 */ - case M4VIDEOEDITING_kWVGA: - pC->ewc.uiVideoWidth = 800; - pC->ewc.uiVideoHeight = 480; - break; - case M4VIDEOEDITING_kNTSC: - pC->ewc.uiVideoWidth = 720; - pC->ewc.uiVideoHeight = 480; - break; - /* -PR LV5807 */ - /* +CR Google */ - case M4VIDEOEDITING_k640_360: - pC->ewc.uiVideoWidth = 640; - pC->ewc.uiVideoHeight = 360; - break; - - case M4VIDEOEDITING_k854_480: - pC->ewc.uiVideoWidth = M4ENCODER_854_480_Width; - pC->ewc.uiVideoHeight = 480; - break; - - case M4VIDEOEDITING_k1280_720: - pC->ewc.uiVideoWidth = 1280; - pC->ewc.uiVideoHeight = 720; - break; - case M4VIDEOEDITING_k1080_720: - pC->ewc.uiVideoWidth = M4ENCODER_1080_720_Width; - - pC->ewc.uiVideoHeight = 720; - break; - case M4VIDEOEDITING_k960_720: - pC->ewc.uiVideoWidth = 960; - pC->ewc.uiVideoHeight = 720; - break; - case M4VIDEOEDITING_k1920_1080: - pC->ewc.uiVideoWidth = 1920; - pC->ewc.uiVideoHeight = 1088; // need to be multiples of 16 - break; - - default: /* If output video size is not given, we take QCIF size */ - M4OSA_TRACE1_0( - "M4VSS3GPP_editOpen: no output video size given, default to QCIF!"); - pC->ewc.uiVideoWidth = 176; - pC->ewc.uiVideoHeight = 144; - pC->xVSS.outputVideoSize = M4VIDEOEDITING_kQCIF; - break; - } - - pC->ewc.uiVideoTimeScale = 30; - pC->ewc.bVideoDataPartitioning = 0; - /* Set output video profile and level */ - pC->ewc.outputVideoProfile = pC->xVSS.outputVideoProfile; - pC->ewc.outputVideoLevel = pC->xVSS.outputVideoLevel; - - switch(pC->xVSS.outputVideoFormat) { - case M4VIDEOEDITING_kH263: - pC->ewc.VideoStreamType = M4SYS_kH263; - break; - case M4VIDEOEDITING_kMPEG4: - pC->ewc.VideoStreamType = M4SYS_kMPEG_4; - break; - case M4VIDEOEDITING_kH264: - pC->ewc.VideoStreamType = M4SYS_kH264; - break; - default: - pC->ewc.VideoStreamType = M4SYS_kVideoUnknown; - break; - } - - /** - * Copy the audio properties of the master clip to the output properties */ - pC->ewc.uiNbChannels = - pC->pClipList[pSettings->uiMasterClip].ClipProperties.uiNbChannels; - pC->ewc.uiAudioBitrate = - pC->pClipList[pSettings->uiMasterClip].ClipProperties.uiAudioBitrate; - pC->ewc.uiSamplingFrequency = pC->pClipList[pSettings-> - uiMasterClip].ClipProperties.uiSamplingFrequency; - pC->ewc.uiSilencePcmSize = - pC->pClipList[pSettings->uiMasterClip].ClipProperties.uiDecodedPcmSize; - pC->ewc.scale_audio = pC->ewc.uiSamplingFrequency / 1000.0; - - switch( pC->pClipList[pSettings->uiMasterClip].ClipProperties.AudioStreamType ) - { - case M4VIDEOEDITING_kAMR_NB: - pC->ewc.AudioStreamType = M4SYS_kAMR; - pC->ewc.pSilenceFrameData = - (M4OSA_UInt8 *)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048; - pC->ewc.uiSilenceFrameSize = - M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE; - pC->ewc.iSilenceFrameDuration = - M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_DURATION; - pC->bSupportSilence = M4OSA_TRUE; - break; - - case M4VIDEOEDITING_kAAC: - case M4VIDEOEDITING_kAACplus: - case M4VIDEOEDITING_keAACplus: - pC->ewc.AudioStreamType = M4SYS_kAAC; - - if( pC->ewc.uiNbChannels == 1 ) - { - pC->ewc.pSilenceFrameData = - (M4OSA_UInt8 *)M4VSS3GPP_AAC_AU_SILENCE_MONO; - pC->ewc.uiSilenceFrameSize = M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE; - pC->bSupportSilence = M4OSA_TRUE; - } - else - { - pC->ewc.pSilenceFrameData = - (M4OSA_UInt8 *)M4VSS3GPP_AAC_AU_SILENCE_STEREO; - pC->ewc.uiSilenceFrameSize = - M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE; - pC->bSupportSilence = M4OSA_TRUE; - } - pC->ewc.iSilenceFrameDuration = - 1024; /* AAC is always 1024/Freq sample duration */ - break; - - case M4VIDEOEDITING_kMP3: - pC->ewc.AudioStreamType = M4SYS_kMP3; - pC->ewc.pSilenceFrameData = M4OSA_NULL; - pC->ewc.uiSilenceFrameSize = 0; - pC->ewc.iSilenceFrameDuration = 0; - /* Special case, mp3 core reader return a time in ms */ - pC->ewc.scale_audio = 1.0; - break; - - case M4VIDEOEDITING_kEVRC: - pC->ewc.AudioStreamType = M4SYS_kEVRC; - pC->ewc.pSilenceFrameData = M4OSA_NULL; - pC->ewc.uiSilenceFrameSize = 0; - pC->ewc.iSilenceFrameDuration = 160; /* EVRC frames are 20 ms at 8000 Hz - (makes it easier to factorize amr and evrc code) */ - break; - - default: - pC->ewc.AudioStreamType = M4SYS_kAudioUnknown; - break; - } - - for (i=0; i<pC->uiClipNumber; i++) { - if (pC->pClipList[i].bTranscodingRequired == M4OSA_FALSE) { - /** If not transcoded in Analysis phase, check - * if transcoding required now - */ - if ((pC->pClipList[i].ClipProperties.VideoStreamType != - pC->xVSS.outputVideoFormat)|| - (pC->pClipList[i].ClipProperties.uiVideoWidth != - pC->ewc.uiVideoWidth) || - (pC->pClipList[i].ClipProperties.uiVideoHeight != - pC->ewc.uiVideoHeight) || - (pC->pClipList[i].ClipProperties.VideoStreamType == - M4VIDEOEDITING_kH264) || - (pC->pClipList[i].ClipProperties.VideoStreamType == - M4VIDEOEDITING_kMPEG4 && - pC->pClipList[i].ClipProperties.uiVideoTimeScale != - pC->ewc.uiVideoTimeScale)) { - pC->pClipList[i].bTranscodingRequired = M4OSA_TRUE; - } - } else { - /** If bTranscodingRequired is true, it means the clip has - * been transcoded in Analysis phase. - */ - pC->pClipList[i].bTranscodingRequired = M4OSA_FALSE; - } - } - /** - * We produce a 3gpp file, unless it is mp3 */ - if( M4VIDEOEDITING_kMP3 == pC-> - pClipList[pSettings->uiMasterClip].ClipProperties.AudioStreamType ) - outputFileType = M4VIDEOEDITING_kFileType_MP3; - else - outputFileType = M4VIDEOEDITING_kFileType_3GPP; - - /** - * Beware, a null duration would lead to a divide by zero error (better safe than sorry...) */ - if( 0 == pC->ewc.iOutputDuration ) - { - pC->ewc.iOutputDuration = 1; - } - - /** - * Open first clip */ - pC->uiCurrentClip = 0; - - // Decorrelate input and output encoding timestamp to handle encoder prefetch - pC->ewc.dInputVidCts = 0.0; - pC->ewc.dOutputVidCts = 0.0; - pC->ewc.dATo = 0.0; - - err = M4VSS3GPP_intSwitchToNextClip(pC); - /* RC: to know when a file has been processed */ - if( M4NO_ERROR != err && err != M4VSS3GPP_WAR_SWITCH_CLIP ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editOpen: M4VSS3GPP_intSwitchToNextClip() returns 0x%x!", - err); - return err; - } - - /** - * Do the video stuff in 3GPP Audio/Video case */ - if( M4VIDEOEDITING_kFileType_3GPP == outputFileType ) - { - /** - * Compute the Decoder Specific Info for the output video and audio streams */ - err = M4VSS3GPP_intComputeOutputVideoAndAudioDsi(pC, - pSettings->uiMasterClip); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editOpen: M4VSS3GPP_intComputeOutputVideoAndAudioDsi() returns 0x%x!", - err); - return err; - } - - /** - * Compute the time increment for the transition file */ - switch( pSettings->videoFrameRate ) - { - case M4VIDEOEDITING_k5_FPS: - pC->dOutputFrameDuration = 1000.0 / 5.0; - break; - - case M4VIDEOEDITING_k7_5_FPS: - pC->dOutputFrameDuration = 1000.0 / 7.5; - break; - - case M4VIDEOEDITING_k10_FPS: - pC->dOutputFrameDuration = 1000.0 / 10.0; - break; - - case M4VIDEOEDITING_k12_5_FPS: - pC->dOutputFrameDuration = 1000.0 / 12.5; - break; - - case M4VIDEOEDITING_k15_FPS: - pC->dOutputFrameDuration = 1000.0 / 15.0; - break; - - case M4VIDEOEDITING_k20_FPS: - pC->dOutputFrameDuration = 1000.0 / 20.0; - break; - - case M4VIDEOEDITING_k25_FPS: - pC->dOutputFrameDuration = 1000.0 / 25.0; - break; - - case M4VIDEOEDITING_k30_FPS: - pC->dOutputFrameDuration = 1000.0 / 30.0; - break; - - default: - M4OSA_TRACE1_1( - "M4VSS3GPP_editOpen(): invalid videoFrameRate (0x%x),\ - returning M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE", - pSettings->videoFrameRate); - return M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE; - } - - if( M4SYS_kMPEG_4 == pC->ewc.VideoStreamType ) - { - M4OSA_UInt32 uiAlpha; - /** - * MPEG-4 case. - * Time scale of the transition encoder must be the same than the - * timescale of the input files. - * So the frame duration must be compatible with this time scale, - * but without beeing too short. - * For that, we must compute alpha (integer) so that: - * (alpha x 1000)/EncoderTimeScale > MinFrameDuration - **/ - - uiAlpha = (M4OSA_UInt32)(( pC->dOutputFrameDuration - * pC->ewc.uiVideoTimeScale) / 1000.0 + 0.5); - - if( uiAlpha > 0 ) - { - pC->dOutputFrameDuration = - ( uiAlpha * 1000.0) / pC->ewc.uiVideoTimeScale; - } - } - else if( M4SYS_kH263 == pC->ewc.VideoStreamType ) - { - switch( pSettings->videoFrameRate ) - { - case M4VIDEOEDITING_k12_5_FPS: - case M4VIDEOEDITING_k20_FPS: - case M4VIDEOEDITING_k25_FPS: - M4OSA_TRACE1_0( - "M4VSS3GPP_editOpen(): invalid videoFrameRate for H263,\ - returning M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE"); - return M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE; - default: - break; - } - } - } - - /** - * Create the MP3 output file */ - if( M4VIDEOEDITING_kFileType_MP3 == outputFileType ) - { - M4READER_Buffer mp3tagBuffer; - err = M4VSS3GPP_intCreateMP3OutputFile(pC, pSettings->pOutputFile); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editOpen: M4VSS3GPP_intCreateMP3OutputFile returns 0x%x", - err); - return err; - } - - /* The ID3v2 tag could be at any place in the mp3 file */ - /* The mp3 reader only checks few bytes in the beginning of - stream to look for a ID3v2 tag */ - /* It means that if the ID3v2 tag is not at the beginning of the file the reader do - as there is no these metadata */ - - /* Retrieve the data of the ID3v2 Tag */ - err = pC->pC1->ShellAPI.m_pReader->m_pFctGetOption( - pC->pC1->pReaderContext, M4READER_kOptionID_Mp3Id3v2Tag, - (M4OSA_DataOption) &mp3tagBuffer); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1("M4VSS3GPP_editOpen: M4MP3R_getOption returns 0x%x", - err); - return err; - } - - /* Write the data of the ID3v2 Tag in the output file */ - if( 0 != mp3tagBuffer.m_uiBufferSize ) - { - err = pC->pOsaFileWritPtr->writeData(pC->ewc.p3gpWriterContext, - (M4OSA_MemAddr8)mp3tagBuffer.m_pData, mp3tagBuffer.m_uiBufferSize); - - /** - * Free before the error checking anyway */ - free(mp3tagBuffer.m_pData); - - /** - * Error checking */ - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editOpen: WriteData(ID3v2Tag) returns 0x%x", - err); - return err; - } - - mp3tagBuffer.m_uiBufferSize = 0; - mp3tagBuffer.m_pData = M4OSA_NULL; - } - } - /** - * Create the 3GPP output file */ - else if( M4VIDEOEDITING_kFileType_3GPP == outputFileType ) - { - pC->ewc.uiVideoBitrate = pSettings->xVSS.outputVideoBitrate; - - /** - * 11/12/2008 CR3283 MMS use case in VideoArtist: Set max output file size if needed */ - if( pC->bIsMMS == M4OSA_TRUE ) - { - err = M4VSS3GPP_intCreate3GPPOutputFile(&pC->ewc, &pC->ShellAPI, - pC->pOsaFileWritPtr, pSettings->pOutputFile, - pC->pOsaFileReadPtr, pSettings->pTemporaryFile, - pSettings->xVSS.outputFileSize); - } - else - { - err = M4VSS3GPP_intCreate3GPPOutputFile(&pC->ewc, &pC->ShellAPI, - pC->pOsaFileWritPtr, pSettings->pOutputFile, - pC->pOsaFileReadPtr, pSettings->pTemporaryFile, 0); - } - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editOpen: M4VSS3GPP_intCreate3GPPOutputFile returns 0x%x", - err); - return err; - } - } - /** - * Default error case */ - else - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editOpen: invalid outputFileType = 0x%x,\ - returning M4VSS3GPP_ERR_OUTPUT_FILE_TYPE_ERROR", - outputFileType); - return - M4VSS3GPP_ERR_OUTPUT_FILE_TYPE_ERROR; /**< this is an internal error code - unknown to the user */ - } - - /** - * Initialize state */ - if( M4SYS_kMP3 == pC->ewc.AudioStreamType ) - { - /** - * In the MP3 case we use a special audio state */ - pC->State = M4VSS3GPP_kEditState_MP3_JUMP; - } - else - { - /** - * We start with the video processing */ - pC->State = M4VSS3GPP_kEditState_VIDEO; - } - - /** - * Initialize state. - * The first clip is independant to the "virtual previous clips", - * so it's like if we where in Read/Write mode before it. */ - pC->Vstate = M4VSS3GPP_kEditVideoState_READ_WRITE; - pC->Astate = M4VSS3GPP_kEditAudioState_READ_WRITE; - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4VSS3GPP_editOpen(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_editStep() - * @brief Perform one step of editing. - * @note - * @param pContext (IN) VSS 3GPP edit context - * @param pProgress (OUT) Progress percentage (0 to 100) of the editing operation - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) - * @return M4ERR_STATE: VSS 3GPP is not in an appropriate state for this - * function to be called - * @return M4VSS3GPP_WAR_EDITING_DONE: Edition is done, user should now call - * M4VSS3GPP_editClose() - ****************************************************************************** - */ -M4OSA_ERR M4VSS3GPP_editStep( M4VSS3GPP_EditContext pContext, - M4OSA_UInt8 *pProgress ) -{ - M4VSS3GPP_InternalEditContext *pC = - (M4VSS3GPP_InternalEditContext *)pContext; - M4OSA_UInt32 uiProgressAudio, uiProgressVideo, uiProgress; - M4OSA_ERR err; - - M4OSA_TRACE3_1("M4VSS3GPP_editStep called with pContext=0x%x", pContext); - - /** - * Check input parameter */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4VSS3GPP_editStep: pContext is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pProgress), M4ERR_PARAMETER, - "M4VSS3GPP_editStep: pProgress is M4OSA_NULL"); - - /** - * Check state automaton and select correct processing */ - switch( pC->State ) - { - case M4VSS3GPP_kEditState_VIDEO: - err = M4VSS3GPP_intEditStepVideo(pC); - break; - - case M4VSS3GPP_kEditState_AUDIO: - err = M4VSS3GPP_intEditStepAudio(pC); - break; - - case M4VSS3GPP_kEditState_MP3: - err = M4VSS3GPP_intEditStepMP3(pC); - break; - - case M4VSS3GPP_kEditState_MP3_JUMP: - err = M4VSS3GPP_intEditJumpMP3(pC); - break; - - default: - M4OSA_TRACE1_0( - "M4VSS3GPP_editStep(): invalid internal state (0x%x), returning M4ERR_STATE"); - return M4ERR_STATE; - } - - /** - * Compute progress. - * We do the computing with 32bits precision because in some (very) extreme case, we may get - * values higher than 256 (...) */ - uiProgressAudio = - ( (M4OSA_UInt32)(pC->ewc.dATo * 100)) / pC->ewc.iOutputDuration; - // Decorrelate input and output encoding timestamp to handle encoder prefetch - uiProgressVideo = ((M4OSA_UInt32)(pC->ewc.dInputVidCts * 100)) / pC->ewc.iOutputDuration; - - uiProgress = uiProgressAudio + uiProgressVideo; - - if( ( pC->ewc.AudioStreamType != M4SYS_kAudioUnknown) - && (pC->ewc.VideoStreamType != M4SYS_kVideoUnknown) ) - uiProgress /= 2; - - /** - * Sanity check */ - if( uiProgress > 100 ) - { - *pProgress = 100; - } - else - { - *pProgress = (M4OSA_UInt8)uiProgress; - } - - /** - * Return the error */ - M4OSA_TRACE3_1("M4VSS3GPP_editStep(): returning 0x%x", err); - return err; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_editClose() - * @brief Finish the VSS edit operation. - * @note The output 3GPP file is ready to be played after this call - * @param pContext (IN) VSS edit context - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) - * @return M4ERR_STATE: VSS is not in an appropriate state for this function to be called - ****************************************************************************** - */ -M4OSA_ERR M4VSS3GPP_editClose( M4VSS3GPP_EditContext pContext ) -{ - M4VSS3GPP_InternalEditContext *pC = - (M4VSS3GPP_InternalEditContext *)pContext; - M4OSA_ERR err; - M4OSA_ERR returnedError = M4NO_ERROR; - M4OSA_UInt32 lastCTS; - - M4OSA_TRACE3_1("M4VSS3GPP_editClose called with pContext=0x%x", pContext); - - /** - * Check input parameter */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER, - "M4VSS3GPP_editClose: pContext is M4OSA_NULL"); - - /** - * Check state automaton. - * In "theory", we should not authorize closing if we are in CREATED state. - * But in practice, in case the opening failed, it may have been partially done. - * In that case we have to free some opened ressources by calling Close. */ - if( M4VSS3GPP_kEditState_CLOSED == pC->State ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editClose: Wrong state (0x%x), returning M4ERR_STATE", - pC->State); - return M4ERR_STATE; - } - - /** - * There may be an encoder to destroy */ - err = M4VSS3GPP_intDestroyVideoEncoder(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editClose: M4VSS3GPP_editDestroyVideoEncoder() returns 0x%x!", - err); - /**< We do not return the error here because we still have stuff to free */ - returnedError = err; - } - - /** - * Close the output file */ - if( M4SYS_kMP3 == pC->ewc.AudioStreamType ) - { - /** - * MP3 case */ - if( M4OSA_NULL != pC->ewc.p3gpWriterContext ) - { - err = pC->pOsaFileWritPtr->closeWrite(pC->ewc.p3gpWriterContext); - pC->ewc.p3gpWriterContext = M4OSA_NULL; - } - } - else - { - /** - * Close the output 3GPP clip, if it has been opened */ - if( M4OSA_NULL != pC->ewc.p3gpWriterContext ) - { - /* Update last Video CTS */ - lastCTS = pC->ewc.iOutputDuration; - - err = pC->ShellAPI.pWriterGlobalFcts->pFctSetOption( - pC->ewc.p3gpWriterContext, - (M4OSA_UInt32)M4WRITER_kMaxFileDuration, &lastCTS); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editClose: SetOption(M4WRITER_kMaxFileDuration) returns 0x%x", - err); - } - - err = pC->ShellAPI.pWriterGlobalFcts->pFctCloseWrite( - pC->ewc.p3gpWriterContext); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editClose: pFctCloseWrite(OUT) returns 0x%x!", - err); - /**< We do not return the error here because we still have stuff to free */ - if( M4NO_ERROR - == returnedError ) /**< we return the first error that happened */ - { - returnedError = err; - } - } - pC->ewc.p3gpWriterContext = M4OSA_NULL; - } - } - - /** - * Free the output video DSI, if it has been created */ - if( M4OSA_NULL != pC->ewc.pVideoOutputDsi ) - { - free(pC->ewc.pVideoOutputDsi); - pC->ewc.pVideoOutputDsi = M4OSA_NULL; - } - - /** - * Free the output audio DSI, if it has been created */ - if( M4OSA_NULL != pC->ewc.pAudioOutputDsi ) - { - free(pC->ewc.pAudioOutputDsi); - pC->ewc.pAudioOutputDsi = M4OSA_NULL; - } - - /** - * Close clip1, if needed */ - if( M4OSA_NULL != pC->pC1 ) - { - err = M4VSS3GPP_intClipCleanUp(pC->pC1); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editClose: M4VSS3GPP_intClipCleanUp(C1) returns 0x%x!", - err); - /**< We do not return the error here because we still have stuff to free */ - if( M4NO_ERROR - == returnedError ) /**< we return the first error that happened */ - { - returnedError = err; - } - } - pC->pC1 = M4OSA_NULL; - } - - /** - * Close clip2, if needed */ - if( M4OSA_NULL != pC->pC2 ) - { - err = M4VSS3GPP_intClipCleanUp(pC->pC2); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editClose: M4VSS3GPP_intClipCleanUp(C2) returns 0x%x!", - err); - /**< We do not return the error here because we still have stuff to free */ - if( M4NO_ERROR - == returnedError ) /**< we return the first error that happened */ - { - returnedError = err; - } - } - pC->pC2 = M4OSA_NULL; - } - - /** - * Free the temporary YUV planes */ - if( M4OSA_NULL != pC->yuv1[0].pac_data ) - { - free(pC->yuv1[0].pac_data); - pC->yuv1[0].pac_data = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->yuv1[1].pac_data ) - { - free(pC->yuv1[1].pac_data); - pC->yuv1[1].pac_data = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->yuv1[2].pac_data ) - { - free(pC->yuv1[2].pac_data); - pC->yuv1[2].pac_data = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->yuv2[0].pac_data ) - { - free(pC->yuv2[0].pac_data); - pC->yuv2[0].pac_data = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->yuv2[1].pac_data ) - { - free(pC->yuv2[1].pac_data); - pC->yuv2[1].pac_data = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->yuv2[2].pac_data ) - { - free(pC->yuv2[2].pac_data); - pC->yuv2[2].pac_data = M4OSA_NULL; - } - - /* RC */ - if( M4OSA_NULL != pC->yuv3[0].pac_data ) - { - free(pC->yuv3[0].pac_data); - pC->yuv3[0].pac_data = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->yuv3[1].pac_data ) - { - free(pC->yuv3[1].pac_data); - pC->yuv3[1].pac_data = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->yuv3[2].pac_data ) - { - free(pC->yuv3[2].pac_data); - pC->yuv3[2].pac_data = M4OSA_NULL; - } - - /* RC */ - if( M4OSA_NULL != pC->yuv4[0].pac_data ) - { - free(pC->yuv4[0].pac_data); - pC->yuv4[0].pac_data = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->yuv4[1].pac_data ) - { - free(pC->yuv4[1].pac_data); - pC->yuv4[1].pac_data = M4OSA_NULL; - } - - if( M4OSA_NULL != pC->yuv4[2].pac_data ) - { - free(pC->yuv4[2].pac_data); - pC->yuv4[2].pac_data = M4OSA_NULL; - } - - /** - * RC Free effects list */ - if( pC->pEffectsList != M4OSA_NULL ) - { - free(pC->pEffectsList); - pC->pEffectsList = M4OSA_NULL; - } - - /** - * RC Free active effects list */ - if( pC->pActiveEffectsList != M4OSA_NULL ) - { - free(pC->pActiveEffectsList); - pC->pActiveEffectsList = M4OSA_NULL; - } - /** - * Free active effects list */ - if(pC->pActiveEffectsList1 != M4OSA_NULL) - { - free(pC->pActiveEffectsList1); - pC->pActiveEffectsList1 = M4OSA_NULL; - } - if(pC->m_air_context != M4OSA_NULL) { - free(pC->m_air_context); - pC->m_air_context = M4OSA_NULL; - } - /** - * Update state automaton */ - pC->State = M4VSS3GPP_kEditState_CLOSED; - - /** - * Return with no error */ - M4OSA_TRACE3_1("M4VSS3GPP_editClose(): returning 0x%x", returnedError); - return returnedError; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_editCleanUp() - * @brief Free all resources used by the VSS edit operation. - * @note The context is no more valid after this call - * @param pContext (IN) VSS edit context - * @return M4NO_ERROR: No error - * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only) - ****************************************************************************** - */ -M4OSA_ERR M4VSS3GPP_editCleanUp( M4VSS3GPP_EditContext pContext ) -{ - M4OSA_ERR err; - M4VSS3GPP_InternalEditContext *pC = - (M4VSS3GPP_InternalEditContext *)pContext; - - M4OSA_TRACE3_1("M4VSS3GPP_editCleanUp called with pContext=0x%x", pContext); - - /** - * Check input parameter */ - if( M4OSA_NULL == pContext ) - { - M4OSA_TRACE1_0( - "M4VSS3GPP_editCleanUp(): pContext is M4OSA_NULL, returning M4ERR_PARAMETER"); - return M4ERR_PARAMETER; - } - - /** - * Close, if needed. - * In "theory", we should not close if we are in CREATED state. - * But in practice, in case the opening failed, it may have been partially done. - * In that case we have to free some opened ressources by calling Close. */ - if( M4VSS3GPP_kEditState_CLOSED != pC->State ) - { - M4OSA_TRACE3_0("M4VSS3GPP_editCleanUp(): calling M4VSS3GPP_editClose"); - err = M4VSS3GPP_editClose(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editCleanUp(): M4VSS3GPP_editClose returns 0x%x", - err); - } - } - - /** - * Free the video encoder dummy AU */ - if( M4OSA_NULL != pC->ewc.pDummyAuBuffer ) - { - free(pC->ewc.pDummyAuBuffer); - pC->ewc.pDummyAuBuffer = M4OSA_NULL; - } - - /** - * Free the Audio encoder context */ - if( M4OSA_NULL != pC->ewc.pAudioEncCtxt ) - { - err = pC->ShellAPI.pAudioEncoderGlobalFcts->pFctClose( - pC->ewc.pAudioEncCtxt); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editCleanUp: pAudioEncoderGlobalFcts->pFctClose returns 0x%x", - err); - /**< don't return, we still have stuff to free */ - } - - err = pC->ShellAPI.pAudioEncoderGlobalFcts->pFctCleanUp( - pC->ewc.pAudioEncCtxt); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_editCleanUp: pAudioEncoderGlobalFcts->pFctCleanUp returns 0x%x", - err); - /**< don't return, we still have stuff to free */ - } - - pC->ewc.pAudioEncCtxt = M4OSA_NULL; - } - - /** - * Free the shells interfaces */ - M4VSS3GPP_unRegisterAllWriters(&pC->ShellAPI); - M4VSS3GPP_unRegisterAllEncoders(&pC->ShellAPI); - M4VSS3GPP_unRegisterAllReaders(&pC->ShellAPI); - M4VSS3GPP_unRegisterAllDecoders(&pC->ShellAPI); - - /** - * Free the settings copied in the internal context */ - M4VSS3GPP_intFreeSettingsList(pC); - - /** - * Finally, Free context */ - free(pC); - pC = M4OSA_NULL; - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4VSS3GPP_editCleanUp(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -#ifdef WIN32 -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_GetErrorMessage() - * @brief Return a string describing the given error code - * @note The input string must be already allocated (and long enough!) - * @param err (IN) Error code to get the description from - * @param sMessage (IN/OUT) Allocated string in which the description will be copied - * @return M4NO_ERROR: Input error is from the VSS3GPP module - * @return M4ERR_PARAMETER:Input error is not from the VSS3GPP module - ****************************************************************************** - */ - -M4OSA_ERR M4VSS3GPP_GetErrorMessage( M4OSA_ERR err, M4OSA_Char *sMessage ) -{ - switch( err ) - { - case M4VSS3GPP_WAR_EDITING_DONE: - strcpy(sMessage, "M4VSS3GPP_WAR_EDITING_DONE"); - break; - - case M4VSS3GPP_WAR_END_OF_AUDIO_MIXING: - strcpy(sMessage, "M4VSS3GPP_WAR_END_OF_AUDIO_MIXING"); - break; - - case M4VSS3GPP_WAR_END_OF_EXTRACT_PICTURE: - strcpy(sMessage, "M4VSS3GPP_WAR_END_OF_EXTRACT_PICTURE"); - break; - - case M4VSS3GPP_ERR_INVALID_FILE_TYPE: - strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_FILE_TYPE"); - break; - - case M4VSS3GPP_ERR_INVALID_EFFECT_KIND: - strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_EFFECT_KIND"); - break; - - case M4VSS3GPP_ERR_INVALID_VIDEO_EFFECT_TYPE: - strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_VIDEO_EFFECT_TYPE"); - break; - - case M4VSS3GPP_ERR_INVALID_AUDIO_EFFECT_TYPE: - strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_AUDIO_EFFECT_TYPE"); - break; - - case M4VSS3GPP_ERR_INVALID_VIDEO_TRANSITION_TYPE: - strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_VIDEO_TRANSITION_TYPE"); - break; - - case M4VSS3GPP_ERR_INVALID_AUDIO_TRANSITION_TYPE: - strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_AUDIO_TRANSITION_TYPE"); - break; - - case M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE: - strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE"); - break; - - case M4VSS3GPP_ERR_EXTERNAL_EFFECT_NULL: - strcpy(sMessage, "M4VSS3GPP_ERR_EXTERNAL_EFFECT_NULL"); - break; - - case M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL: - strcpy(sMessage, "M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL"); - break; - - case M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION: - strcpy(sMessage, "M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION"); - break; - - case M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT: - strcpy(sMessage, "M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT"); - break; - - case M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS: - strcpy(sMessage, "M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS"); - break; - - case M4VSS3GPP_ERR_INVALID_3GPP_FILE: - strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_3GPP_FILE"); - break; - - case M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT: - strcpy(sMessage, "M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT"); - break; - - case M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT: - strcpy(sMessage, "M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT"); - break; - - case M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED: - strcpy(sMessage, "M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED"); - break; - - case M4VSS3GPP_ERR_INPUT_VIDEO_AU_TOO_LARGE: - strcpy(sMessage, "M4VSS3GPP_ERR_INPUT_VIDEO_AU_TOO_LARGE"); - break; - - case M4VSS3GPP_ERR_INPUT_AUDIO_AU_TOO_LARGE: - strcpy(sMessage, "M4VSS3GPP_ERR_INPUT_AUDIO_AU_TOO_LARGE"); - break; - - case M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU: - strcpy(sMessage, "M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU"); - break; - - case M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR: - strcpy(sMessage, "M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR"); - break; - - case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT: - strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT"); - break; - - case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE: - strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE"); - break; - - case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE: - strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE"); - break; - - case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC: - strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC"); - break; - - case M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT: - strcpy(sMessage, "M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT"); - break; - - case M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE: - strcpy(sMessage, - "M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE"); - break; - - case M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE: - strcpy(sMessage, - "M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE"); - break; - - case M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION: - strcpy(sMessage, "M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION"); - break; - - case M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT: - strcpy(sMessage, "M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT"); - break; - - case M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE: - strcpy(sMessage, "M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE"); - break; - - case M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE: - strcpy(sMessage, "M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE"); - break; - - case M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING: - strcpy(sMessage, - "M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING"); - break; - - case M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY: - strcpy(sMessage, "M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY"); - break; - - case M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_STREAM_TYPE: - strcpy(sMessage, "M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_STREAM_TYPE"); - break; - - case M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS: - strcpy(sMessage, "M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS"); - break; - - case M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY: - strcpy(sMessage, - "M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY"); - break; - - case M4VSS3GPP_ERR_NO_SUPPORTED_STREAM_IN_FILE: - strcpy(sMessage, "M4VSS3GPP_ERR_NO_SUPPORTED_STREAM_IN_FILE"); - break; - - case M4VSS3GPP_ERR_ADDVOLUME_EQUALS_ZERO: - strcpy(sMessage, "M4VSS3GPP_ERR_ADDVOLUME_EQUALS_ZERO"); - break; - - case M4VSS3GPP_ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION: - strcpy(sMessage, "M4VSS3GPP_ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION"); - break; - - case M4VSS3GPP_ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT: - strcpy(sMessage, "M4VSS3GPP_ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT"); - break; - - case M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM: - strcpy(sMessage, "M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM"); - break; - - case M4VSS3GPP_ERR_AUDIO_MIXING_UNSUPPORTED: - strcpy(sMessage, "M4VSS3GPP_ERR_AUDIO_MIXING_UNSUPPORTED"); - break; - - case M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK: - strcpy(sMessage, - "M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK"); - break; - - case M4VSS3GPP_ERR_AUDIO_CANNOT_BE_MIXED: - strcpy(sMessage, "M4VSS3GPP_ERR_AUDIO_CANNOT_BE_MIXED"); - break; - - case M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP: - strcpy(sMessage, "M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP"); - break; - - case M4VSS3GPP_ERR_BEGINLOOP_HIGHER_ENDLOOP: - strcpy(sMessage, "M4VSS3GPP_ERR_BEGINLOOP_HIGHER_ENDLOOP"); - break; - - case M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED: - strcpy(sMessage, "M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED"); - break; - - case M4VSS3GPP_ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE: - strcpy(sMessage, "M4VSS3GPP_ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE"); - break; - - default: /**< Not a VSS3GPP error */ - strcpy(sMessage, ""); - return M4ERR_PARAMETER; - } - return M4NO_ERROR; -} - -#endif /* WIN32 */ - -/********************************************************/ -/********************************************************/ -/********************************************************/ -/**************** STATIC FUNCTIONS ******************/ -/********************************************************/ -/********************************************************/ -/********************************************************/ - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_intClipSettingsSanityCheck() - * @brief Simplify the given clip settings - * @note This function may modify the given structure - * @param pClip (IN/OUT) Clip settings - * @return M4NO_ERROR: No error - * @return M4VSS3GPP_ERR_EXTERNAL_EFFECT_NULL: - ****************************************************************************** - */ - -static M4OSA_ERR M4VSS3GPP_intClipSettingsSanityCheck( - M4VSS3GPP_ClipSettings *pClip ) -{ - M4OSA_UInt8 uiFx; - M4OSA_UInt32 - uiClipActualDuration; /**< the clip duration once the cuts are done */ - M4OSA_UInt32 uiDuration; - M4VSS3GPP_EffectSettings *pFx; - - /** - * If begin cut is too far, return an error */ - uiDuration = pClip->ClipProperties.uiClipDuration; - - if( pClip->uiBeginCutTime > uiDuration ) - { - M4OSA_TRACE1_2( - "M4VSS3GPP_intClipSettingsSanityCheck: %d > %d,\ - returning M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION", - pClip->uiBeginCutTime, uiDuration); - return M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION; - } - - /** - * If end cut is too far, set to zero (it means no end cut) */ - if( pClip->uiEndCutTime > uiDuration ) - { - pClip->uiEndCutTime = 0; - } - - /** - * Compute actual clip duration (once cuts are done) */ - if( 0 == pClip->uiEndCutTime ) - { - /** - * No end cut */ - uiClipActualDuration = uiDuration - pClip->uiBeginCutTime; - } - else - { - if( pClip->uiBeginCutTime >= pClip->uiEndCutTime ) - { - M4OSA_TRACE1_2( - "M4VSS3GPP_intClipSettingsSanityCheck: %d > %d,\ - returning M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT", - pClip->uiBeginCutTime, pClip->uiEndCutTime); - return M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT; - } - uiClipActualDuration = pClip->uiEndCutTime - pClip->uiBeginCutTime; - } - - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_intTransitionSettingsSanityCheck() - * @brief Simplify the given transition settings - * @note This function may modify the given structure - * @param pTransition (IN/OUT) Transition settings - * @return M4NO_ERROR: No error - * @return M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL: - ****************************************************************************** - */ -static M4OSA_ERR M4VSS3GPP_intTransitionSettingsSanityCheck( - M4VSS3GPP_TransitionSettings *pTransition ) -{ - /** - * No transition */ - if( 0 == pTransition->uiTransitionDuration ) - { - pTransition->VideoTransitionType = M4VSS3GPP_kVideoTransitionType_None; - pTransition->AudioTransitionType = M4VSS3GPP_kAudioTransitionType_None; - } - else if( ( M4VSS3GPP_kVideoTransitionType_None - == pTransition->VideoTransitionType) - && (M4VSS3GPP_kAudioTransitionType_None - == pTransition->AudioTransitionType) ) - { - pTransition->uiTransitionDuration = 0; - } - - /** - * Check external transition function is set */ - if( ( pTransition->VideoTransitionType - >= M4VSS3GPP_kVideoTransitionType_External) - && (M4OSA_NULL == pTransition->ExtVideoTransitionFct) ) - { - return M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL; - } - - /** - * Set minimal transition duration */ - if( ( pTransition->uiTransitionDuration > 0) - && (pTransition->uiTransitionDuration - < M4VSS3GPP_MINIMAL_TRANSITION_DURATION) ) - { - pTransition->uiTransitionDuration = - M4VSS3GPP_MINIMAL_TRANSITION_DURATION; - } - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_intFreeSettingsList() - * @brief Free the settings copied in the internal context - * @param pC (IN/OUT) Internal edit context - ****************************************************************************** - */ -static M4OSA_Void M4VSS3GPP_intFreeSettingsList( - M4VSS3GPP_InternalEditContext *pC ) -{ - M4OSA_UInt32 i; - - /** - * Free the settings list */ - if( M4OSA_NULL != pC->pClipList ) - { - for ( i = 0; i < pC->uiClipNumber; i++ ) - { - M4VSS3GPP_editFreeClipSettings(&(pC->pClipList[i])); - } - - free(pC->pClipList); - pC->pClipList = M4OSA_NULL; - } - - /** - * Free the transition list */ - if( M4OSA_NULL != pC->pTransitionList ) - { - free(pC->pTransitionList); - pC->pTransitionList = M4OSA_NULL; - } -} -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_intCreateMP3OutputFile() - * @brief Creates and prepare the output MP file - * @param pC (IN/OUT) Internal edit context - ****************************************************************************** - */ -static M4OSA_ERR -M4VSS3GPP_intCreateMP3OutputFile( M4VSS3GPP_InternalEditContext *pC, - M4OSA_Void *pOutputFile ) -{ - M4OSA_ERR err; - - err = - pC->pOsaFileWritPtr->openWrite(&pC->ewc.p3gpWriterContext, pOutputFile, - M4OSA_kFileWrite); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreateMP3OutputFile: WriteOpen returns 0x%x!", err); - return err; - } - - return M4NO_ERROR; -} -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_intCreate3GPPOutputFile() - * @brief Creates and prepare the output MP3 file - * @note Creates the writer, Creates the output file, Adds the streams, - Readies the writing process - * @param pC (IN/OUT) Internal edit context - ****************************************************************************** - */ -M4OSA_ERR -M4VSS3GPP_intCreate3GPPOutputFile( M4VSS3GPP_EncodeWriteContext *pC_ewc, - M4VSS3GPP_MediaAndCodecCtxt *pC_ShellAPI, - M4OSA_FileWriterPointer *pOsaFileWritPtr, - M4OSA_Void *pOutputFile, - M4OSA_FileReadPointer *pOsaFileReadPtr, - M4OSA_Void *pTempFile, - M4OSA_UInt32 maxOutputFileSize ) -{ - M4OSA_ERR err; - M4OSA_UInt32 uiVersion; - M4SYS_StreamIDValue temp; - - M4OSA_TRACE3_2( - "M4VSS3GPP_intCreate3GPPOutputFile called with pC_ewc=0x%x, pOutputFile=0x%x", - pC_ewc, pOutputFile); - - /** - * Check input parameter */ - M4OSA_DEBUG_IF2((M4OSA_NULL == pC_ewc), M4ERR_PARAMETER, - "M4VSS3GPP_intCreate3GPPOutputFile: pC_ewc is M4OSA_NULL"); - M4OSA_DEBUG_IF2((M4OSA_NULL == pOutputFile), M4ERR_PARAMETER, - "M4VSS3GPP_intCreate3GPPOutputFile: pOutputFile is M4OSA_NULL"); - - /* Set writer */ - err = - M4VSS3GPP_setCurrentWriter(pC_ShellAPI, M4VIDEOEDITING_kFileType_3GPP); - M4ERR_CHECK_RETURN(err); - - /** - * Create the output file */ - err = pC_ShellAPI->pWriterGlobalFcts->pFctOpen(&pC_ewc->p3gpWriterContext, - pOutputFile, pOsaFileWritPtr, pTempFile, pOsaFileReadPtr); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreate3GPPOutputFile: pWriterGlobalFcts->pFctOpen returns 0x%x!", - err); - return err; - } - - /** - * Set the signature option of the writer */ - err = - pC_ShellAPI->pWriterGlobalFcts->pFctSetOption(pC_ewc->p3gpWriterContext, - M4WRITER_kEmbeddedString, (M4OSA_DataOption)"NXP-SW : VSS "); - - if( ( M4NO_ERROR != err) && (((M4OSA_UInt32)M4ERR_BAD_OPTION_ID) - != err) ) /* this option may not be implemented by some writers */ - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreate3GPPOutputFile:\ - pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedString) returns 0x%x!", - err); - return err; - } - - /*11/12/2008 CR3283 MMS use case for VideoArtist: - Set the max output file size option in the writer so that the output file will be - smaller than the given file size limitation*/ - if( maxOutputFileSize > 0 ) - { - err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( - pC_ewc->p3gpWriterContext, - M4WRITER_kMaxFileSize, &maxOutputFileSize); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreate3GPPOutputFile:\ - writer set option M4WRITER_kMaxFileSize returns 0x%x", - err); - return err; - } - } - - /** - * Set the version option of the writer */ - uiVersion = - (M4VIDEOEDITING_VERSION_MAJOR * 100 + M4VIDEOEDITING_VERSION_MINOR * 10 - + M4VIDEOEDITING_VERSION_REVISION); - err = - pC_ShellAPI->pWriterGlobalFcts->pFctSetOption(pC_ewc->p3gpWriterContext, - M4WRITER_kEmbeddedVersion, (M4OSA_DataOption) &uiVersion); - - if( ( M4NO_ERROR != err) && (((M4OSA_UInt32)M4ERR_BAD_OPTION_ID) - != err) ) /* this option may not be implemented by some writers */ - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreate3GPPOutputFile:\ - pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedVersion) returns 0x%x!", - err); - return err; - } - - if( M4SYS_kVideoUnknown != pC_ewc->VideoStreamType ) - { - /** - * Set the video stream properties */ - pC_ewc->WriterVideoStreamInfo.height = pC_ewc->uiVideoHeight; - pC_ewc->WriterVideoStreamInfo.width = pC_ewc->uiVideoWidth; - pC_ewc->WriterVideoStreamInfo.fps = - 0.0; /**< Not used by the shell/core writer */ - pC_ewc->WriterVideoStreamInfo.Header.pBuf = - pC_ewc->pVideoOutputDsi; /**< Previously computed output DSI */ - pC_ewc->WriterVideoStreamInfo.Header.Size = pC_ewc-> - uiVideoOutputDsiSize; /**< Previously computed output DSI size */ - - pC_ewc->WriterVideoStream.streamType = pC_ewc->VideoStreamType; - - switch( pC_ewc->VideoStreamType ) - { - case M4SYS_kMPEG_4: - case M4SYS_kH263: - case M4SYS_kH264: - /**< We HAVE to put a value here... */ - pC_ewc->WriterVideoStream.averageBitrate = - pC_ewc->uiVideoBitrate; - pC_ewc->WriterVideoStream.maxBitrate = pC_ewc->uiVideoBitrate; - break; - - default: - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreate3GPPOutputFile: unknown input video format (0x%x),\ - returning M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT!", - pC_ewc->VideoStreamType); - return M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT; - } - - pC_ewc->WriterVideoStream.streamID = M4VSS3GPP_WRITER_VIDEO_STREAM_ID; - pC_ewc->WriterVideoStream.timeScale = - 0; /**< Not used by the shell/core writer */ - pC_ewc->WriterVideoStream.profileLevel = - 0; /**< Not used by the shell/core writer */ - pC_ewc->WriterVideoStream.duration = - 0; /**< Not used by the shell/core writer */ - - pC_ewc->WriterVideoStream.decoderSpecificInfoSize = - sizeof(M4WRITER_StreamVideoInfos); - pC_ewc->WriterVideoStream.decoderSpecificInfo = - (M4OSA_MemAddr32) &(pC_ewc->WriterVideoStreamInfo); - - /** - * Add the video stream */ - err = pC_ShellAPI->pWriterGlobalFcts->pFctAddStream( - pC_ewc->p3gpWriterContext, &pC_ewc->WriterVideoStream); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreate3GPPOutputFile:\ - pWriterGlobalFcts->pFctAddStream(video) returns 0x%x!", - err); - return err; - } - - /** - * Update AU properties for video stream */ - pC_ewc->WriterVideoAU.attribute = AU_RAP; - pC_ewc->WriterVideoAU.CTS = 0; - pC_ewc->WriterVideoAU.DTS = 0; /** Reset time */ - pC_ewc->WriterVideoAU.frag = M4OSA_NULL; - pC_ewc->WriterVideoAU.nbFrag = 0; /** No fragment */ - pC_ewc->WriterVideoAU.size = 0; - pC_ewc->WriterVideoAU.dataAddress = M4OSA_NULL; - pC_ewc->WriterVideoAU.stream = &(pC_ewc->WriterVideoStream); - - /** - * Set the writer max video AU size */ - pC_ewc->uiVideoMaxAuSize = (M4OSA_UInt32)(1.5F - *(M4OSA_Float)(pC_ewc->WriterVideoStreamInfo.width - * pC_ewc->WriterVideoStreamInfo.height) - * M4VSS3GPP_VIDEO_MIN_COMPRESSION_RATIO); - temp.streamID = M4VSS3GPP_WRITER_VIDEO_STREAM_ID; - temp.value = pC_ewc->uiVideoMaxAuSize; - err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( - pC_ewc->p3gpWriterContext, (M4OSA_UInt32)M4WRITER_kMaxAUSize, - (M4OSA_DataOption) &temp); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreate3GPPOutputFile:\ - pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!", - err); - return err; - } - - /** - * Set the writer max video chunk size */ - temp.streamID = M4VSS3GPP_WRITER_VIDEO_STREAM_ID; - temp.value = (M4OSA_UInt32)(pC_ewc->uiVideoMaxAuSize \ - * M4VSS3GPP_VIDEO_AU_SIZE_TO_CHUNCK_SIZE_RATIO); /**< from max AU size to - max Chunck size */ - err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( - pC_ewc->p3gpWriterContext, - (M4OSA_UInt32)M4WRITER_kMaxChunckSize, - (M4OSA_DataOption) &temp); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreate3GPPOutputFile:\ - pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!", - err); - return err; - } - } - - if( M4SYS_kAudioUnknown != pC_ewc->AudioStreamType ) - { - M4WRITER_StreamAudioInfos streamAudioInfo; - - streamAudioInfo.nbSamplesPerSec = 0; /**< unused by our shell writer */ - streamAudioInfo.nbBitsPerSample = 0; /**< unused by our shell writer */ - streamAudioInfo.nbChannels = 1; /**< unused by our shell writer */ - - if( pC_ewc->pAudioOutputDsi != M4OSA_NULL ) - { - /* If we copy the stream from the input, we copy its DSI */ - streamAudioInfo.Header.Size = pC_ewc->uiAudioOutputDsiSize; - streamAudioInfo.Header.pBuf = pC_ewc->pAudioOutputDsi; - } - else - { - /* Writer will put a default DSI */ - streamAudioInfo.Header.Size = 0; - streamAudioInfo.Header.pBuf = M4OSA_NULL; - } - - pC_ewc->WriterAudioStream.streamID = M4VSS3GPP_WRITER_AUDIO_STREAM_ID; - pC_ewc->WriterAudioStream.streamType = pC_ewc->AudioStreamType; - pC_ewc->WriterAudioStream.duration = - 0; /**< Not used by the shell/core writer */ - pC_ewc->WriterAudioStream.profileLevel = - 0; /**< Not used by the shell/core writer */ - pC_ewc->WriterAudioStreamInfo.nbSamplesPerSec = - pC_ewc->uiSamplingFrequency; - pC_ewc->WriterAudioStream.timeScale = pC_ewc->uiSamplingFrequency; - pC_ewc->WriterAudioStreamInfo.nbChannels = - (M4OSA_UInt16)pC_ewc->uiNbChannels; - pC_ewc->WriterAudioStreamInfo.nbBitsPerSample = - 0; /**< Not used by the shell/core writer */ - - /** - * Add the audio stream */ - switch( pC_ewc->AudioStreamType ) - { - case M4SYS_kAMR: - pC_ewc->WriterAudioStream.averageBitrate = - 0; /**< It is not used by the shell, the DSI is taken into account instead */ - pC_ewc->WriterAudioStream.maxBitrate = - 0; /**< Not used by the shell/core writer */ - break; - - case M4SYS_kAAC: - pC_ewc->WriterAudioStream.averageBitrate = - pC_ewc->uiAudioBitrate; - pC_ewc->WriterAudioStream.maxBitrate = pC_ewc->uiAudioBitrate; - break; - - case M4SYS_kEVRC: - pC_ewc->WriterAudioStream.averageBitrate = - 0; /**< It is not used by the shell, the DSI is taken into account instead */ - pC_ewc->WriterAudioStream.maxBitrate = - 0; /**< Not used by the shell/core writer */ - break; - - case M4SYS_kMP3: /**< there can't be MP3 track in 3GPP file -> error */ - default: - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreate3GPPOutputFile: unknown output audio format (0x%x),\ - returning M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT!", - pC_ewc->AudioStreamType); - return M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT; - } - - /** - * Our writer shell interface is a little tricky: we put M4WRITER_StreamAudioInfos - in the DSI pointer... */ - pC_ewc->WriterAudioStream.decoderSpecificInfo = - (M4OSA_MemAddr32) &streamAudioInfo; - - /** - * Link the AU and the stream */ - pC_ewc->WriterAudioAU.stream = &(pC_ewc->WriterAudioStream); - pC_ewc->WriterAudioAU.dataAddress = M4OSA_NULL; - pC_ewc->WriterAudioAU.size = 0; - pC_ewc->WriterAudioAU.CTS = - -pC_ewc->iSilenceFrameDuration; /** Reset time */ - pC_ewc->WriterAudioAU.DTS = 0; - pC_ewc->WriterAudioAU.attribute = 0; - pC_ewc->WriterAudioAU.nbFrag = 0; /** No fragment */ - pC_ewc->WriterAudioAU.frag = M4OSA_NULL; - - err = pC_ShellAPI->pWriterGlobalFcts->pFctAddStream( - pC_ewc->p3gpWriterContext, &pC_ewc->WriterAudioStream); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreate3GPPOutputFile:\ - pWriterGlobalFcts->pFctAddStream(audio) returns 0x%x!", - err); - return err; - } - - /** - * Set the writer max audio AU size */ - pC_ewc->uiAudioMaxAuSize = M4VSS3GPP_AUDIO_MAX_AU_SIZE; - temp.streamID = M4VSS3GPP_WRITER_AUDIO_STREAM_ID; - temp.value = pC_ewc->uiAudioMaxAuSize; - err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( - pC_ewc->p3gpWriterContext, (M4OSA_UInt32)M4WRITER_kMaxAUSize, - (M4OSA_DataOption) &temp); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreate3GPPOutputFile:\ - pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, audio) returns 0x%x!", - err); - return err; - } - - /** - * Set the writer max audio chunck size */ - temp.streamID = M4VSS3GPP_WRITER_AUDIO_STREAM_ID; - temp.value = M4VSS3GPP_AUDIO_MAX_CHUNCK_SIZE; - err = pC_ShellAPI->pWriterGlobalFcts->pFctSetOption( - pC_ewc->p3gpWriterContext, - (M4OSA_UInt32)M4WRITER_kMaxChunckSize, - (M4OSA_DataOption) &temp); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreate3GPPOutputFile:\ - pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, audio) returns 0x%x!", - err); - return err; - } - } - - /** - * All streams added, we're now ready to write */ - err = pC_ShellAPI->pWriterGlobalFcts->pFctStartWriting( - pC_ewc->p3gpWriterContext); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intCreate3GPPOutputFile:\ - pWriterGlobalFcts->pFctStartWriting() returns 0x%x!", - err); - return err; - } - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4VSS3GPP_intCreate3GPPOutputFile(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_intComputeOutputVideoAndAudioDsi() - * @brief Generate a H263 or MPEG-4 decoder specific info compatible with all input video - * tracks. Copy audio dsi from master clip. - * @param pC (IN/OUT) Internal edit context - ****************************************************************************** - */ -static M4OSA_ERR -M4VSS3GPP_intComputeOutputVideoAndAudioDsi( M4VSS3GPP_InternalEditContext *pC, - M4OSA_UInt8 uiMasterClip ) -{ - M4OSA_Int32 iResynchMarkerDsiIndex; - M4_StreamHandler *pStreamForDsi; - M4VSS3GPP_ClipContext *pClip; - M4OSA_ERR err; - M4OSA_UInt32 i; - M4DECODER_MPEG4_DecoderConfigInfo DecConfigInfo; - M4DECODER_VideoSize dummySize; - M4OSA_Bool bGetDSiFromEncoder = M4OSA_FALSE; - - M4ENCODER_Header *encHeader; - M4SYS_StreamIDmemAddr streamHeader; - - pStreamForDsi = M4OSA_NULL; - pClip = M4OSA_NULL; - - /** - * H263 case */ - if( M4SYS_kH263 == pC->ewc.VideoStreamType ) - { - /** - * H263 output DSI is always 7 bytes */ - pC->ewc.uiVideoOutputDsiSize = 7; - pC->ewc.pVideoOutputDsi = - (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ewc.uiVideoOutputDsiSize, - M4VSS3GPP, (M4OSA_Char *)"pC->ewc.pVideoOutputDsi (H263)"); - - if( M4OSA_NULL == pC->ewc.pVideoOutputDsi ) - { - M4OSA_TRACE1_0( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi():\ - unable to allocate pVideoOutputDsi (H263), returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - - /** - * (We override the input vendor info. - * At least we know that nothing special will be tried with PHLP-stamped - edited streams...) */ - pC->ewc.pVideoOutputDsi[0] = 'P'; - pC->ewc.pVideoOutputDsi[1] = 'H'; - pC->ewc.pVideoOutputDsi[2] = 'L'; - pC->ewc.pVideoOutputDsi[3] = 'P'; - - /** - * Decoder version is 0 */ - pC->ewc.pVideoOutputDsi[4] = 0; - - /** - * Level is the sixth byte in the DSI */ - pC->ewc.pVideoOutputDsi[5] = pC->xVSS.outputVideoLevel; - - /** - * Profile is the seventh byte in the DSI*/ - pC->ewc.pVideoOutputDsi[6] = pC->xVSS.outputVideoProfile; - } - - /** - * MPEG-4 case */ - else if( M4SYS_kMPEG_4 == pC->ewc.VideoStreamType || - M4SYS_kH264 == pC->ewc.VideoStreamType) { - - /* For MPEG4 and H.264 encoder case - * Fetch the DSI from the shell video encoder, and feed it to the writer before - closing it. */ - - M4OSA_TRACE1_0( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi: get DSI for H264 stream"); - - if( M4OSA_NULL == pC->ewc.pEncContext ) - { - M4OSA_TRACE1_0( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi: pC->ewc.pEncContext is NULL"); - err = M4VSS3GPP_intCreateVideoEncoder(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ - M4VSS3GPP_intCreateVideoEncoder returned error 0x%x", - err); - } - } - - if( M4OSA_NULL != pC->ewc.pEncContext ) - { - err = pC->ShellAPI.pVideoEncoderGlobalFcts->pFctGetOption( - pC->ewc.pEncContext, M4ENCODER_kOptionID_EncoderHeader, - (M4OSA_DataOption) &encHeader); - - if( ( M4NO_ERROR != err) || (M4OSA_NULL == encHeader->pBuf) ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ - failed to get the encoder header (err 0x%x)", - err); - M4OSA_TRACE1_2( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi: encHeader->pBuf=0x%x, size=0x%x", - encHeader->pBuf, encHeader->Size); - } - else - { - M4OSA_TRACE1_0( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ - send DSI for video stream to 3GP writer"); - - /** - * Allocate and copy the new DSI */ - pC->ewc.pVideoOutputDsi = - (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(encHeader->Size, M4VSS3GPP, - (M4OSA_Char *)"pC->ewc.pVideoOutputDsi (H264)"); - - if( M4OSA_NULL == pC->ewc.pVideoOutputDsi ) - { - M4OSA_TRACE1_0( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi():\ - unable to allocate pVideoOutputDsi, returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - pC->ewc.uiVideoOutputDsiSize = (M4OSA_UInt16)encHeader->Size; - memcpy((void *)pC->ewc.pVideoOutputDsi, (void *)encHeader->pBuf, - encHeader->Size); - } - - err = M4VSS3GPP_intDestroyVideoEncoder(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ - M4VSS3GPP_intDestroyVideoEncoder returned error 0x%x", - err); - } - } - else - { - M4OSA_TRACE1_0( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ - pC->ewc.pEncContext is NULL, cannot get the DSI"); - } - } - - pStreamForDsi = M4OSA_NULL; - pClip = M4OSA_NULL; - - /* Compute Audio DSI */ - if( M4SYS_kAudioUnknown != pC->ewc.AudioStreamType ) - { - if( uiMasterClip == 0 ) - { - /* Clip is already opened */ - pStreamForDsi = &(pC->pC1->pAudioStream->m_basicProperties); - } - else - { - /** - * We can use the fast open mode to get the DSI */ - err = M4VSS3GPP_intClipInit(&pClip, pC->pOsaFileReadPtr); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ - M4VSS3GPP_intClipInit() returns 0x%x!", - err); - - if( pClip != M4OSA_NULL ) - { - M4VSS3GPP_intClipCleanUp(pClip); - } - return err; - } - - err = M4VSS3GPP_intClipOpen(pClip, &pC->pClipList[uiMasterClip], - M4OSA_FALSE, M4OSA_TRUE, M4OSA_TRUE); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ - M4VSS3GPP_intClipOpen() returns 0x%x!", - err); - M4VSS3GPP_intClipCleanUp(pClip); - return err; - } - - pStreamForDsi = &(pClip->pAudioStream->m_basicProperties); - } - - /** - * Allocate and copy the new DSI */ - pC->ewc.pAudioOutputDsi = (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc( - pStreamForDsi->m_decoderSpecificInfoSize, - M4VSS3GPP, (M4OSA_Char *)"pC->ewc.pAudioOutputDsi"); - - if( M4OSA_NULL == pC->ewc.pAudioOutputDsi ) - { - M4OSA_TRACE1_0( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi():\ - unable to allocate pAudioOutputDsi, returning M4ERR_ALLOC"); - return M4ERR_ALLOC; - } - pC->ewc.uiAudioOutputDsiSize = - (M4OSA_UInt16)pStreamForDsi->m_decoderSpecificInfoSize; - memcpy((void *)pC->ewc.pAudioOutputDsi, - (void *)pStreamForDsi->m_pDecoderSpecificInfo, - pC->ewc.uiAudioOutputDsiSize); - - /** - * If a clip has been temporarily opened to get its DSI, close it */ - if( M4OSA_NULL != pClip ) - { - err = M4VSS3GPP_intClipCleanUp(pClip); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi:\ - M4VSS3GPP_intClipCleanUp() returns 0x%x!", - err); - return err; - } - } - } - - /** - * Return with no error */ - M4OSA_TRACE3_0( - "M4VSS3GPP_intComputeOutputVideoAndAudioDsi(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_intSwitchToNextClip() - * @brief Switch from the current clip to the next one - * @param pC (IN/OUT) Internal edit context - ****************************************************************************** - */ -static M4OSA_ERR M4VSS3GPP_intSwitchToNextClip( - M4VSS3GPP_InternalEditContext *pC ) -{ - M4OSA_ERR err; - - if( M4OSA_NULL != pC->pC1 ) - { - if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame) { - if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame[0].pac_data) { - free(pC->pC1->m_pPreResizeFrame[0].pac_data); - pC->pC1->m_pPreResizeFrame[0].pac_data = M4OSA_NULL; - } - if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame[1].pac_data) { - free(pC->pC1->m_pPreResizeFrame[1].pac_data); - pC->pC1->m_pPreResizeFrame[1].pac_data = M4OSA_NULL; - } - if (M4OSA_NULL != pC->pC1->m_pPreResizeFrame[2].pac_data) { - free(pC->pC1->m_pPreResizeFrame[2].pac_data); - pC->pC1->m_pPreResizeFrame[2].pac_data = M4OSA_NULL; - } - free(pC->pC1->m_pPreResizeFrame); - pC->pC1->m_pPreResizeFrame = M4OSA_NULL; - } - /** - * Close the current first clip */ - err = M4VSS3GPP_intClipCleanUp(pC->pC1); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intSwitchToNextClip: M4VSS3GPP_intClipCleanUp(C1) returns 0x%x!", - err); - return err; - } - - /** - * increment clip counter */ - pC->uiCurrentClip++; - } - - /** - * Check if we reached the last clip */ - if( pC->uiCurrentClip >= pC->uiClipNumber ) - { - pC->pC1 = M4OSA_NULL; - pC->State = M4VSS3GPP_kEditState_FINISHED; - - M4OSA_TRACE1_0( - "M4VSS3GPP_intSwitchToNextClip:\ - M4VSS3GPP_intClipClose(C1) returns M4VSS3GPP_WAR_EDITING_DONE"); - return M4VSS3GPP_WAR_EDITING_DONE; - } - - /** - * If the next clip has already be opened, set it as first clip */ - if( M4OSA_NULL != pC->pC2 ) - { - pC->pC1 = pC->pC2; - if(M4OSA_NULL != pC->pC2->m_pPreResizeFrame) { - pC->pC1->m_pPreResizeFrame = pC->pC2->m_pPreResizeFrame; - } - pC->pC2 = M4OSA_NULL; - pC->bClip1ActiveFramingEffect = pC->bClip2ActiveFramingEffect; - pC->bClip2ActiveFramingEffect = M4OSA_FALSE; - } - /** - * else open it */ - else - { - err = M4VSS3GPP_intOpenClip(pC, &pC->pC1, - &pC->pClipList[pC->uiCurrentClip]); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intSwitchToNextClip: M4VSS3GPP_intOpenClip() returns 0x%x!", - err); - return err; - } - - /** - * If the second clip has not been opened yet, - that means that there has been no transition. - * So both output video and audio times are OK. - * So we can set both video2 and audio offsets */ - - /** - * Add current video output CTS to the clip video offset */ - - // Decorrelate input and output encoding timestamp to handle encoder prefetch - pC->pC1->iVoffset += (M4OSA_UInt32)pC->ewc.dInputVidCts; - /** - * Add current audio output CTS to the clip audio offset */ - pC->pC1->iAoffset += - (M4OSA_UInt32)(pC->ewc.dATo * pC->ewc.scale_audio + 0.5); - - /** - * 2005-03-24: BugFix for audio-video synchro: - * There may be a portion of the duration of an audio AU of desynchro at each assembly. - * It leads to an audible desynchro when there are a lot of clips assembled. - * This bug fix allows to resynch the audio track when the delta is higher - * than one audio AU duration. - * We Step one AU in the second clip and we change the audio offset accordingly. */ - if( ( pC->pC1->iAoffset - - (M4OSA_Int32)(pC->pC1->iVoffset *pC->pC1->scale_audio + 0.5)) - > pC->ewc.iSilenceFrameDuration ) - { - /** - * Advance one AMR frame */ - err = M4VSS3GPP_intClipReadNextAudioFrame(pC->pC1); - - if( M4OSA_ERR_IS_ERROR(err) ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intSwitchToNextClip:\ - M4VSS3GPP_intClipReadNextAudioFrame returns 0x%x!", - err); - return err; - } - /** - * Update audio offset accordingly*/ - pC->pC1->iAoffset -= pC->ewc.iSilenceFrameDuration; - } - } - - /** - * Init starting state for this clip processing */ - if( M4SYS_kMP3 == pC->ewc.AudioStreamType ) - { - /** - * In the MP3 case we use a special audio state */ - pC->State = M4VSS3GPP_kEditState_MP3_JUMP; - } - else - { - /** - * We start with the video processing */ - pC->State = M4VSS3GPP_kEditState_VIDEO; - - if( pC->Vstate != M4VSS3GPP_kEditVideoState_TRANSITION ) - { - /* if not a transition then reset previous video state */ - pC->Vstate = M4VSS3GPP_kEditVideoState_READ_WRITE; - } - } - /* The flags are set to false at the beginning of every clip */ - pC->m_bClipExternalHasStarted = M4OSA_FALSE; - pC->bEncodeTillEoF = M4OSA_FALSE; - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4VSS3GPP_intSwitchToNextClip(): returning M4NO_ERROR"); - /* RC: to know when a file has been processed */ - return M4VSS3GPP_WAR_SWITCH_CLIP; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_intReachedEndOfVideo() - * @brief Do what to do when the end of a clip video track is reached - * @note If there is audio on the current clip, process it, else switch to the next clip - * @param pC (IN/OUT) Internal edit context - ****************************************************************************** - */ -M4OSA_ERR M4VSS3GPP_intReachedEndOfVideo( M4VSS3GPP_InternalEditContext *pC ) -{ - M4OSA_ERR err; - - /** - * Video is done for this clip, now we do the audio */ - if( M4SYS_kAudioUnknown != pC->ewc.AudioStreamType ) - { - pC->State = M4VSS3GPP_kEditState_AUDIO; - } - else - { - /** - * Clip done, do the next one */ - err = M4VSS3GPP_intSwitchToNextClip(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intReachedEndOfVideo: M4VSS3GPP_intSwitchToNextClip() returns 0x%x", - err); - return err; - } - } - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4VSS3GPP_intReachedEndOfVideo(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_intReachedEndOfAudio() - * @brief Do what to do when the end of a clip audio track is reached - * @param pC (IN/OUT) Internal edit context - ****************************************************************************** - */ -M4OSA_ERR M4VSS3GPP_intReachedEndOfAudio( M4VSS3GPP_InternalEditContext *pC ) -{ - M4OSA_ERR err; - - /** - * Clip done, do the next one */ - err = M4VSS3GPP_intSwitchToNextClip(pC); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intReachedEndOfAudio: M4VSS3GPP_intSwitchToNextClip() returns 0x%x", - err); - return err; - } - - /** - * Start with the video */ - if( M4SYS_kVideoUnknown != pC->ewc.VideoStreamType ) - { - pC->State = M4VSS3GPP_kEditState_VIDEO; - } - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4VSS3GPP_intReachedEndOfAudio(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_intOpenClip() - * @brief Open next clip - * @param pC (IN/OUT) Internal edit context - ****************************************************************************** - */ -M4OSA_ERR M4VSS3GPP_intOpenClip( M4VSS3GPP_InternalEditContext *pC, - M4VSS3GPP_ClipContext ** hClip, - M4VSS3GPP_ClipSettings *pClipSettings ) -{ - M4OSA_ERR err; - M4VSS3GPP_ClipContext *pClip; /**< shortcut */ - M4VIDEOEDITING_ClipProperties *pClipProperties = M4OSA_NULL; - M4OSA_Int32 iCts; - M4OSA_UInt32 i; - - M4OSA_TRACE2_1("M4VSS3GPP_intOpenClip: \"%s\"", - (M4OSA_Char *)pClipSettings->pFile); - - err = M4VSS3GPP_intClipInit(hClip, pC->pOsaFileReadPtr); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intOpenClip: M4VSS3GPP_intClipInit() returns 0x%x!", - err); - - if( *hClip != M4OSA_NULL ) - { - M4VSS3GPP_intClipCleanUp(*hClip); - } - return err; - } - - /** - * Set shortcut */ - pClip = *hClip; - - if (pClipSettings->FileType == M4VIDEOEDITING_kFileType_ARGB8888 ) { - pClipProperties = &pClipSettings->ClipProperties; - pClip->pSettings = pClipSettings; - pClip->iEndTime = pClipSettings->uiEndCutTime; - } - - err = M4VSS3GPP_intClipOpen(pClip, pClipSettings, - M4OSA_FALSE, M4OSA_FALSE, M4OSA_FALSE); - if (M4NO_ERROR != err) { - M4OSA_TRACE1_1("M4VSS3GPP_intOpenClip: \ - M4VSS3GPP_intClipOpen() returns 0x%x!", err); - M4VSS3GPP_intClipCleanUp(pClip); - *hClip = M4OSA_NULL; - return err; - } - - if (pClipSettings->FileType != M4VIDEOEDITING_kFileType_ARGB8888 ) { - pClipProperties = &pClip->pSettings->ClipProperties; - } - - /** - * Copy common 'silence frame stuff' to ClipContext */ - pClip->uiSilencePcmSize = pC->ewc.uiSilencePcmSize; - pClip->pSilenceFrameData = pC->ewc.pSilenceFrameData; - pClip->uiSilenceFrameSize = pC->ewc.uiSilenceFrameSize; - pClip->iSilenceFrameDuration = pC->ewc.iSilenceFrameDuration; - pClip->scale_audio = pC->ewc.scale_audio; - - pClip->iAudioFrameCts = -pClip->iSilenceFrameDuration; /* Reset time */ - - /** - * If the audio track is not compatible with the output audio format, - * we remove it. So it will be replaced by silence */ - if( M4OSA_FALSE == pClipProperties->bAudioIsCompatibleWithMasterClip ) - { - M4VSS3GPP_intClipDeleteAudioTrack(pClip); - } - - /** - * Actual begin cut */ - if( 0 == pClipSettings->uiBeginCutTime ) - { - pClip->iVoffset = 0; - pClip->iAoffset = 0; - pClip->iActualVideoBeginCut = 0; - pClip->iActualAudioBeginCut = 0; - } - else if(pClipSettings->FileType != M4VIDEOEDITING_kFileType_ARGB8888) { - if( M4SYS_kVideoUnknown != pC->ewc.VideoStreamType ) - { - /** - * Jump the video to the target begin cut to get the actual begin cut value */ - pClip->iActualVideoBeginCut = - (M4OSA_Int32)pClipSettings->uiBeginCutTime; - iCts = pClip->iActualVideoBeginCut; - - err = pClip->ShellAPI.m_pReader->m_pFctJump(pClip->pReaderContext, - (M4_StreamHandler *)pClip->pVideoStream, &iCts); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intOpenClip: m_pFctJump(V) returns 0x%x!", err); - return err; - } - - /** - * Update clip offset with the video begin cut */ - pClip->iVoffset = -pClip->iActualVideoBeginCut; - } - - if( M4SYS_kAudioUnknown != pC->ewc.AudioStreamType ) - { - /** - * Jump the audio to the video actual begin cut */ - if( M4VIDEOEDITING_kMP3 != pClipProperties->AudioStreamType ) - { - pClip->iActualAudioBeginCut = pClip->iActualVideoBeginCut; - iCts = (M4OSA_Int32)(pClip->iActualAudioBeginCut - * pClip->scale_audio + 0.5); - - err = M4VSS3GPP_intClipJumpAudioAt(pClip, &iCts); - - if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intOpenClip: M4VSS3GPP_intClipJumpAudioAt(A) returns 0x%x!", - err); - return err; - } - /** - * Update clip offset with the audio begin cut */ - pClip->iAoffset = -iCts; - } - else - { - /** - * For the MP3, the jump is not done because of the VBR, - it could be not enough accurate */ - pClip->iActualAudioBeginCut = - (M4OSA_Int32)pClipSettings->uiBeginCutTime; - } - } - } - - if( M4SYS_kVideoUnknown != pC->ewc.VideoStreamType ) - { - if ((pClipSettings->FileType != M4VIDEOEDITING_kFileType_ARGB8888 )) { - - /** - * Read the first Video AU of the clip */ - err = pClip->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu( - pClip->pReaderContext, - (M4_StreamHandler *)pClip->pVideoStream, &pClip->VideoAU); - - if( M4WAR_NO_MORE_AU == err ) - { - /** - * If we (already!) reach the end of the clip, we filter the error. - * It will be correctly managed at the first step. */ - err = M4NO_ERROR; - } - else if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1("M4VSS3GPP_intOpenClip: \ - m_pReaderDataIt->m_pFctGetNextAu() returns 0x%x!", err); - return err; - } - } else { - pClipProperties->uiVideoWidth = pClipProperties->uiStillPicWidth; - pClipProperties->uiVideoHeight = pClipProperties->uiStillPicHeight; - } - /* state check not to allocate buffer during save start */ - - - /******************************/ - /* Video resize management */ - /******************************/ - /** - * If the input clip is a rotate video or the output resolution is different - * from the input resolution, then the video frame needs to be rotated - * or resized, force to resize mode */ - if (((M4OSA_UInt32)pC->ewc.uiVideoWidth != - pClipProperties->uiVideoWidth) || - ((M4OSA_UInt32)pC->ewc.uiVideoHeight != - pClipProperties->uiVideoHeight) || - pClipProperties->videoRotationDegrees != 0) { - - if (pClip->m_pPreResizeFrame == M4OSA_NULL) { - /** - * Allocate the intermediate video plane that will - receive the decoded image before resizing */ - pClip->m_pPreResizeFrame = - (M4VIFI_ImagePlane*)M4OSA_32bitAlignedMalloc( - 3*sizeof(M4VIFI_ImagePlane), M4VSS3GPP, - (M4OSA_Char *)"pPreResizeFrame"); - if (M4OSA_NULL == pClip->m_pPreResizeFrame) { - M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder(): \ - unable to allocate m_pPreResizeFrame"); - return M4ERR_ALLOC; - } - - pClip->m_pPreResizeFrame[0].pac_data = M4OSA_NULL; - pClip->m_pPreResizeFrame[1].pac_data = M4OSA_NULL; - pClip->m_pPreResizeFrame[2].pac_data = M4OSA_NULL; - - /** - * Allocate the Y plane */ - pClip->m_pPreResizeFrame[0].u_topleft = 0; - pClip->m_pPreResizeFrame[0].u_width = - pClipProperties->uiVideoWidth; - pClip->m_pPreResizeFrame[0].u_height = - pClipProperties->uiVideoHeight; - pClip->m_pPreResizeFrame[0].u_stride = - pClip->m_pPreResizeFrame[0].u_width; - - pClip->m_pPreResizeFrame[0].pac_data = - (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc ( - pClip->m_pPreResizeFrame[0].u_stride * pClip->m_pPreResizeFrame[0].u_height, - M4MCS, (M4OSA_Char *)"m_pPreResizeFrame[0].pac_data"); - if (M4OSA_NULL == pClip->m_pPreResizeFrame[0].pac_data) { - M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder(): \ - unable to allocate m_pPreResizeFrame[0].pac_data"); - free(pClip->m_pPreResizeFrame); - return M4ERR_ALLOC; - } - - /** - * Allocate the U plane */ - pClip->m_pPreResizeFrame[1].u_topleft = 0; - pClip->m_pPreResizeFrame[1].u_width = - pClip->m_pPreResizeFrame[0].u_width >> 1; - pClip->m_pPreResizeFrame[1].u_height = - pClip->m_pPreResizeFrame[0].u_height >> 1; - pClip->m_pPreResizeFrame[1].u_stride = - pClip->m_pPreResizeFrame[1].u_width; - - pClip->m_pPreResizeFrame[1].pac_data = - (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc ( - pClip->m_pPreResizeFrame[1].u_stride * pClip->m_pPreResizeFrame[1].u_height, - M4MCS, (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data"); - if (M4OSA_NULL == pClip->m_pPreResizeFrame[1].pac_data) { - M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder(): \ - unable to allocate m_pPreResizeFrame[1].pac_data"); - free(pClip->m_pPreResizeFrame[0].pac_data); - free(pClip->m_pPreResizeFrame); - return M4ERR_ALLOC; - } - - /** - * Allocate the V plane */ - pClip->m_pPreResizeFrame[2].u_topleft = 0; - pClip->m_pPreResizeFrame[2].u_width = - pClip->m_pPreResizeFrame[1].u_width; - pClip->m_pPreResizeFrame[2].u_height = - pClip->m_pPreResizeFrame[1].u_height; - pClip->m_pPreResizeFrame[2].u_stride = - pClip->m_pPreResizeFrame[2].u_width; - - pClip->m_pPreResizeFrame[2].pac_data = - (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc ( - pClip->m_pPreResizeFrame[2].u_stride * pClip->m_pPreResizeFrame[2].u_height, - M4MCS, (M4OSA_Char *)"m_pPreResizeFrame[2].pac_data"); - if (M4OSA_NULL == pClip->m_pPreResizeFrame[2].pac_data) { - M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder(): \ - unable to allocate m_pPreResizeFrame[2].pac_data"); - free(pClip->m_pPreResizeFrame[0].pac_data); - free(pClip->m_pPreResizeFrame[1].pac_data); - free(pClip->m_pPreResizeFrame); - return M4ERR_ALLOC; - } - } - } - - /** - * The video is currently in reading mode */ - pClip->Vstatus = M4VSS3GPP_kClipStatus_READ; - } - - if( ( M4SYS_kAudioUnknown != pC->ewc.AudioStreamType) - && (M4VIDEOEDITING_kMP3 != pClipProperties->AudioStreamType) ) - { - /** - * Read the first Audio AU of the clip */ - err = M4VSS3GPP_intClipReadNextAudioFrame(pClip); - - if( M4OSA_ERR_IS_ERROR(err) ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intOpenClip: M4VSS3GPP_intClipReadNextAudioFrame returns 0x%x!", - err); - return err; - } - - /** - * The audio is currently in reading mode */ - pClip->Astatus = M4VSS3GPP_kClipStatus_READ; - } - - /** - * Return with no error */ - M4OSA_TRACE3_0("M4VSS3GPP_intOpenClip(): returning M4NO_ERROR"); - return M4NO_ERROR; -} - -/** - ****************************************************************************** - * M4OSA_ERR M4VSS3GPP_intComputeOutputAverageVideoBitrate() - * @brief Average bitrate of the output file, computed from input bitrates, - * durations, transitions and cuts. - * @param pC (IN/OUT) Internal edit context - ****************************************************************************** - */ -static M4OSA_Void M4VSS3GPP_intComputeOutputAverageVideoBitrate( - M4VSS3GPP_InternalEditContext *pC ) -{ - M4VSS3GPP_ClipSettings *pCS_0, *pCS_1, *pCS_2; - M4VSS3GPP_TransitionSettings *pT0, *pT2; - M4OSA_Int32 i; - - M4OSA_UInt32 t0_duration, t2_duration; - M4OSA_UInt32 t0_bitrate, t2_bitrate; - M4OSA_UInt32 c1_duration; - - M4OSA_UInt32 total_duration; - M4OSA_UInt32 total_bitsum; - - total_duration = 0; - total_bitsum = 0; - - /* Loop on the number of clips */ - for ( i = 0; i < pC->uiClipNumber; i++ ) - { - pCS_1 = &pC->pClipList[i]; - - t0_duration = 0; - t0_bitrate = pCS_1->ClipProperties.uiVideoBitrate; - t2_duration = 0; - t2_bitrate = pCS_1->ClipProperties.uiVideoBitrate; - - /* Transition with the previous clip */ - if( i > 0 ) - { - pCS_0 = &pC->pClipList[i - 1]; - pT0 = &pC->pTransitionList[i - 1]; - - if( pT0->VideoTransitionType - != M4VSS3GPP_kVideoTransitionType_None ) - { - t0_duration = pT0->uiTransitionDuration; - - if( pCS_0->ClipProperties.uiVideoBitrate > t0_bitrate ) - { - t0_bitrate = pCS_0->ClipProperties.uiVideoBitrate; - } - } - } - - /* Transition with the next clip */ - if( i < pC->uiClipNumber - 1 ) - { - pCS_2 = &pC->pClipList[i + 1]; - pT2 = &pC->pTransitionList[i]; - - if( pT2->VideoTransitionType - != M4VSS3GPP_kVideoTransitionType_None ) - { - t2_duration = pT2->uiTransitionDuration; - - if( pCS_2->ClipProperties.uiVideoBitrate > t2_bitrate ) - { - t2_bitrate = pCS_2->ClipProperties.uiVideoBitrate; - } - } - } - - /* Check for cut times */ - if( pCS_1->uiEndCutTime > 0 ) - c1_duration = pCS_1->uiEndCutTime; - else - c1_duration = pCS_1->ClipProperties.uiClipVideoDuration; - - if( pCS_1->uiBeginCutTime > 0 ) - c1_duration -= pCS_1->uiBeginCutTime; - - c1_duration -= t0_duration + t2_duration; - - /* Compute bitsum and duration */ - total_duration += c1_duration + t0_duration / 2 + t2_duration / 2; - - total_bitsum += - c1_duration * (pCS_1->ClipProperties.uiVideoBitrate / 1000) - + (t0_bitrate / 1000) * t0_duration / 2 - + (t2_bitrate / 1000) * t2_duration / 2; - } - - pC->ewc.uiVideoBitrate = ( total_bitsum / total_duration) * 1000; -} - |