blob: 9f5410b550939e16d4219985cc0c41ca7d6489ff [file] [log] [blame]
/*
* 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 M4xVSS_API.c
* @brief API of eXtended Video Studio Service (Video Studio 2.1)
* @note
******************************************************************************
*/
/**
* OSAL main types and errors ***/
#include "M4OSA_Types.h"
#include "M4OSA_Error.h"
#include "M4OSA_Memory.h"
#include "M4OSA_Debug.h"
#include "M4OSA_FileReader.h"
#include "M4OSA_FileWriter.h"
#include "M4OSA_CoreID.h"
#include "M4OSA_CharStar.h"
// StageFright encoders require %16 resolution
#include "M4ENCODER_common.h"
#include "M4DECODER_Common.h"
#include "VideoEditorVideoDecoder.h"
/**
* VSS 3GPP API definition */
#include "M4VSS3GPP_ErrorCodes.h"
/*************************
Begin of xVSS API
**************************/
#include "M4xVSS_API.h"
#include "M4xVSS_Internal.h"
/* RC: to delete unecessary temp files on the fly */
#include "M4VSS3GPP_InternalTypes.h"
#include <utils/Log.h>
/**
******************************************************************************
* prototype M4OSA_ERR M4xVSS_Init(M4OSA_Context* pContext, M4xVSS_InitParams* pParams)
* @brief This function initializes the xVSS
* @note Initializes the xVSS edit operation (allocates an execution context).
*
* @param pContext (OUT) Pointer on the xVSS edit context to allocate
* @param params (IN) Parameters mandatory for xVSS
* @return M4NO_ERROR: No error
* @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL
* @return M4ERR_ALLOC: Memory allocation has failed
******************************************************************************
*/
M4OSA_ERR M4xVSS_Init( M4OSA_Context *pContext, M4xVSS_InitParams *pParams )
{
M4xVSS_Context *xVSS_context;
M4OSA_UInt32 length = 0, i;
if( pParams == M4OSA_NULL )
{
M4OSA_TRACE1_0("Parameter structure for M4xVSS_Init function is NULL");
return M4ERR_PARAMETER;
}
if( pParams->pFileReadPtr == M4OSA_NULL
|| pParams->pFileWritePtr == M4OSA_NULL )
{
M4OSA_TRACE1_0(
"pFileReadPtr or pFileWritePtr in M4xVSS_InitParams structure is NULL");
return M4ERR_PARAMETER;
}
xVSS_context = (M4xVSS_Context *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_Context), M4VS,
(M4OSA_Char *)"Context of the xVSS layer");
if( xVSS_context == M4OSA_NULL )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_Init");
return M4ERR_ALLOC;
}
/* Initialize file read/write functions pointers */
xVSS_context->pFileReadPtr = pParams->pFileReadPtr;
xVSS_context->pFileWritePtr = pParams->pFileWritePtr;
/*UTF Conversion support: copy conversion functions pointers and allocate the temporary
buffer*/
if( pParams->pConvFromUTF8Fct != M4OSA_NULL )
{
if( pParams->pConvToUTF8Fct != M4OSA_NULL )
{
xVSS_context->UTFConversionContext.pConvFromUTF8Fct =
pParams->pConvFromUTF8Fct;
xVSS_context->UTFConversionContext.pConvToUTF8Fct =
pParams->pConvToUTF8Fct;
xVSS_context->UTFConversionContext.m_TempOutConversionSize =
UTF_CONVERSION_BUFFER_SIZE;
xVSS_context->UTFConversionContext.pTempOutConversionBuffer =
(M4OSA_Void *)M4OSA_32bitAlignedMalloc(UTF_CONVERSION_BUFFER_SIZE
* sizeof(M4OSA_UInt8),
M4VA, (M4OSA_Char *)"M4xVSS_Init: UTF conversion buffer");
if( M4OSA_NULL
== xVSS_context->UTFConversionContext.pTempOutConversionBuffer )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_Init");
free(xVSS_context->pTempPath);
xVSS_context->pTempPath = M4OSA_NULL;
free(xVSS_context);
xVSS_context = M4OSA_NULL;
return M4ERR_ALLOC;
}
}
else
{
M4OSA_TRACE1_0("M4xVSS_Init: one UTF conversion pointer is null and the other\
is not null");
free(xVSS_context->pTempPath);
xVSS_context->pTempPath = M4OSA_NULL;
free(xVSS_context);
xVSS_context = M4OSA_NULL;
return M4ERR_PARAMETER;
}
}
else
{
xVSS_context->UTFConversionContext.pConvFromUTF8Fct = M4OSA_NULL;
xVSS_context->UTFConversionContext.pConvToUTF8Fct = M4OSA_NULL;
xVSS_context->UTFConversionContext.m_TempOutConversionSize = 0;
xVSS_context->UTFConversionContext.pTempOutConversionBuffer =
M4OSA_NULL;
}
if( pParams->pTempPath != M4OSA_NULL )
{
/*No need to convert into UTF8 as all input of xVSS are in UTF8
(the conversion customer format into UTF8
is done in VA/VAL)*/
xVSS_context->pTempPath =
(M4OSA_Void *)M4OSA_32bitAlignedMalloc(strlen(pParams->pTempPath) + 1,
M4VS, (M4OSA_Char *)"xVSS Path for temporary files");
if( xVSS_context->pTempPath == M4OSA_NULL )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_Init");
return M4ERR_ALLOC;
}
memcpy((void *)xVSS_context->pTempPath, (void *)pParams->pTempPath,
strlen(pParams->pTempPath) + 1);
/* TODO: Check that no previous xVSS temporary files are present ? */
}
else
{
M4OSA_TRACE1_0("Path for temporary files is NULL");
free(xVSS_context);
xVSS_context = M4OSA_NULL;
return M4ERR_PARAMETER;
}
xVSS_context->pSettings =
(M4VSS3GPP_EditSettings *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_EditSettings),
M4VS, (M4OSA_Char *)"Copy of VSS structure");
if( xVSS_context->pSettings == M4OSA_NULL )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_Init");
free(xVSS_context->pTempPath);
xVSS_context->pTempPath = M4OSA_NULL;
free(xVSS_context);
xVSS_context = M4OSA_NULL;
return M4ERR_ALLOC;
}
/* Initialize pointers in pSettings */
xVSS_context->pSettings->pClipList = M4OSA_NULL;
xVSS_context->pSettings->pTransitionList = M4OSA_NULL;
xVSS_context->pSettings->Effects = M4OSA_NULL; /* RC */
xVSS_context->pSettings->xVSS.pBGMtrack = M4OSA_NULL;
/* This is used to know if the user has added or removed some medias */
xVSS_context->previousClipNumber = 0;
/* "State machine" */
xVSS_context->editingStep = 0;
xVSS_context->analyseStep = 0;
xVSS_context->pcmPreviewFile = M4OSA_NULL;
/* Initialize Pto3GPP and MCS lists */
xVSS_context->pMCSparamsList = M4OSA_NULL;
xVSS_context->pPTo3GPPparamsList = M4OSA_NULL;
xVSS_context->pPTo3GPPcurrentParams = M4OSA_NULL;
xVSS_context->pMCScurrentParams = M4OSA_NULL;
xVSS_context->tempFileIndex = 0;
xVSS_context->targetedBitrate = 0;
xVSS_context->targetedTimescale = 0;
xVSS_context->pAudioMixContext = M4OSA_NULL;
xVSS_context->pAudioMixSettings = M4OSA_NULL;
/*FB: initialize to avoid crash when error during the editing*/
xVSS_context->pCurrentEditSettings = M4OSA_NULL;
/* Initialize state if all initializations are corrects */
xVSS_context->m_state = M4xVSS_kStateInitialized;
/* initialize MCS context*/
xVSS_context->pMCS_Ctxt = M4OSA_NULL;
*pContext = xVSS_context;
return M4NO_ERROR;
}
/**
******************************************************************************
* prototype M4xVSS_ReduceTranscode
* @brief This function changes the given editing structure in order to
* minimize the transcoding time.
* @note The xVSS analyses this structure, and if needed, changes the
* output parameters (Video codec, video size, audio codec,
* audio nb of channels) to minimize the transcoding time.
*
* @param pContext (OUT) Pointer on the xVSS edit context to allocate
* @param pSettings (IN) Edition settings (allocated by the user)
* @return M4NO_ERROR: No error
* @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL
* @return M4ERR_ALLOC: Memory allocation has failed
* @return M4ERR_STATE: This function cannot not be called at this time
******************************************************************************
*/
M4OSA_ERR M4xVSS_ReduceTranscode( M4OSA_Context pContext,
M4VSS3GPP_EditSettings *pSettings )
{
M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
M4OSA_ERR err = M4NO_ERROR;
M4VIDEOEDITING_ClipProperties fileProperties;
M4OSA_UInt8 i, j;
M4OSA_Bool bAudioTransition = M4OSA_FALSE;
M4OSA_Bool bIsBGMReplace = M4OSA_FALSE;
M4OSA_Bool bFound;
M4OSA_UInt32 videoConfig[9] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0
};
/** Index <-> Video config **/
/* 0: H263 SQCIF */
/* 1: H263 QCIF */
/* 2: H263 CIF */
/* 3: MPEG4 SQCIF */
/* 4: MPEG4 QQVGA */
/* 5: MPEG4 QCIF */
/* 6: MPEG4 QVGA */
/* 7: MPEG4 CIF */
/* 8: MPEG4 VGA */
/****************************/
M4OSA_UInt32 audioConfig[3] =
{
0, 0, 0
};
/** Index <-> Audio config **/
/* 0: AMR */
/* 1: AAC 16kHz mono */
/* 2: AAC 16kHz stereo */
/****************************/
/* Check state */
if( xVSS_context->m_state != M4xVSS_kStateInitialized \
&& xVSS_context->m_state != M4xVSS_kStateOpened )
{
M4OSA_TRACE1_1(
"Bad state when calling M4xVSS_ReduceTranscode function! State is %d",
xVSS_context->m_state);
return M4ERR_STATE;
}
/* Check number of clips */
if( pSettings->uiClipNumber == 0 )
{
M4OSA_TRACE1_0("The number of input clip must be greater than 0 !");
return M4ERR_PARAMETER;
}
/* Check if there is a background music, and if its audio will replace input clip audio */
if( pSettings->xVSS.pBGMtrack != M4OSA_NULL )
{
if( pSettings->xVSS.pBGMtrack->uiAddVolume == 100 )
{
bIsBGMReplace = M4OSA_TRUE;
}
}
/* Parse all clips, and give occurences of each combination */
for ( i = 0; i < pSettings->uiClipNumber; i++ )
{
/* We ignore JPG input files as they are always transcoded */
if( pSettings->pClipList[i]->FileType == M4VIDEOEDITING_kFileType_3GPP )
{
/**
* UTF conversion: convert into the customer format*/
M4OSA_Void *pDecodedPath = pSettings->pClipList[i]->pFile;
M4OSA_UInt32 ConvertedSize = 0;
if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
!= M4OSA_NULL && xVSS_context->
UTFConversionContext.pTempOutConversionBuffer
!= M4OSA_NULL )
{
err = M4xVSS_internalConvertFromUTF8(xVSS_context,
(M4OSA_Void *)pSettings->pClipList[i]->pFile,
(M4OSA_Void *)xVSS_context->
UTFConversionContext.pTempOutConversionBuffer,
&ConvertedSize);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1("M4xVSS_ReduceTranscode:\
M4xVSS_internalConvertFromUTF8 returns err: 0x%x", err);
return err;
}
pDecodedPath =
xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
}
/**
* End of the utf conversion, now use the converted path*/
err = M4xVSS_internalGetProperties(xVSS_context, pDecodedPath,
&fileProperties);
//err = M4xVSS_internalGetProperties(xVSS_context, pSettings->pClipList[i]->pFile,
// &fileProperties);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1(
"M4xVSS_sendCommand: M4xVSS_internalGetProperties returned 0x%x",
err);
/* TODO: Translate error code of MCS to an xVSS error code ? */
return err;
}
/* Check best video settings */
if( fileProperties.uiVideoWidth == 128
&& fileProperties.uiVideoHeight == 96 )
{
if( fileProperties.VideoStreamType == M4VIDEOEDITING_kH263 )
{
videoConfig[0] += fileProperties.uiClipVideoDuration;
}
else if( ( fileProperties.VideoStreamType
== M4VIDEOEDITING_kMPEG4) \
|| (fileProperties.VideoStreamType == M4VIDEOEDITING_kH264) )
{
videoConfig[3] += fileProperties.uiClipVideoDuration;
}
}
else if( fileProperties.uiVideoWidth == 160
&& fileProperties.uiVideoHeight == 120 )
{
if( ( fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4) \
|| (fileProperties.VideoStreamType == M4VIDEOEDITING_kH264) )
{
videoConfig[4] += fileProperties.uiClipVideoDuration;
}
}
else if( fileProperties.uiVideoWidth == 176
&& fileProperties.uiVideoHeight == 144 )
{
if( fileProperties.VideoStreamType == M4VIDEOEDITING_kH263 )
{
videoConfig[1] += fileProperties.uiClipVideoDuration;
}
else if( ( fileProperties.VideoStreamType
== M4VIDEOEDITING_kMPEG4) \
|| (fileProperties.VideoStreamType == M4VIDEOEDITING_kH264) )
{
videoConfig[5] += fileProperties.uiClipVideoDuration;
}
}
else if( fileProperties.uiVideoWidth == 320
&& fileProperties.uiVideoHeight == 240 )
{
if( ( fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4) \
|| (fileProperties.VideoStreamType == M4VIDEOEDITING_kH264) )
{
videoConfig[6] += fileProperties.uiClipVideoDuration;
}
}
else if( fileProperties.uiVideoWidth == 352
&& fileProperties.uiVideoHeight == 288 )
{
if( fileProperties.VideoStreamType == M4VIDEOEDITING_kH263 )
{
videoConfig[2] += fileProperties.uiClipVideoDuration;
}
else if( ( fileProperties.VideoStreamType
== M4VIDEOEDITING_kMPEG4) \
|| (fileProperties.VideoStreamType == M4VIDEOEDITING_kH264) )
{
videoConfig[7] += fileProperties.uiClipVideoDuration;
}
}
else if( fileProperties.uiVideoWidth == 640
&& fileProperties.uiVideoHeight == 480 )
{
if( ( fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4) \
|| (fileProperties.VideoStreamType == M4VIDEOEDITING_kH264) )
{
videoConfig[8] += fileProperties.uiClipVideoDuration;
}
}
/* If there is a BGM that replaces existing audio track, we do not care about
audio track as it will be replaced */
/* If not, we try to minimize audio reencoding */
if( bIsBGMReplace == M4OSA_FALSE )
{
if( fileProperties.AudioStreamType == M4VIDEOEDITING_kAAC )
{
if( fileProperties.uiSamplingFrequency == 16000 && \
fileProperties.uiNbChannels == 1 )
{
audioConfig[1] += fileProperties.uiClipAudioDuration;
}
else if( fileProperties.uiSamplingFrequency == 16000 && \
fileProperties.uiNbChannels == 2 )
{
audioConfig[2] += fileProperties.uiClipAudioDuration;
}
}
else if( fileProperties.AudioStreamType
== M4VIDEOEDITING_kAMR_NB )
{
audioConfig[0] += fileProperties.uiClipAudioDuration;
}
}
}
}
/* Find best output video format (the most occuring combination) */
j = 0;
bFound = M4OSA_FALSE;
for ( i = 0; i < 9; i++ )
{
if( videoConfig[i] >= videoConfig[j] )
{
j = i;
bFound = M4OSA_TRUE;
}
}
if( bFound )
{
switch( j )
{
case 0:
pSettings->xVSS.outputVideoFormat = M4VIDEOEDITING_kH263;
pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kSQCIF;
break;
case 1:
pSettings->xVSS.outputVideoFormat = M4VIDEOEDITING_kH263;
pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kQCIF;
break;
case 2:
pSettings->xVSS.outputVideoFormat = M4VIDEOEDITING_kH263;
pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kCIF;
break;
case 3:
pSettings->xVSS.outputVideoFormat =
(fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)
? M4VIDEOEDITING_kMPEG4 : M4VIDEOEDITING_kH264;
pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kSQCIF;
break;
case 4:
pSettings->xVSS.outputVideoFormat =
(fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)
? M4VIDEOEDITING_kMPEG4 : M4VIDEOEDITING_kH264;
pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kQQVGA;
break;
case 5:
pSettings->xVSS.outputVideoFormat =
(fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)
? M4VIDEOEDITING_kMPEG4 : M4VIDEOEDITING_kH264;
pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kQCIF;
break;
case 6:
pSettings->xVSS.outputVideoFormat =
(fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)
? M4VIDEOEDITING_kMPEG4 : M4VIDEOEDITING_kH264;
pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kQVGA;
break;
case 7:
pSettings->xVSS.outputVideoFormat =
(fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)
? M4VIDEOEDITING_kMPEG4 : M4VIDEOEDITING_kH264;
pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kCIF;
break;
case 8:
pSettings->xVSS.outputVideoFormat =
(fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)
? M4VIDEOEDITING_kMPEG4 : M4VIDEOEDITING_kH264;
pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kVGA;
break;
}
}
/* Find best output audio format (the most occuring combination) */
j = 0;
bFound = M4OSA_FALSE;
for ( i = 0; i < 3; i++ )
{
if( audioConfig[i] >= audioConfig[j] )
{
j = i;
bFound = M4OSA_TRUE;
}
}
if( bFound )
{
switch( j )
{
case 0:
pSettings->xVSS.outputAudioFormat = M4VIDEOEDITING_kAMR_NB;
pSettings->xVSS.bAudioMono = M4OSA_TRUE;
break;
case 1:
pSettings->xVSS.outputAudioFormat = M4VIDEOEDITING_kAAC;
pSettings->xVSS.bAudioMono = M4OSA_TRUE;
break;
case 2:
pSettings->xVSS.outputAudioFormat = M4VIDEOEDITING_kAAC;
pSettings->xVSS.bAudioMono = M4OSA_FALSE;
break;
}
}
return M4NO_ERROR;
}
/**
******************************************************************************
* prototype M4OSA_ERR M4xVSS_SendCommand(M4OSA_Context pContext,
* M4VSS3GPP_EditSettings* pSettings)
* @brief This function gives to the xVSS an editing structure
* @note The xVSS analyses this structure, and prepare edition
* This function must be called after M4xVSS_Init, after
* M4xVSS_CloseCommand, or after M4xVSS_PreviewStop.
* After this function, the user must call M4xVSS_Step until
* it returns another error than M4NO_ERROR.
*
* @param pContext (IN) Pointer on the xVSS edit context
* @param pSettings (IN) Edition settings (allocated by the user)
* @return M4NO_ERROR: No error
* @return M4ERR_PARAMETER: At least one parameter is M4OSA_NULL
* @return M4ERR_ALLOC: Memory allocation has failed
* @return M4ERR_STATE: This function cannot not be called at this time
******************************************************************************
*/
M4OSA_ERR M4xVSS_SendCommand( M4OSA_Context pContext,
M4VSS3GPP_EditSettings *pSettings )
{
M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
M4OSA_UInt8 i, j;
M4OSA_UInt8 nbOfSameClip = 0;
M4OSA_ERR err;
M4OSA_Bool isNewBGM = M4OSA_TRUE;
M4xVSS_Pto3GPP_params *pPto3GPP_last = M4OSA_NULL;
M4xVSS_MCS_params *pMCS_last = M4OSA_NULL;
M4OSA_UInt32 width, height, samplingFreq;
M4OSA_Bool bIsTranscoding = M4OSA_FALSE;
M4OSA_Int32 totalDuration;
M4OSA_UInt32 outputSamplingFrequency = 0;
M4OSA_UInt32 length = 0;
M4OSA_Int8 masterClip = -1;
i = 0;
/* Check state */
if( xVSS_context->m_state != M4xVSS_kStateInitialized \
&& xVSS_context->m_state != M4xVSS_kStateOpened )
{
M4OSA_TRACE1_1(
"Bad state when calling M4xVSS_SendCommand function! State is %d",
xVSS_context->m_state);
return M4ERR_STATE;
}
/* State is back to initialized to allow call of cleanup function in case of error */
xVSS_context->m_state = M4xVSS_kStateInitialized;
/* Check if a previous sendCommand has been called */
if( xVSS_context->previousClipNumber != 0 )
{
M4OSA_UInt32 pCmpResult = 0;
/* Compare BGM input */
if( xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL \
&& pSettings->xVSS.pBGMtrack != M4OSA_NULL )
{
pCmpResult = strcmp((const char *)xVSS_context->pSettings->xVSS.pBGMtrack->pFile,
(const char *)pSettings->xVSS.pBGMtrack->pFile);
if( pCmpResult == 0 )
{
/* Check if audio output parameters have changed */
if( xVSS_context->pSettings->xVSS.outputAudioFormat ==
pSettings->xVSS.outputAudioFormat
&& xVSS_context->pSettings->xVSS.bAudioMono
== pSettings->xVSS.bAudioMono )
{
/* It means that BGM is the same as before, so, no need to redecode it */
M4OSA_TRACE2_0(
"BGM is the same as before, nothing to decode");
isNewBGM = M4OSA_FALSE;
}
else
{
/* We need to unallocate PCM preview file path in internal context */
if( xVSS_context->pcmPreviewFile != M4OSA_NULL )
{
free(xVSS_context->pcmPreviewFile);
xVSS_context->pcmPreviewFile = M4OSA_NULL;
}
}
}
else
{
/* We need to unallocate PCM preview file path in internal context */
if( xVSS_context->pcmPreviewFile != M4OSA_NULL )
{
free(xVSS_context->pcmPreviewFile);
xVSS_context->pcmPreviewFile = M4OSA_NULL;
}
}
}
/* Check if output settings have changed */
if( xVSS_context->pSettings->xVSS.outputVideoSize
!= pSettings->xVSS.outputVideoSize
|| xVSS_context->pSettings->xVSS.outputVideoFormat
!= pSettings->xVSS.outputVideoFormat
|| xVSS_context->pSettings->xVSS.outputVideoProfile
!= pSettings->xVSS.outputVideoProfile
|| xVSS_context->pSettings->xVSS.outputVideoLevel
!= pSettings->xVSS.outputVideoLevel
|| xVSS_context->pSettings->xVSS.outputAudioFormat
!= pSettings->xVSS.outputAudioFormat
|| xVSS_context->pSettings->xVSS.bAudioMono
!= pSettings->xVSS.bAudioMono
|| xVSS_context->pSettings->xVSS.outputAudioSamplFreq
!= pSettings->xVSS.outputAudioSamplFreq )
{
/* If it is the case, we can't reuse already transcoded/converted files */
/* so, we delete these files and remove them from chained list */
if( xVSS_context->pPTo3GPPparamsList != M4OSA_NULL )
{
M4xVSS_Pto3GPP_params *pParams =
xVSS_context->pPTo3GPPparamsList;
M4xVSS_Pto3GPP_params *pParams_sauv;
while( pParams != M4OSA_NULL )
{
if( pParams->pFileIn != M4OSA_NULL )
{
free(pParams->pFileIn);
pParams->pFileIn = M4OSA_NULL;
}
if( pParams->pFileOut != M4OSA_NULL )
{
/* Delete temporary file */
remove((const char *)pParams->pFileOut);
free(pParams->pFileOut);
pParams->pFileOut = M4OSA_NULL;
}
if( pParams->pFileTemp != M4OSA_NULL )
{
/* Delete temporary file */
#ifdef M4xVSS_RESERVED_MOOV_DISK_SPACE
remove((const char *)pParams->pFileTemp);
free(pParams->pFileTemp);
#endif /*M4xVSS_RESERVED_MOOV_DISK_SPACE*/
pParams->pFileTemp = M4OSA_NULL;
}
pParams_sauv = pParams;
pParams = pParams->pNext;
free(pParams_sauv);
pParams_sauv = M4OSA_NULL;
}
xVSS_context->pPTo3GPPparamsList = M4OSA_NULL;
}
if( xVSS_context->pMCSparamsList != M4OSA_NULL )
{
M4xVSS_MCS_params *pParams = xVSS_context->pMCSparamsList;
M4xVSS_MCS_params *pParams_sauv;
M4xVSS_MCS_params *pParams_bgm = M4OSA_NULL;
while( pParams != M4OSA_NULL )
{
/* Here, we do not delete BGM */
if( pParams->isBGM != M4OSA_TRUE )
{
if( pParams->pFileIn != M4OSA_NULL )
{
free(pParams->pFileIn);
pParams->pFileIn = M4OSA_NULL;
}
if( pParams->pFileOut != M4OSA_NULL )
{
/* Delete temporary file */
remove((const char *)pParams->pFileOut);
free(pParams->pFileOut);
pParams->pFileOut = M4OSA_NULL;
}
if( pParams->pFileTemp != M4OSA_NULL )
{
/* Delete temporary file */
#ifdef M4xVSS_RESERVED_MOOV_DISK_SPACE
remove((const char *)pParams->pFileTemp);
free(pParams->pFileTemp);
#endif /*M4xVSS_RESERVED_MOOV_DISK_SPACE*/
pParams->pFileTemp = M4OSA_NULL;
}
pParams_sauv = pParams;
pParams = pParams->pNext;
free(pParams_sauv);
pParams_sauv = M4OSA_NULL;
}
else
{
pParams_bgm = pParams;
pParams = pParams->pNext;
/*PR P4ME00003182 initialize this pointer because the following params
element will be deallocated*/
if( pParams != M4OSA_NULL
&& pParams->isBGM != M4OSA_TRUE )
{
pParams_bgm->pNext = M4OSA_NULL;
}
}
}
xVSS_context->pMCSparamsList = pParams_bgm;
}
/* Maybe need to implement framerate changing */
//xVSS_context->pSettings->videoFrameRate;
}
/* Unallocate previous xVSS_context->pSettings structure */
M4xVSS_freeSettings(xVSS_context->pSettings);
/*Unallocate output file path*/
if( xVSS_context->pSettings->pOutputFile != M4OSA_NULL )
{
free(xVSS_context->pSettings->pOutputFile);
xVSS_context->pSettings->pOutputFile = M4OSA_NULL;
}
xVSS_context->pSettings->uiOutputPathSize = 0;
xVSS_context->pOutputFile = M4OSA_NULL;
}
/**********************************
Clips registering
**********************************/
/* Copy settings from user given structure to our "local" structure */
xVSS_context->pSettings->xVSS.outputVideoFormat =
pSettings->xVSS.outputVideoFormat;
xVSS_context->pSettings->xVSS.outputVideoProfile =
pSettings->xVSS.outputVideoProfile;
xVSS_context->pSettings->xVSS.outputVideoLevel =
pSettings->xVSS.outputVideoLevel;
xVSS_context->pSettings->xVSS.outputVideoSize =
pSettings->xVSS.outputVideoSize;
xVSS_context->pSettings->xVSS.outputAudioFormat =
pSettings->xVSS.outputAudioFormat;
xVSS_context->pSettings->xVSS.bAudioMono = pSettings->xVSS.bAudioMono;
xVSS_context->pSettings->xVSS.outputAudioSamplFreq =
pSettings->xVSS.outputAudioSamplFreq;
/*xVSS_context->pSettings->pOutputFile = pSettings->pOutputFile;*/
/*FB: VAL CR P4ME00003076
The output video and audio bitrate are given by the user in the edition settings structure*/
xVSS_context->pSettings->xVSS.outputVideoBitrate =
pSettings->xVSS.outputVideoBitrate;
xVSS_context->pSettings->xVSS.outputAudioBitrate =
pSettings->xVSS.outputAudioBitrate;
xVSS_context->pSettings->PTVolLevel = pSettings->PTVolLevel;
/*FB: bug fix if the output path is given in M4xVSS_sendCommand*/
if( pSettings->pOutputFile != M4OSA_NULL
&& pSettings->uiOutputPathSize > 0 )
{
M4OSA_Void *pDecodedPath = pSettings->pOutputFile;
/*As all inputs of the xVSS are in UTF8, convert the output file path into the
customer format*/
if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
&& xVSS_context->UTFConversionContext.pTempOutConversionBuffer
!= M4OSA_NULL )
{
err = M4xVSS_internalConvertFromUTF8(xVSS_context,
(M4OSA_Void *)pSettings->pOutputFile,
(M4OSA_Void *)xVSS_context->
UTFConversionContext.pTempOutConversionBuffer, &length);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1("M4xVSS_SendCommand:\
M4xVSS_internalConvertFromUTF8 returns err: 0x%x", err);
return err;
}
pDecodedPath =
xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
pSettings->uiOutputPathSize = length;
}
xVSS_context->pSettings->pOutputFile = (M4OSA_Void *)M4OSA_32bitAlignedMalloc \
(pSettings->uiOutputPathSize + 1, M4VS,
(M4OSA_Char *)"output file path");
if( xVSS_context->pSettings->pOutputFile == M4OSA_NULL )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
memcpy((void *)xVSS_context->pSettings->pOutputFile,
(void *)pDecodedPath, pSettings->uiOutputPathSize + 1);
xVSS_context->pSettings->uiOutputPathSize = pSettings->uiOutputPathSize;
xVSS_context->pOutputFile = xVSS_context->pSettings->pOutputFile;
}
else
{
xVSS_context->pSettings->pOutputFile = M4OSA_NULL;
xVSS_context->pSettings->uiOutputPathSize = 0;
xVSS_context->pOutputFile = M4OSA_NULL;
}
xVSS_context->pSettings->pTemporaryFile = pSettings->pTemporaryFile;
xVSS_context->pSettings->uiClipNumber = pSettings->uiClipNumber;
xVSS_context->pSettings->videoFrameRate = pSettings->videoFrameRate;
xVSS_context->pSettings->uiMasterClip =
0; /* With VSS 2.0, this new param is mandatory */
xVSS_context->pSettings->xVSS.pTextRenderingFct =
pSettings->xVSS.pTextRenderingFct; /* CR text handling */
xVSS_context->pSettings->xVSS.outputFileSize =
pSettings->xVSS.outputFileSize;
if( pSettings->xVSS.outputFileSize != 0 \
&& pSettings->xVSS.outputAudioFormat != M4VIDEOEDITING_kAMR_NB )
{
M4OSA_TRACE1_0("M4xVSS_SendCommand: Impossible to limit file\
size with other audio output than AAC");
return M4ERR_PARAMETER;
}
xVSS_context->nbStepTotal = 0;
xVSS_context->currentStep = 0;
if( xVSS_context->pSettings->xVSS.outputVideoFormat != M4VIDEOEDITING_kMPEG4
&& xVSS_context->pSettings->xVSS.outputVideoFormat
!= M4VIDEOEDITING_kH263
&& xVSS_context->pSettings->xVSS.outputVideoFormat
!= M4VIDEOEDITING_kH264 )
{
xVSS_context->pSettings->xVSS.outputVideoFormat =
M4VIDEOEDITING_kNoneVideo;
}
/* Get output width/height */
switch( xVSS_context->pSettings->xVSS.outputVideoSize )
{
case M4VIDEOEDITING_kSQCIF:
width = 128;
height = 96;
break;
case M4VIDEOEDITING_kQQVGA:
width = 160;
height = 120;
break;
case M4VIDEOEDITING_kQCIF:
width = 176;
height = 144;
break;
case M4VIDEOEDITING_kQVGA:
width = 320;
height = 240;
break;
case M4VIDEOEDITING_kCIF:
width = 352;
height = 288;
break;
case M4VIDEOEDITING_kVGA:
width = 640;
height = 480;
break;
/* +PR LV5807 */
case M4VIDEOEDITING_kWVGA:
width = 800;
height = 480;
break;
case M4VIDEOEDITING_kNTSC:
width = 720;
height = 480;
break;
/* -PR LV5807 */
/* +CR Google */
case M4VIDEOEDITING_k640_360:
width = 640;
height = 360;
break;
case M4VIDEOEDITING_k854_480:
// StageFright encoders require %16 resolution
width = M4ENCODER_854_480_Width;
height = 480;
break;
case M4VIDEOEDITING_k1280_720:
width = 1280;
height = 720;
break;
case M4VIDEOEDITING_k1080_720:
// StageFright encoders require %16 resolution
width = M4ENCODER_1080_720_Width;
height = 720;
break;
case M4VIDEOEDITING_k960_720:
width = 960;
height = 720;
break;
case M4VIDEOEDITING_k1920_1080:
width = 1920;
height = M4ENCODER_1920_1080_Height;
break;
/* -CR Google */
default: /* If output video size is not given, we take QCIF size */
width = 176;
height = 144;
xVSS_context->pSettings->xVSS.outputVideoSize =
M4VIDEOEDITING_kQCIF;
break;
}
/* Get output Sampling frequency */
switch( xVSS_context->pSettings->xVSS.outputAudioSamplFreq )
{
case M4VIDEOEDITING_k8000_ASF:
samplingFreq = 8000;
break;
case M4VIDEOEDITING_k16000_ASF:
samplingFreq = 16000;
break;
case M4VIDEOEDITING_k22050_ASF:
samplingFreq = 22050;
break;
case M4VIDEOEDITING_k24000_ASF:
samplingFreq = 24000;
break;
case M4VIDEOEDITING_k32000_ASF:
samplingFreq = 32000;
break;
case M4VIDEOEDITING_k44100_ASF:
samplingFreq = 44100;
break;
case M4VIDEOEDITING_k48000_ASF:
samplingFreq = 48000;
break;
case M4VIDEOEDITING_kDefault_ASF:
default:
if( xVSS_context->pSettings->xVSS.outputAudioFormat
== M4VIDEOEDITING_kAMR_NB )
{
samplingFreq = 8000;
}
else if( xVSS_context->pSettings->xVSS.outputAudioFormat
== M4VIDEOEDITING_kAAC )
{
samplingFreq = 16000;
}
else
{
samplingFreq = 0;
}
break;
}
/* Allocate clip/transitions if clip number is not null ... */
if( 0 < xVSS_context->pSettings->uiClipNumber )
{
if( xVSS_context->pSettings->pClipList != M4OSA_NULL )
{
free((xVSS_context->pSettings->pClipList));
xVSS_context->pSettings->pClipList = M4OSA_NULL;
}
if( xVSS_context->pSettings->pTransitionList != M4OSA_NULL )
{
free(xVSS_context->pSettings->pTransitionList);
xVSS_context->pSettings->pTransitionList = M4OSA_NULL;
}
xVSS_context->pSettings->pClipList =
(M4VSS3GPP_ClipSettings ** )M4OSA_32bitAlignedMalloc \
(sizeof(M4VSS3GPP_ClipSettings *)*xVSS_context->pSettings->uiClipNumber,
M4VS, (M4OSA_Char *)"xVSS, copy of pClipList");
if( xVSS_context->pSettings->pClipList == M4OSA_NULL )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
/* Set clip list to NULL */
memset((void *)xVSS_context->pSettings->pClipList,0,
sizeof(M4VSS3GPP_ClipSettings *)
*xVSS_context->pSettings->uiClipNumber);
if( xVSS_context->pSettings->uiClipNumber > 1 )
{
xVSS_context->pSettings->pTransitionList =
(M4VSS3GPP_TransitionSettings ** ) \
M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_TransitionSettings *) \
*(xVSS_context->pSettings->uiClipNumber - 1), M4VS, (M4OSA_Char *) \
"xVSS, copy of pTransitionList");
if( xVSS_context->pSettings->pTransitionList == M4OSA_NULL )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
/* Set transition list to NULL */
memset(
(void *)xVSS_context->pSettings->pTransitionList,0,
sizeof(M4VSS3GPP_TransitionSettings *)
*(xVSS_context->pSettings->uiClipNumber - 1));
}
else
{
xVSS_context->pSettings->pTransitionList = M4OSA_NULL;
}
}
/* else, there is a pb in the input settings structure */
else
{
M4OSA_TRACE1_0("No clip in this settings list !!");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_PARAMETER;
}
/* RC Allocate effects settings */
xVSS_context->pSettings->nbEffects = pSettings->nbEffects;
if( 0 < xVSS_context->pSettings->nbEffects )
{
xVSS_context->pSettings->Effects =
(M4VSS3GPP_EffectSettings *)M4OSA_32bitAlignedMalloc \
(xVSS_context->pSettings->nbEffects * sizeof(M4VSS3GPP_EffectSettings),
M4VS, (M4OSA_Char *)"effects settings");
if( xVSS_context->pSettings->Effects == M4OSA_NULL )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
/*FB bug fix 19.03.2008: these pointers were not initialized -> crash when free*/
for ( i = 0; i < xVSS_context->pSettings->nbEffects; i++ )
{
xVSS_context->pSettings->Effects[i].xVSS.pFramingFilePath =
M4OSA_NULL;
xVSS_context->pSettings->Effects[i].xVSS.pFramingBuffer =
M4OSA_NULL;
xVSS_context->pSettings->Effects[i].xVSS.pTextBuffer = M4OSA_NULL;
}
/**/
}
if( xVSS_context->targetedTimescale == 0 )
{
M4OSA_UInt32 pTargetedTimeScale = 0;
err = M4xVSS_internalGetTargetedTimeScale(xVSS_context, pSettings,
&pTargetedTimeScale);
if( M4NO_ERROR != err || pTargetedTimeScale == 0 )
{
M4OSA_TRACE1_1("M4xVSS_SendCommand: M4xVSS_internalGetTargetedTimeScale\
returned 0x%x", err);
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return err;
}
xVSS_context->targetedTimescale = pTargetedTimeScale;
}
/* Initialize total duration variable */
totalDuration = 0;
/* Parsing list of clips given by application, and prepare analyzing */
for ( i = 0; i < xVSS_context->pSettings->uiClipNumber; i++ )
{
/* Allocate current clip */
xVSS_context->pSettings->pClipList[i] =
(M4VSS3GPP_ClipSettings *)M4OSA_32bitAlignedMalloc \
(sizeof(M4VSS3GPP_ClipSettings), M4VS, (M4OSA_Char *)"clip settings");
if( xVSS_context->pSettings->pClipList[i] == M4OSA_NULL )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
/* Copy clip settings from given structure to our xVSS_context structure */
err =
M4xVSS_DuplicateClipSettings(xVSS_context->pSettings->pClipList[i],
pSettings->pClipList[i], M4OSA_TRUE);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1(
"M4xVSS_SendCommand: M4xVSS_DuplicateClipSettings return error 0x%x",
err);
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return err;
}
xVSS_context->pSettings->pClipList[i]->bTranscodingRequired =
M4OSA_FALSE;
/* Because there is 1 less transition than clip number */
if( i < xVSS_context->pSettings->uiClipNumber - 1 )
{
xVSS_context->pSettings->pTransitionList[i] =
(M4VSS3GPP_TransitionSettings
*)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_TransitionSettings),
M4VS, (M4OSA_Char *)"transition settings");
if( xVSS_context->pSettings->pTransitionList[i] == M4OSA_NULL )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
memcpy(
(void *)xVSS_context->pSettings->pTransitionList[i],
(void *)pSettings->pTransitionList[i],
sizeof(M4VSS3GPP_TransitionSettings));
/* Initialize external effect context to NULL, to know if input jpg has already been
decoded or not */
xVSS_context->pSettings->pTransitionList[i]->
pExtVideoTransitionFctCtxt = M4OSA_NULL;
switch( xVSS_context->pSettings->
pTransitionList[i]->VideoTransitionType )
{
/* If transition type is alpha magic, we need to decode input file */
case M4xVSS_kVideoTransitionType_AlphaMagic:
/* Allocate our alpha magic settings structure to have a copy of the
provided one */
xVSS_context->pSettings->pTransitionList[i]-> \
xVSS.transitionSpecific.pAlphaMagicSettings =
(M4xVSS_AlphaMagicSettings *)M4OSA_32bitAlignedMalloc \
(sizeof(M4xVSS_AlphaMagicSettings), M4VS,
(M4OSA_Char *)"Input Alpha magic settings structure");
if( xVSS_context->pSettings->pTransitionList[i]-> \
xVSS.transitionSpecific.pAlphaMagicSettings == M4OSA_NULL )
{
M4OSA_TRACE1_0(
"Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
/* Copy data from the provided alpha magic settings structure tou our
structure */
memcpy((void *)xVSS_context->pSettings->
pTransitionList[i]-> \
xVSS.transitionSpecific.pAlphaMagicSettings,
(void *)pSettings->pTransitionList[i]-> \
xVSS.transitionSpecific.pAlphaMagicSettings,
sizeof(M4xVSS_AlphaMagicSettings));
/* Allocate our alpha magic input filename */
xVSS_context->pSettings->pTransitionList[i]-> \
xVSS.transitionSpecific.pAlphaMagicSettings->
pAlphaFilePath = M4OSA_32bitAlignedMalloc(
(strlen(pSettings->pTransitionList[i]-> \
xVSS.transitionSpecific.pAlphaMagicSettings->pAlphaFilePath)
+ 1), M4VS, (M4OSA_Char *)"Alpha magic file path");
if( xVSS_context->pSettings->pTransitionList[i]-> \
xVSS.transitionSpecific.pAlphaMagicSettings->pAlphaFilePath
== M4OSA_NULL )
{
M4OSA_TRACE1_0(
"Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
/* Copy data from the provided alpha magic filename to our */
M4OSA_chrNCopy(
xVSS_context->pSettings->pTransitionList[i]->xVSS.
transitionSpecific.pAlphaMagicSettings->
pAlphaFilePath,
pSettings->pTransitionList[i]->xVSS.
transitionSpecific.pAlphaMagicSettings->
pAlphaFilePath, strlen(
pSettings->pTransitionList[i]->xVSS.
transitionSpecific.pAlphaMagicSettings->
pAlphaFilePath) + 1);
/* Parse all transition to know if the input jpg has already been decoded */
for ( j = 0; j < i; j++ )
{
if( xVSS_context->pSettings->
pTransitionList[j]->VideoTransitionType
== M4xVSS_kVideoTransitionType_AlphaMagic )
{
M4OSA_UInt32 pCmpResult = 0;
pCmpResult = strcmp((const char *)xVSS_context->pSettings->
pTransitionList[i]->xVSS.
transitionSpecific.pAlphaMagicSettings->
pAlphaFilePath, (const char *)xVSS_context->pSettings->
pTransitionList[j]->xVSS.
transitionSpecific.
pAlphaMagicSettings->pAlphaFilePath);
if( pCmpResult == 0 )
{
M4xVSS_internal_AlphaMagicSettings
*alphaSettings;
alphaSettings =
(M4xVSS_internal_AlphaMagicSettings
*)M4OSA_32bitAlignedMalloc(
sizeof(
M4xVSS_internal_AlphaMagicSettings),
M4VS,
(M4OSA_Char
*)
"Alpha magic settings structure 1");
if( alphaSettings == M4OSA_NULL )
{
M4OSA_TRACE1_0(
"Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send
command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
alphaSettings->pPlane =
((M4xVSS_internal_AlphaMagicSettings *)(
xVSS_context->pSettings->
pTransitionList[j]->
pExtVideoTransitionFctCtxt))->
pPlane;
if( xVSS_context->pSettings->
pTransitionList[i]->xVSS.transitionSpecific.
pAlphaMagicSettings->blendingPercent > 0
&& xVSS_context->pSettings->
pTransitionList[i]->xVSS.
transitionSpecific.
pAlphaMagicSettings->blendingPercent
<= 100 )
{
alphaSettings->blendingthreshold =
( xVSS_context->pSettings->
pTransitionList[i]->xVSS.
transitionSpecific.
pAlphaMagicSettings->
blendingPercent) * 255 / 200;
}
else
{
alphaSettings->blendingthreshold = 0;
}
alphaSettings->isreverse =
xVSS_context->pSettings->
pTransitionList[i]->xVSS.
transitionSpecific.
pAlphaMagicSettings->isreverse;
/* It means that the input jpg file for alpha magic has already
been decoded -> no nedd to decode it again */
if( alphaSettings->blendingthreshold == 0 )
{
xVSS_context->pSettings->
pTransitionList[i]->
ExtVideoTransitionFct =
M4xVSS_AlphaMagic;
}
else
{
xVSS_context->pSettings->
pTransitionList[i]->
ExtVideoTransitionFct =
M4xVSS_AlphaMagicBlending;
}
xVSS_context->pSettings->pTransitionList[i]->
pExtVideoTransitionFctCtxt = alphaSettings;
break;
}
}
}
/* If the jpg has not been decoded yet ... */
if( xVSS_context->pSettings->
pTransitionList[i]->pExtVideoTransitionFctCtxt
== M4OSA_NULL )
{
M4VIFI_ImagePlane *outputPlane;
M4xVSS_internal_AlphaMagicSettings *alphaSettings;
/*UTF conversion support*/
M4OSA_Void *pDecodedPath = M4OSA_NULL;
/*To support ARGB8888 : get the width and height */
M4OSA_UInt32 width_ARGB888 =
xVSS_context->pSettings->pTransitionList[i]->xVSS.
transitionSpecific.pAlphaMagicSettings->width;
M4OSA_UInt32 height_ARGB888 =
xVSS_context->pSettings->pTransitionList[i]->xVSS.
transitionSpecific.pAlphaMagicSettings->height;
M4OSA_TRACE1_1(
" TransitionListM4xVSS_SendCommand width State is %d",
width_ARGB888);
M4OSA_TRACE1_1(
" TransitionListM4xVSS_SendCommand height! State is %d",
height_ARGB888);
/* Allocate output plane */
outputPlane = (M4VIFI_ImagePlane *)M4OSA_32bitAlignedMalloc(3
* sizeof(M4VIFI_ImagePlane), M4VS, (M4OSA_Char
*)
"Output plane for Alpha magic transition");
if( outputPlane == M4OSA_NULL )
{
M4OSA_TRACE1_0(
"Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
outputPlane[0].u_width = width;
outputPlane[0].u_height = height;
outputPlane[0].u_topleft = 0;
outputPlane[0].u_stride = width;
outputPlane[0].pac_data = (M4VIFI_UInt8
*)M4OSA_32bitAlignedMalloc(( width * height * 3)
>> 1,
M4VS,
(M4OSA_Char
*)
"Alloc for the Alpha magic pac_data output YUV");
;
if( outputPlane[0].pac_data == M4OSA_NULL )
{
free(outputPlane);
outputPlane = M4OSA_NULL;
M4OSA_TRACE1_0(
"Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
outputPlane[1].u_width = width >> 1;
outputPlane[1].u_height = height >> 1;
outputPlane[1].u_topleft = 0;
outputPlane[1].u_stride = width >> 1;
outputPlane[1].pac_data = outputPlane[0].pac_data
+ outputPlane[0].u_width * outputPlane[0].u_height;
outputPlane[2].u_width = width >> 1;
outputPlane[2].u_height = height >> 1;
outputPlane[2].u_topleft = 0;
outputPlane[2].u_stride = width >> 1;
outputPlane[2].pac_data = outputPlane[1].pac_data
+ outputPlane[1].u_width * outputPlane[1].u_height;
pDecodedPath =
xVSS_context->pSettings->pTransitionList[i]->xVSS.
transitionSpecific.pAlphaMagicSettings->
pAlphaFilePath;
/**
* UTF conversion: convert into the customer format, before being used*/
if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
!= M4OSA_NULL && xVSS_context->
UTFConversionContext.
pTempOutConversionBuffer != M4OSA_NULL )
{
err = M4xVSS_internalConvertFromUTF8(xVSS_context,
(M4OSA_Void *)xVSS_context->pSettings->
pTransitionList[i]->xVSS.
transitionSpecific.
pAlphaMagicSettings->pAlphaFilePath,
(M4OSA_Void *)xVSS_context->
UTFConversionContext.
pTempOutConversionBuffer, &length);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1(
"M4xVSS_SendCommand: pConvFromUTF8Fct returns err: 0x%x",
err);
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
return err;
}
pDecodedPath =
xVSS_context->UTFConversionContext.
pTempOutConversionBuffer;
}
/**
End of the conversion, use the decoded path*/
/*To support ARGB8888 : convert + resizing from ARGB8888 to yuv420 */
err = M4xVSS_internalConvertAndResizeARGB8888toYUV420(
pDecodedPath,
xVSS_context->pFileReadPtr, outputPlane,
width_ARGB888, height_ARGB888);
if( err != M4NO_ERROR )
{
free(outputPlane[0].pac_data);
outputPlane[0].pac_data = M4OSA_NULL;
free(outputPlane);
outputPlane = M4OSA_NULL;
M4xVSS_freeCommand(xVSS_context);
M4OSA_TRACE1_1(
"M4xVSS_SendCommand: error when decoding alpha magic JPEG: 0x%x",
err);
return err;
}
/* Allocate alpha settings structure */
alphaSettings =
(M4xVSS_internal_AlphaMagicSettings *)M4OSA_32bitAlignedMalloc(
sizeof(M4xVSS_internal_AlphaMagicSettings),
M4VS, (M4OSA_Char
*)"Alpha magic settings structure 2");
if( alphaSettings == M4OSA_NULL )
{
M4OSA_TRACE1_0(
"Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
alphaSettings->pPlane = outputPlane;
if( xVSS_context->pSettings->pTransitionList[i]->xVSS.
transitionSpecific.pAlphaMagicSettings->
blendingPercent > 0 && xVSS_context->pSettings->
pTransitionList[i]->xVSS.
transitionSpecific.pAlphaMagicSettings->
blendingPercent <= 100 )
{
alphaSettings->blendingthreshold =
( xVSS_context->pSettings->
pTransitionList[i]->xVSS.
transitionSpecific.pAlphaMagicSettings->
blendingPercent) * 255 / 200;
}
else
{
alphaSettings->blendingthreshold = 0;
}
alphaSettings->isreverse =
xVSS_context->pSettings->pTransitionList[i]->xVSS.
transitionSpecific.pAlphaMagicSettings->
isreverse;
if( alphaSettings->blendingthreshold == 0 )
{
xVSS_context->pSettings->pTransitionList[i]->
ExtVideoTransitionFct = M4xVSS_AlphaMagic;
}
else
{
xVSS_context->pSettings->pTransitionList[i]->
ExtVideoTransitionFct =
M4xVSS_AlphaMagicBlending;
}
xVSS_context->pSettings->pTransitionList[i]->
pExtVideoTransitionFctCtxt = alphaSettings;
}
break;
case M4xVSS_kVideoTransitionType_SlideTransition:
{
M4xVSS_internal_SlideTransitionSettings *slideSettings;
slideSettings =
(M4xVSS_internal_SlideTransitionSettings *)M4OSA_32bitAlignedMalloc(
sizeof(M4xVSS_internal_SlideTransitionSettings),
M4VS, (M4OSA_Char
*)"Internal slide transition settings");
if( M4OSA_NULL == slideSettings )
{
M4OSA_TRACE1_0(
"Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
/* Just copy the lone parameter from the input settings to the internal
context. */
slideSettings->direction =
pSettings->pTransitionList[i]->xVSS.transitionSpecific.
pSlideTransitionSettings->direction;
/* No need to keep our copy of the settings. */
xVSS_context->pSettings->pTransitionList[i]->
xVSS.transitionSpecific.pSlideTransitionSettings =
M4OSA_NULL;
xVSS_context->pSettings->pTransitionList[i]->
ExtVideoTransitionFct = &M4xVSS_SlideTransition;
xVSS_context->pSettings->pTransitionList[i]->
pExtVideoTransitionFctCtxt = slideSettings;
}
break;
case M4xVSS_kVideoTransitionType_FadeBlack:
{
xVSS_context->pSettings->pTransitionList[i]->
ExtVideoTransitionFct = &M4xVSS_FadeBlackTransition;
}
break;
case M4xVSS_kVideoTransitionType_External:
{
xVSS_context->pSettings->pTransitionList[i]->
ExtVideoTransitionFct =
pSettings->pTransitionList[i]->ExtVideoTransitionFct;
xVSS_context->pSettings->pTransitionList[i]->
pExtVideoTransitionFctCtxt =
pSettings->pTransitionList[i]->
pExtVideoTransitionFctCtxt;
xVSS_context->pSettings->pTransitionList[i]->
VideoTransitionType =
M4VSS3GPP_kVideoTransitionType_External;
}
break;
default:
break;
} // switch
/* Update total_duration with transition duration */
totalDuration -= xVSS_context->pSettings->
pTransitionList[i]->uiTransitionDuration;
}
if( xVSS_context->pSettings->pClipList[i]->FileType
== M4VIDEOEDITING_kFileType_ARGB8888 )
{
if(M4OSA_TRUE ==
xVSS_context->pSettings->pClipList[i]->xVSS.isPanZoom) {
M4OSA_Char out_img[M4XVSS_MAX_PATH_LEN];
M4OSA_Char out_img_tmp[M4XVSS_MAX_PATH_LEN];
M4xVSS_Pto3GPP_params *pParams = M4OSA_NULL;
M4OSA_Context pARGBFileIn;
/*UTF conversion support*/
M4OSA_Void *pDecodedPath = pSettings->pClipList[i]->pFile;
/* Parse Pto3GPP params chained list to know if input file has already been
converted */
if( xVSS_context->pPTo3GPPparamsList != M4OSA_NULL )
{
M4OSA_UInt32 pCmpResult = 0;
pParams = xVSS_context->pPTo3GPPparamsList;
/* We parse all Pto3gpp Param chained list */
while( pParams != M4OSA_NULL )
{
pCmpResult = strcmp((const char *)pSettings->pClipList[i]->pFile,
(const char *)pParams->pFileIn);
if( pCmpResult == 0
&& (pSettings->pClipList[i]->uiEndCutTime
== pParams->duration
|| pSettings->pClipList[i]->xVSS.uiDuration
== pParams->duration)
&& pSettings->pClipList[i]->xVSS.MediaRendering
== pParams->MediaRendering )
{
/* Replace JPG filename with existing 3GP filename */
goto replaceARGB_3GP;
}
/* We need to update this variable, in case some pictures have been
added between two */
/* calls to M4xVSS_sendCommand */
pPto3GPP_last = pParams;
pParams = pParams->pNext;
}
}
/* Construct output temporary 3GP filename */
err = M4OSA_chrSPrintf(out_img, M4XVSS_MAX_PATH_LEN - 1, (M4OSA_Char *)"%simg%d.3gp",
xVSS_context->pTempPath, xVSS_context->tempFileIndex);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1("Error in M4OSA_chrSPrintf: 0x%x", err);
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return err;
}
#ifdef M4xVSS_RESERVED_MOOV_DISK_SPACE
err = M4OSA_chrSPrintf(out_img_tmp, M4XVSS_MAX_PATH_LEN - 1, "%simg%d.tmp",
xVSS_context->pTempPath, xVSS_context->tempFileIndex);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1("Error in M4OSA_chrSPrintf: 0x%x", err);
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return err;
}
#endif /*M4xVSS_RESERVED_MOOV_DISK_SPACE*/
xVSS_context->tempFileIndex++;
/* Allocate last element Pto3GPP params structure */
pParams = (M4xVSS_Pto3GPP_params
*)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_Pto3GPP_params),
M4VS, (M4OSA_Char *)"Element of Pto3GPP Params");
if( pParams == M4OSA_NULL )
{
M4OSA_TRACE1_0(
"M4xVSS_sendCommand: Problem when allocating one element Pto3GPP Params");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
/* Initializes pfilexxx members of pParams to be able to free them correctly */
pParams->pFileIn = M4OSA_NULL;
pParams->pFileOut = M4OSA_NULL;
pParams->pFileTemp = M4OSA_NULL;
pParams->pNext = M4OSA_NULL;
pParams->MediaRendering = M4xVSS_kResizing;
/*To support ARGB8888 :get the width and height */
pParams->height = pSettings->pClipList[
i]->ClipProperties.uiStillPicHeight; //ARGB_Height;
pParams->width = pSettings->pClipList[
i]->ClipProperties.uiStillPicWidth; //ARGB_Width;
M4OSA_TRACE3_1("CLIP M4xVSS_SendCommand ARGB8888 H = %d", pParams->height);
M4OSA_TRACE3_1("CLIP M4xVSS_SendCommand ARGB8888 W = %d", pParams->width);
if( xVSS_context->pPTo3GPPparamsList
== M4OSA_NULL ) /* Means it is the first element of the list */
{
/* Initialize the xVSS context with the first element of the list */
xVSS_context->pPTo3GPPparamsList = pParams;
/* Save this element in case of other file to convert */
pPto3GPP_last = pParams;
}
else
{
/* Update next pointer of the previous last element of the chain */
pPto3GPP_last->pNext = pParams;
/* Update save of last element of the chain */
pPto3GPP_last = pParams;
}
/* Fill the last M4xVSS_Pto3GPP_params element */
pParams->duration =
xVSS_context->pSettings->pClipList[i]->uiEndCutTime;
/* If duration is filled, let's use it instead of EndCutTime */
if( xVSS_context->pSettings->pClipList[i]->xVSS.uiDuration != 0 )
{
pParams->duration =
xVSS_context->pSettings->pClipList[i]->xVSS.uiDuration;
}
pParams->InputFileType = M4VIDEOEDITING_kFileType_ARGB8888;
/**
* UTF conversion: convert into the customer format, before being used*/
pDecodedPath = xVSS_context->pSettings->pClipList[i]->pFile;
length = strlen(pDecodedPath);
/**
* UTF conversion: convert into the customer format, before being used*/
if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
!= M4OSA_NULL && xVSS_context->
UTFConversionContext.pTempOutConversionBuffer
!= M4OSA_NULL )
{
err = M4xVSS_internalConvertFromUTF8(xVSS_context, (M4OSA_Void
*)xVSS_context->pSettings->pClipList[i]->pFile,
(M4OSA_Void *)xVSS_context->
UTFConversionContext.pTempOutConversionBuffer,
&length);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1(
"M4xVSS_SendCommand: pConvFromUTF8Fct returns err: 0x%x",
err);
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
return err;
}
pDecodedPath =
xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
}
/**
* End of the UTF conversion, use the converted file path*/
pParams->pFileIn = (M4OSA_Void *)M4OSA_32bitAlignedMalloc(length + 1, M4VS,
(M4OSA_Char *)"Pto3GPP Params: file in");
if( pParams->pFileIn == M4OSA_NULL )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
memcpy((void *)pParams->pFileIn, (void *)pDecodedPath,
(length + 1)); /* Copy input file path */
/* Check that JPG file is present on the FS (P4ME00002974) by just opening
and closing it */
err =
xVSS_context->pFileReadPtr->openRead(&pARGBFileIn, pDecodedPath,
M4OSA_kFileRead);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_2("Can't open input jpg file %s, error: 0x%x\n",
pDecodedPath, err);
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
return err;
}
err = xVSS_context->pFileReadPtr->closeRead(pARGBFileIn);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_2("Can't close input jpg file %s, error: 0x%x\n",
pDecodedPath, err);
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
return err;
}
/**
* UTF conversion: convert into the customer format, before being used*/
pDecodedPath = out_img;
length = strlen(pDecodedPath);
if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
!= M4OSA_NULL && xVSS_context->
UTFConversionContext.pTempOutConversionBuffer
!= M4OSA_NULL )
{
err = M4xVSS_internalConvertFromUTF8(xVSS_context,
(M4OSA_Void *)out_img, (M4OSA_Void *)xVSS_context->
UTFConversionContext.pTempOutConversionBuffer, &length);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1(
"M4xVSS_SendCommand: pConvFromUTF8Fct returns err: 0x%x",
err);
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
return err;
}
pDecodedPath =
xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
}
/**
* End of the UTF conversion, use the converted file path*/
pParams->pFileOut = (M4OSA_Void *)M4OSA_32bitAlignedMalloc((length + 1), M4VS,
(M4OSA_Char *)"Pto3GPP Params: file out");
if( pParams->pFileOut == M4OSA_NULL )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
memcpy((void *)pParams->pFileOut, (void *)pDecodedPath,
(length + 1)); /* Copy output file path */
#ifdef M4xVSS_RESERVED_MOOV_DISK_SPACE
/**
* UTF conversion: convert into the customer format, before being used*/
pDecodedPath = out_img_tmp;
length = strlen(pDecodedPath);
if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
!= M4OSA_NULL && xVSS_context->
UTFConversionContext.pTempOutConversionBuffer
!= M4OSA_NULL )
{
err = M4xVSS_internalConvertFromUTF8(xVSS_context,
(M4OSA_Void *)out_img_tmp, (M4OSA_Void *)xVSS_context->
UTFConversionContext.pTempOutConversionBuffer, &length);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1("M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8\
returns err: 0x%x",
err);
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
return err;
}
pDecodedPath =
xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
}
/**
* End of the UTF conversion, use the converted file path*/
pParams->pFileTemp = (M4OSA_Void *)M4OSA_32bitAlignedMalloc((length + 1), M4VS,
(M4OSA_Char *)"Pto3GPP Params: file temp");
if( pParams->pFileTemp == M4OSA_NULL )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
memcpy((void *)pParams->pFileTemp, (void *)pDecodedPath,
(length + 1)); /* Copy temporary file path */
#endif /*M4xVSS_RESERVED_MOOV_DISK_SPACE*/
/* Fill PanAndZoom settings if needed */
if( M4OSA_TRUE
== xVSS_context->pSettings->pClipList[i]->xVSS.isPanZoom )
{
pParams->isPanZoom =
xVSS_context->pSettings->pClipList[i]->xVSS.isPanZoom;
/* Check that Pan & Zoom parameters are corrects */
if( xVSS_context->pSettings->pClipList[i]->xVSS.PanZoomXa > 1000
|| xVSS_context->pSettings->pClipList[i]->xVSS.PanZoomXa
<= 0 || xVSS_context->pSettings->pClipList[i]->xVSS.
PanZoomTopleftXa > 1000
|| xVSS_context->pSettings->pClipList[i]->xVSS.
PanZoomTopleftYa > 1000
|| xVSS_context->pSettings->pClipList[i]->xVSS.PanZoomXb
> 1000
|| xVSS_context->pSettings->pClipList[i]->xVSS.PanZoomXb
<= 0 || xVSS_context->pSettings->pClipList[i]->xVSS.
PanZoomTopleftXb > 1000
|| xVSS_context->pSettings->pClipList[i]->xVSS.
PanZoomTopleftYb > 1000)
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
M4xVSS_freeCommand(xVSS_context);
return M4ERR_PARAMETER;
}
pParams->PanZoomXa =
xVSS_context->pSettings->pClipList[i]->xVSS.PanZoomXa;
pParams->PanZoomTopleftXa =
xVSS_context->pSettings->
pClipList[i]->xVSS.PanZoomTopleftXa;
pParams->PanZoomTopleftYa =
xVSS_context->pSettings->
pClipList[i]->xVSS.PanZoomTopleftYa;
pParams->PanZoomXb =
xVSS_context->pSettings->pClipList[i]->xVSS.PanZoomXb;
pParams->PanZoomTopleftXb =
xVSS_context->pSettings->
pClipList[i]->xVSS.PanZoomTopleftXb;
pParams->PanZoomTopleftYb =
xVSS_context->pSettings->
pClipList[i]->xVSS.PanZoomTopleftYb;
}
else
{
pParams->isPanZoom = M4OSA_FALSE;
}
/*+ PR No: blrnxpsw#223*/
/*Intializing the Video Frame Rate as it may not be intialized*/
/*Other changes made is @ M4xVSS_Internal.c @ line 1518 in
M4xVSS_internalStartConvertPictureTo3gp*/
switch( xVSS_context->pSettings->videoFrameRate )
{
case M4VIDEOEDITING_k30_FPS:
pParams->framerate = 33;
break;
case M4VIDEOEDITING_k25_FPS:
pParams->framerate = 40;
break;
case M4VIDEOEDITING_k20_FPS:
pParams->framerate = 50;
break;
case M4VIDEOEDITING_k15_FPS:
pParams->framerate = 66;
break;
case M4VIDEOEDITING_k12_5_FPS:
pParams->framerate = 80;
break;
case M4VIDEOEDITING_k10_FPS:
pParams->framerate = 100;
break;
case M4VIDEOEDITING_k7_5_FPS:
pParams->framerate = 133;
break;
case M4VIDEOEDITING_k5_FPS:
pParams->framerate = 200;
break;
default:
/*Making Default Frame Rate @ 15 FPS*/
pParams->framerate = 66;
break;
}
/*-PR No: blrnxpsw#223*/
if( xVSS_context->pSettings->pClipList[i]->xVSS.MediaRendering
== M4xVSS_kCropping
|| xVSS_context->pSettings->pClipList[i]->xVSS.
MediaRendering == M4xVSS_kBlackBorders
|| xVSS_context->pSettings->pClipList[i]->xVSS.
MediaRendering == M4xVSS_kResizing )
{
pParams->MediaRendering =
xVSS_context->pSettings->pClipList[i]->xVSS.MediaRendering;
}
pParams->pNext = M4OSA_NULL;
pParams->isCreated = M4OSA_FALSE;
xVSS_context->nbStepTotal++;
/* Set bTranscodingRequired to TRUE to indicate the kenburn video has
* been generated in analysis phase, and does not need to be tanscoded again
* in saving phase */
xVSS_context->pSettings->pClipList[i]->bTranscodingRequired =
M4OSA_TRUE;
replaceARGB_3GP:
/* Update total duration */
totalDuration += pParams->duration;
/* Replacing in VSS structure the JPG file by the 3gp file */
xVSS_context->pSettings->pClipList[i]->FileType =
M4VIDEOEDITING_kFileType_3GPP;
if( xVSS_context->pSettings->pClipList[i]->pFile != M4OSA_NULL )
{
free(xVSS_context->pSettings->pClipList[i]->pFile);
xVSS_context->pSettings->pClipList[i]->pFile = M4OSA_NULL;
}
/**
* UTF conversion: convert into UTF8, before being used*/
pDecodedPath = pParams->pFileOut;
if( xVSS_context->UTFConversionContext.pConvToUTF8Fct != M4OSA_NULL
&& xVSS_context->UTFConversionContext.pTempOutConversionBuffer
!= M4OSA_NULL )
{
err = M4xVSS_internalConvertToUTF8(xVSS_context,
(M4OSA_Void *)pParams->pFileOut,
(M4OSA_Void *)xVSS_context->
UTFConversionContext.pTempOutConversionBuffer,
&length);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1(
"M4xVSS_SendCommand: M4xVSS_internalConvertToUTF8 returns err: \
0x%x",err);
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
return err;
}
pDecodedPath =
xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
}
else
{
length = strlen(pDecodedPath);
}
/**
* End of the UTF conversion, use the converted file path*/
xVSS_context->pSettings->pClipList[i]->pFile = M4OSA_32bitAlignedMalloc((length
+ 1), M4VS, (M4OSA_Char *)"xVSS file path of ARGB to 3gp");
if( xVSS_context->pSettings->pClipList[i]->pFile == M4OSA_NULL )
{
M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
memcpy((void *)xVSS_context->pSettings->pClipList[i]->pFile,
(void *)pDecodedPath, (length + 1));
/*FB: add file path size because of UTF16 conversion*/
xVSS_context->pSettings->pClipList[i]->filePathSize = length+1;
}
}
/************************
3GP input file type case
*************************/
else if( xVSS_context->pSettings->pClipList[i]->FileType
== M4VIDEOEDITING_kFileType_3GPP
|| xVSS_context->pSettings->pClipList[i]->FileType
== M4VIDEOEDITING_kFileType_MP4
|| xVSS_context->pSettings->pClipList[i]->FileType
== M4VIDEOEDITING_kFileType_M4V )
{
/*UTF conversion support*/
M4OSA_Void *pDecodedPath = M4OSA_NULL;
/* Need to call MCS in case 3GP video/audio types are not compatible
(H263/MPEG4 or AMRNB/AAC) */
/* => Need to fill MCS_Params structure with the right parameters ! */
/* Need also to parse MCS params struct to check if file has already been transcoded */
M4VIDEOEDITING_ClipProperties fileProperties;
M4xVSS_MCS_params *pParams;
M4OSA_Bool audioIsDifferent = M4OSA_FALSE;
M4OSA_Bool videoIsDifferent = M4OSA_FALSE;
M4OSA_Bool bAudioMono;
/* Initialize file properties structure */
memset((void *) &fileProperties,0,
sizeof(M4VIDEOEDITING_ClipProperties));
//fileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio;
/* Prevent from bad initializing of percentage cut time */
if( xVSS_context->pSettings->pClipList[i]->xVSS.uiEndCutPercent
> 100 || xVSS_context->pSettings->pClipList[i]->xVSS.
uiBeginCutPercent > 100 )
{
/* These percentage cut time have probably not been initialized */
/* Let's not use them by setting them to 0 */
xVSS_context->pSettings->pClipList[i]->xVSS.uiEndCutPercent = 0;
xVSS_context->pSettings->pClipList[i]->xVSS.uiBeginCutPercent =
0;
}
/**
* UTF conversion: convert into the customer format, before being used*/
pDecodedPath = xVSS_context->pSettings->pClipList[i]->pFile;
if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
!= M4OSA_NULL && xVSS_context->
UTFConversionContext.pTempOutConversionBuffer
!= M4OSA_NULL )
{
err = M4xVSS_internalConvertFromUTF8(xVSS_context, (M4OSA_Void
*)xVSS_context->pSettings->pClipList[i]->pFile,
(M4OSA_Void *)xVSS_context->
UTFConversionContext.pTempOutConversionBuffer,
&length);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1(
"M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
err);
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
return err;
}
pDecodedPath =
xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
}
/**
* End of the UTF conversion, use the converted file path*/
err = M4xVSS_internalGetProperties(xVSS_context, pDecodedPath,
&fileProperties);
if( err != M4NO_ERROR )
{
M4xVSS_freeCommand(xVSS_context);
M4OSA_TRACE1_1(
"M4xVSS_sendCommand: M4xVSS_internalGetProperties returned 0x%x",
err);
/* TODO: Translate error code of MCS to an xVSS error code */
return err;
}
/* Parse MCS params chained list to know if input file has already been converted */
if( xVSS_context->pMCSparamsList != M4OSA_NULL )
{
M4OSA_UInt32 pCmpResult = 0;
pParams = xVSS_context->pMCSparamsList;
/* We parse all MCS Param chained list */
while( pParams != M4OSA_NULL )
{
/**
* UTF conversion: convert into UTF8, before being used*/
pDecodedPath = pParams->pFileIn;
if( xVSS_context->UTFConversionContext.pConvToUTF8Fct
!= M4OSA_NULL && xVSS_context->
UTFConversionContext.pTempOutConversionBuffer
!= M4OSA_NULL )
{
err = M4xVSS_internalConvertToUTF8(xVSS_context,
(M4OSA_Void *)pParams->pFileIn,
(M4OSA_Void *)xVSS_context->
UTFConversionContext.
pTempOutConversionBuffer, &length);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1(
"M4xVSS_SendCommand: M4xVSS_internalConvertToUTF8 returns err:\
0x%x", err);
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
return err;
}
pDecodedPath = xVSS_context->
UTFConversionContext.pTempOutConversionBuffer;
}
/**
* End of the UTF conversion, use the converted file path*/
pCmpResult = strcmp((const char *)pSettings->pClipList[i]->pFile,
(const char *)pDecodedPath);
/* If input filenames are the same, and if this is not a BGM, we can reuse
the transcoded file */
if( pCmpResult == 0 && pParams->isBGM == M4OSA_FALSE
&& pParams->BeginCutTime
== pSettings->pClipList[i]->uiBeginCutTime
&& (pParams->EndCutTime
== pSettings->pClipList[i]->uiEndCutTime
|| pParams->EndCutTime
== pSettings->pClipList[i]->uiBeginCutTime
+ pSettings->pClipList[i]->xVSS.uiDuration)
&& pSettings->pClipList[i]->xVSS.MediaRendering
== pParams->MediaRendering )
{
if( pSettings->xVSS.pBGMtrack != M4OSA_NULL )
{
if( pSettings->xVSS.pBGMtrack->uiAddVolume == 100
|| (pParams->OutputAudioFormat
== M4VIDEOEDITING_kNullAudio
&& fileProperties.AudioStreamType
== pSettings->xVSS.outputAudioFormat)
|| pParams->OutputAudioFormat
== pSettings->xVSS.outputAudioFormat
|| fileProperties.AudioStreamType
== M4VIDEOEDITING_kNoneAudio )
{
/* Replace 3GP filename with transcoded 3GP filename */
goto replace3GP_3GP;
}
}
else if( ( pParams->OutputAudioFormat
== M4VIDEOEDITING_kNullAudio
&& fileProperties.AudioStreamType
== pSettings->xVSS.outputAudioFormat)
|| pParams->OutputAudioFormat
== pSettings->xVSS.outputAudioFormat
|| fileProperties.AudioStreamType
== M4VIDEOEDITING_kNoneAudio )
{
/* Replace 3GP filename with transcoded 3GP filename */
goto replace3GP_3GP;
}
}
/* We need to update this variable, in case some 3GP files have been added
between two */
/* calls to M4xVSS_sendCommand */
pMCS_last = pParams;
pParams = pParams->pNext;
}
}
/* If we have percentage information let's use it... */
if( xVSS_context->pSettings->pClipList[i]->xVSS.uiEndCutPercent != 0
|| xVSS_context->pSettings->pClipList[i]->xVSS.uiBeginCutPercent
!= 0 )
{
/* If percentage information are not correct and if duration field is not filled */
if( ( xVSS_context->pSettings->pClipList[i]->xVSS.
uiEndCutPercent
<= xVSS_context->pSettings->pClipList[i]->xVSS.
uiBeginCutPercent)
&& xVSS_context->pSettings->pClipList[i]->xVSS.uiDuration
== 0 )
{
M4OSA_TRACE1_0(
"M4xVSS_sendCommand: Bad percentage for begin and end cut time !");
M4xVSS_freeCommand(xVSS_context);
return M4ERR_PARAMETER;
}
/* We transform the percentage into absolute time */
xVSS_context->pSettings->pClipList[i]->uiBeginCutTime
= (M4OSA_UInt32)(
xVSS_context->pSettings->pClipList[i]->xVSS.
uiBeginCutPercent
* fileProperties.uiClipDuration / 100);
xVSS_context->pSettings->pClipList[i]->uiEndCutTime
= (M4OSA_UInt32)(
xVSS_context->pSettings->pClipList[i]->xVSS.
uiEndCutPercent
* fileProperties.uiClipDuration / 100);
}
/* ...Otherwise, we use absolute time. */
else
{
/* If endCutTime == 0, it means all the file is taken. Let's change to the file
duration, to accurate preview. */
if( xVSS_context->pSettings->pClipList[i]->uiEndCutTime == 0
|| xVSS_context->pSettings->pClipList[i]->uiEndCutTime
> fileProperties.uiClipDuration )
{
xVSS_context->pSettings->pClipList[i]->uiEndCutTime =
fileProperties.uiClipDuration;
}
}
/* If duration field is filled, it has priority on other fields on EndCutTime,
so let's use it */
if( xVSS_context->pSettings->pClipList[i]->xVSS.uiDuration != 0 )
{
xVSS_context->pSettings->pClipList[i]->uiEndCutTime =
xVSS_context->pSettings->pClipList[i]->uiBeginCutTime
+xVSS_context->pSettings->pClipList[i]->xVSS.uiDuration;
if( xVSS_context->pSettings->pClipList[i]->uiEndCutTime
> fileProperties.uiClipDuration )
{
xVSS_context->pSettings->pClipList[i]->uiEndCutTime =
fileProperties.uiClipDuration;
}
}
/* If output video format is not set, we take video format of the first 3GP video */
if( xVSS_context->pSettings->xVSS.outputVideoFormat
== M4VIDEOEDITING_kNoneVideo )
{
//xVSS_context->pSettings->xVSS.outputVideoFormat = fileProperties.VideoStreamType;
//M4OSA_TRACE2_1("Output video format is not set, set it to current clip: %d",
// xVSS_context->pSettings->xVSS.outputVideoFormat);
M4OSA_TRACE1_0(
"Output video format is not set, an error parameter is returned.");
M4xVSS_freeCommand(xVSS_context);
return M4ERR_PARAMETER;
}
if( xVSS_context->pSettings->xVSS.outputAudioFormat
== M4VIDEOEDITING_kNoneAudio )
{
//xVSS_context->pSettings->xVSS.outputAudioFormat = fileProperties.AudioStreamType;
M4OSA_TRACE2_1(
"Output audio format is not set -> remove audio track of clip: %d",
i);
}
if( fileProperties.uiNbChannels == 1 )
{
bAudioMono = M4OSA_TRUE;
}
else
{
bAudioMono = M4OSA_FALSE;
}
if( fileProperties.AudioStreamType
!= xVSS_context->pSettings->xVSS.outputAudioFormat
|| (fileProperties.AudioStreamType == M4VIDEOEDITING_kAAC
&& (fileProperties.uiSamplingFrequency != samplingFreq
|| bAudioMono
!= xVSS_context->pSettings->xVSS.bAudioMono)) )
{
audioIsDifferent = M4OSA_TRUE;
/* If we want to replace audio, there is no need to transcode audio */
if( pSettings->xVSS.pBGMtrack != M4OSA_NULL )
{
/* temp fix :PT volume not herad in the second clip */
if( /*(pSettings->xVSS.pBGMtrack->uiAddVolume == 100
&& xVSS_context->pSettings->xVSS.outputFileSize == 0)
||*/
fileProperties.AudioStreamType
== M4VIDEOEDITING_kNoneAudio ) /*11/12/2008 CR 3283 VAL for the MMS
use case, we need to transcode except the media without audio*/
{
audioIsDifferent = M4OSA_FALSE;
}
}
else if( fileProperties.AudioStreamType
== M4VIDEOEDITING_kNoneAudio )
{
audioIsDifferent = M4OSA_FALSE;
}
}
/* Here check the clip video profile and level, if it exceeds
* the profile and level of export file, then the file needs
* to be transcoded(do not do compress domain trim).
* Also for MPEG4 fomart, always do transcoding since HW encoder
* may use different time scale value than the input clip*/
if ((fileProperties.uiVideoProfile >
xVSS_context->pSettings->xVSS.outputVideoProfile) ||
(fileProperties.uiVideoLevel >
xVSS_context->pSettings->xVSS.outputVideoLevel) ||
(fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)) {
/* Set bTranscodingRequired to TRUE to indicate the video will be
* transcoded in MCS. */
xVSS_context->pSettings->pClipList[i]->bTranscodingRequired =
M4OSA_TRUE;
videoIsDifferent = M4OSA_TRUE;
}
if( videoIsDifferent == M4OSA_TRUE || audioIsDifferent == M4OSA_TRUE)
{
M4OSA_Char out_3gp[M4XVSS_MAX_PATH_LEN];
M4OSA_Char out_3gp_tmp[M4XVSS_MAX_PATH_LEN];
/* Construct output temporary 3GP filename */
err = M4OSA_chrSPrintf(out_3gp, M4XVSS_MAX_PATH_LEN - 1, (M4OSA_Char *)"%svid%d.3gp",
xVSS_context->pTempPath, xVSS_context->tempFileIndex);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1("Error in M4OSA_chrSPrintf: 0x%x", err);
return err;
}
#ifdef M4xVSS_RESERVED_MOOV_DISK_SPACE
err = M4OSA_chrSPrintf(out_3gp_tmp, M4XVSS_MAX_PATH_LEN - 1, "%svid%d.tmp",
xVSS_context->pTempPath, xVSS_context->tempFileIndex);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1("Error in M4OSA_chrSPrintf: 0x%x", err);
return err;
}
#endif /*M4xVSS_RESERVED_MOOV_DISK_SPACE*/
xVSS_context->tempFileIndex++;
pParams =
(M4xVSS_MCS_params *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_MCS_params),
M4VS, (M4OSA_Char *)"Element of MCS Params (for 3GP)");
if( pParams == M4OSA_NULL )
{
M4OSA_TRACE1_0(
"M4xVSS_sendCommand: Problem when allocating one element MCS Params");
/*FB: to avoid leaks when there is an error in the send command*/
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
/**/
return M4ERR_ALLOC;
}
pParams->MediaRendering = M4xVSS_kResizing;
pParams->videoclipnumber = i; // Indicates video clip index
if( xVSS_context->pMCSparamsList
== M4OSA_NULL ) /* Means it is the first element of the list */
{
/* Initialize the xVSS context with the first element of the list */
xVSS_context->pMCSparamsList = pParams;
}
else
{
/* Update next pointer of the previous last element of the chain */
pMCS_last->pNext = pParams;
}
/* Save this element in case of other file to convert */
pMCS_last = pParams;
/* Fill the last M4xVSS_MCS_params element */
pParams->InputFileType = M4VIDEOEDITING_kFileType_3GPP;
pParams->OutputFileType = M4VIDEOEDITING_kFileType_3GPP;
pParams->OutputVideoTimescale = xVSS_context->targetedTimescale;
/* We do not need to reencode video if its parameters do not differ */
/* from output settings parameters */
if( videoIsDifferent == M4OSA_TRUE )
{
pParams->OutputVideoFormat =
xVSS_context->pSettings->xVSS.outputVideoFormat;
pParams->outputVideoProfile =
xVSS_context->pSettings->xVSS.outputVideoProfile;
pParams->outputVideoLevel =
xVSS_context->pSettings->xVSS.outputVideoLevel;
pParams->OutputVideoFrameRate =
xVSS_context->pSettings->videoFrameRate;
pParams->OutputVideoFrameSize =
xVSS_context->pSettings->xVSS.outputVideoSize;
/*FB: VAL CR P4ME00003076
The output video bitrate is now directly given by the user in the edition
settings structure If the bitrate given by the user is irrelevant
(the MCS minimum and maximum video bitrate are used),
the output video bitrate is hardcoded according to the output video size*/
if( xVSS_context->pSettings->xVSS.outputVideoBitrate
>= M4VIDEOEDITING_k16_KBPS
&& xVSS_context->pSettings->xVSS.outputVideoBitrate
<= M4VIDEOEDITING_k8_MBPS ) /*+ New Encoder bitrates */
{
pParams->OutputVideoBitrate =
xVSS_context->pSettings->xVSS.outputVideoBitrate;
}
else
{
switch( xVSS_context->pSettings->xVSS.outputVideoSize )
{
case M4VIDEOEDITING_kSQCIF:
pParams->OutputVideoBitrate =
M4VIDEOEDITING_k48_KBPS;
break;
case M4VIDEOEDITING_kQQVGA:
pParams->OutputVideoBitrate =
M4VIDEOEDITING_k64_KBPS;
break;
case M4VIDEOEDITING_kQCIF:
pParams->OutputVideoBitrate =
M4VIDEOEDITING_k128_KBPS;
break;
case M4VIDEOEDITING_kQVGA:
pParams->OutputVideoBitrate =
M4VIDEOEDITING_k384_KBPS;
break;
case M4VIDEOEDITING_kCIF:
pParams->OutputVideoBitrate =
M4VIDEOEDITING_k384_KBPS;
break;
case M4VIDEOEDITING_kVGA:
pParams->OutputVideoBitrate =
M4VIDEOEDITING_k512_KBPS;
break;
default: /* Should not happen !! */
pParams->OutputVideoBitrate =
M4VIDEOEDITING_k64_KBPS;
break;
}
}
}
else
{
pParams->outputVideoProfile =
xVSS_context->pSettings->xVSS.outputVideoProfile;
pParams->outputVideoLevel =
xVSS_context->pSettings->xVSS.outputVideoLevel;
pParams->OutputVideoFormat = M4VIDEOEDITING_kNullVideo;
pParams->OutputVideoFrameRate =
M4VIDEOEDITING_k15_FPS; /* Must be set, otherwise, MCS returns an error */
}
if( audioIsDifferent == M4OSA_TRUE )
{
pParams->OutputAudioFormat =
xVSS_context->pSettings->xVSS.outputAudioFormat;
switch( xVSS_context->pSettings->xVSS.outputAudioFormat )
{
case M4VIDEOEDITING_kNoneAudio:
break;
case M4VIDEOEDITING_kAMR_NB:
pParams->OutputAudioBitrate =
M4VIDEOEDITING_k12_2_KBPS;
pParams->bAudioMono = M4OSA_TRUE;
pParams->OutputAudioSamplingFrequency =
M4VIDEOEDITING_kDefault_ASF;
break;
case M4VIDEOEDITING_kAAC:
{
/*FB: VAL CR P4ME00003076
The output audio bitrate in the AAC case is now directly given by
the user in the edition settings structure
If the bitrate given by the user is irrelevant or undefined
(the MCS minimum and maximum audio bitrate are used),
the output audio bitrate is hard coded according to the output
audio sampling frequency*/
/*Check if the audio bitrate is correctly defined*/
/*Mono
MCS values for AAC Mono are min: 16kbps and max: 192 kbps*/
if( xVSS_context->pSettings->xVSS.outputAudioBitrate
>= M4VIDEOEDITING_k16_KBPS
&& xVSS_context->pSettings->
xVSS.outputAudioBitrate
<= M4VIDEOEDITING_k192_KBPS
&& xVSS_context->pSettings->xVSS.bAudioMono
== M4OSA_TRUE )
{
pParams->OutputAudioBitrate =
xVSS_context->pSettings->
xVSS.outputAudioBitrate;
}
/*Stereo
MCS values for AAC Mono are min: 32kbps and max: 192 kbps*/
else if( xVSS_context->pSettings->
xVSS.outputAudioBitrate
>= M4VIDEOEDITING_k32_KBPS
&& xVSS_context->pSettings->
xVSS.outputAudioBitrate
<= M4VIDEOEDITING_k192_KBPS
&& xVSS_context->pSettings->xVSS.bAudioMono
== M4OSA_FALSE )
{
pParams->OutputAudioBitrate =
xVSS_context->pSettings->
xVSS.outputAudioBitrate;
}
/*The audio bitrate is hard coded according to the output audio
sampling frequency*/
else
{
switch( xVSS_context->pSettings->
xVSS.outputAudioSamplFreq )
{
case M4VIDEOEDITING_k16000_ASF:
pParams->OutputAudioBitrate =
M4VIDEOEDITING_k24_KBPS;
break;
case M4VIDEOEDITING_k22050_ASF:
case M4VIDEOEDITING_k24000_ASF:
pParams->OutputAudioBitrate =
M4VIDEOEDITING_k32_KBPS;
break;
case M4VIDEOEDITING_k32000_ASF:
pParams->OutputAudioBitrate =
M4VIDEOEDITING_k48_KBPS;
break;
case M4VIDEOEDITING_k44100_ASF:
case M4VIDEOEDITING_k48000_ASF:
pParams->OutputAudioBitrate =
M4VIDEOEDITING_k64_KBPS;
break;
default:
pParams->OutputAudioBitrate =
M4VIDEOEDITING_k64_KBPS;
break;
}
if( xVSS_context->pSettings->xVSS.bAudioMono
== M4OSA_FALSE )
{
/* Output bitrate have to be doubled */
pParams->OutputAudioBitrate +=
pParams->OutputAudioBitrate;
}
}
pParams->bAudioMono =
xVSS_context->pSettings->xVSS.bAudioMono;
if( xVSS_context->pSettings->
xVSS.outputAudioSamplFreq
== M4VIDEOEDITING_k8000_ASF )
{
/* Prevent from unallowed sampling frequencies */
pParams->OutputAudioSamplingFrequency =
M4VIDEOEDITING_kDefault_ASF;
}
else
{
pParams->OutputAudioSamplingFrequency =
xVSS_context->pSettings->
xVSS.outputAudioSamplFreq;
}
break;
}
default: /* Should not happen !! */
pParams->OutputAudioFormat = M4VIDEOEDITING_kAMR_NB;
pParams->OutputAudioBitrate =
M4VIDEOEDITING_k12_2_KBPS;
pParams->bAudioMono = M4OSA_TRUE;
pParams->OutputAudioSamplingFrequency =
M4VIDEOEDITING_kDefault_ASF;
break;
}
}
else
{
pParams->OutputAudioFormat = M4VIDEOEDITING_kNullAudio;
}
/**
* UTF conversion: convert into the customer format, before being used*/
pDecodedPath = xVSS_context->pSettings->pClipList[i]->pFile;
length = strlen(pDecodedPath);
if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
!= M4OSA_NULL && xVSS_context->
UTFConversionContext.pTempOutConversionBuffer
!= M4OSA_NULL )
{
err = M4xVSS_internalConvertFromUTF8(xVSS_context,
(M4OSA_Void *)xVSS_context->pSettings->
pClipList[i]->pFile,
(M4OSA_Void *)xVSS_context->
UTFConversionContext.pTempOutConversionBuffer,
&length);
if( err != M4NO_ERROR )
{
M4OSA_TRACE1_1(
"M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
err);
/* Free Send command */
M4xVSS_freeCommand(xVSS_context);
return err;
}
pDecodedPath = xVSS_context->
UTFConversionContext.pTempOutConversionBuffer;
}
/**
* End of the UTF conversion, use the converted file path*/
pParams->pFileIn =
(M4OSA_Void *)M4OSA_32bitAlignedMalloc((length + 1), M4VS,
(M4OSA_Char *)"MCS 3GP Params: file in");