1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16/**
17 ******************************************************************************
18 * @file    M4xVSS_API.c
19 * @brief    API of eXtended Video Studio Service (Video Studio 2.1)
20 * @note
21 ******************************************************************************
22 */
23
24/**
25 * OSAL main types and errors ***/
26#include "M4OSA_Types.h"
27#include "M4OSA_Error.h"
28#include "M4OSA_Memory.h"
29#include "M4OSA_Debug.h"
30#include "M4OSA_FileReader.h"
31#include "M4OSA_FileWriter.h"
32#include "M4OSA_CoreID.h"
33#include "M4OSA_CharStar.h"
34// StageFright encoders require %16 resolution
35#include "M4ENCODER_common.h"
36#include "M4DECODER_Common.h"
37#include "VideoEditorVideoDecoder.h"
38
39/**
40 * VSS 3GPP API definition */
41#include "M4VSS3GPP_ErrorCodes.h"
42
43/*************************
44Begin of xVSS API
45 **************************/
46
47#include "M4xVSS_API.h"
48#include "M4xVSS_Internal.h"
49
50/* RC: to delete unecessary temp files on the fly */
51#include "M4VSS3GPP_InternalTypes.h"
52#include <utils/Log.h>
53
54/**
55 ******************************************************************************
56 * prototype    M4OSA_ERR M4xVSS_Init(M4OSA_Context* pContext, M4xVSS_InitParams* pParams)
57 * @brief        This function initializes the xVSS
58 * @note        Initializes the xVSS edit operation (allocates an execution context).
59 *
60 * @param    pContext            (OUT) Pointer on the xVSS edit context to allocate
61 * @param    params                (IN) Parameters mandatory for xVSS
62 * @return    M4NO_ERROR:            No error
63 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
64 * @return    M4ERR_ALLOC:        Memory allocation has failed
65 ******************************************************************************
66 */
67
68M4OSA_ERR M4xVSS_Init( M4OSA_Context *pContext, M4xVSS_InitParams *pParams )
69{
70    M4xVSS_Context *xVSS_context;
71    M4OSA_UInt32 length = 0, i;
72
73    if( pParams == M4OSA_NULL )
74    {
75        M4OSA_TRACE1_0("Parameter structure for M4xVSS_Init function is NULL");
76        return M4ERR_PARAMETER;
77    }
78
79    if( pParams->pFileReadPtr == M4OSA_NULL
80        || pParams->pFileWritePtr == M4OSA_NULL )
81    {
82        M4OSA_TRACE1_0(
83            "pFileReadPtr or pFileWritePtr in M4xVSS_InitParams structure is NULL");
84        return M4ERR_PARAMETER;
85    }
86
87    xVSS_context = (M4xVSS_Context *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_Context), M4VS,
88        (M4OSA_Char *)"Context of the xVSS layer");
89
90    if( xVSS_context == M4OSA_NULL )
91    {
92        M4OSA_TRACE1_0("Allocation error in M4xVSS_Init");
93        return M4ERR_ALLOC;
94    }
95
96    /* Initialize file read/write functions pointers */
97    xVSS_context->pFileReadPtr = pParams->pFileReadPtr;
98    xVSS_context->pFileWritePtr = pParams->pFileWritePtr;
99
100    /*UTF Conversion support: copy conversion functions pointers and allocate the temporary
101     buffer*/
102    if( pParams->pConvFromUTF8Fct != M4OSA_NULL )
103    {
104        if( pParams->pConvToUTF8Fct != M4OSA_NULL )
105        {
106            xVSS_context->UTFConversionContext.pConvFromUTF8Fct =
107                pParams->pConvFromUTF8Fct;
108            xVSS_context->UTFConversionContext.pConvToUTF8Fct =
109                pParams->pConvToUTF8Fct;
110            xVSS_context->UTFConversionContext.m_TempOutConversionSize =
111                UTF_CONVERSION_BUFFER_SIZE;
112            xVSS_context->UTFConversionContext.pTempOutConversionBuffer =
113                (M4OSA_Void *)M4OSA_32bitAlignedMalloc(UTF_CONVERSION_BUFFER_SIZE
114                * sizeof(M4OSA_UInt8),
115                M4VA, (M4OSA_Char *)"M4xVSS_Init: UTF conversion buffer");
116
117            if( M4OSA_NULL
118                == xVSS_context->UTFConversionContext.pTempOutConversionBuffer )
119            {
120                M4OSA_TRACE1_0("Allocation error in M4xVSS_Init");
121                free(xVSS_context->pTempPath);
122                xVSS_context->pTempPath = M4OSA_NULL;
123                free(xVSS_context);
124                xVSS_context = M4OSA_NULL;
125                return M4ERR_ALLOC;
126            }
127        }
128        else
129        {
130            M4OSA_TRACE1_0("M4xVSS_Init: one UTF conversion pointer is null and the other\
131                           is not null");
132            free(xVSS_context->pTempPath);
133            xVSS_context->pTempPath = M4OSA_NULL;
134            free(xVSS_context);
135            xVSS_context = M4OSA_NULL;
136            return M4ERR_PARAMETER;
137        }
138    }
139    else
140    {
141        xVSS_context->UTFConversionContext.pConvFromUTF8Fct = M4OSA_NULL;
142        xVSS_context->UTFConversionContext.pConvToUTF8Fct = M4OSA_NULL;
143        xVSS_context->UTFConversionContext.m_TempOutConversionSize = 0;
144        xVSS_context->UTFConversionContext.pTempOutConversionBuffer =
145            M4OSA_NULL;
146    }
147
148    if( pParams->pTempPath != M4OSA_NULL )
149    {
150        /*No need to convert into UTF8 as all input of xVSS are in UTF8
151        (the conversion customer format into UTF8
152        is done in VA/VAL)*/
153        xVSS_context->pTempPath =
154            (M4OSA_Void *)M4OSA_32bitAlignedMalloc(strlen(pParams->pTempPath) + 1,
155            M4VS, (M4OSA_Char *)"xVSS Path for temporary files");
156
157        if( xVSS_context->pTempPath == M4OSA_NULL )
158        {
159            M4OSA_TRACE1_0("Allocation error in M4xVSS_Init");
160            return M4ERR_ALLOC;
161        }
162        memcpy((void *)xVSS_context->pTempPath, (void *)pParams->pTempPath,
163            strlen(pParams->pTempPath) + 1);
164        /* TODO: Check that no previous xVSS temporary files are present ? */
165    }
166    else
167    {
168        M4OSA_TRACE1_0("Path for temporary files is NULL");
169        free(xVSS_context);
170        xVSS_context = M4OSA_NULL;
171        return M4ERR_PARAMETER;
172    }
173
174    xVSS_context->pSettings =
175        (M4VSS3GPP_EditSettings *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_EditSettings),
176        M4VS, (M4OSA_Char *)"Copy of VSS structure");
177
178    if( xVSS_context->pSettings == M4OSA_NULL )
179    {
180        M4OSA_TRACE1_0("Allocation error in M4xVSS_Init");
181        free(xVSS_context->pTempPath);
182        xVSS_context->pTempPath = M4OSA_NULL;
183        free(xVSS_context);
184        xVSS_context = M4OSA_NULL;
185        return M4ERR_ALLOC;
186    }
187
188    /* Initialize pointers in pSettings */
189    xVSS_context->pSettings->pClipList = M4OSA_NULL;
190    xVSS_context->pSettings->pTransitionList = M4OSA_NULL;
191    xVSS_context->pSettings->Effects = M4OSA_NULL; /* RC */
192    xVSS_context->pSettings->xVSS.pBGMtrack = M4OSA_NULL;
193
194    /* This is used to know if the user has added or removed some medias */
195    xVSS_context->previousClipNumber = 0;
196
197    /* "State machine" */
198    xVSS_context->editingStep = 0;
199    xVSS_context->analyseStep = 0;
200
201    xVSS_context->pcmPreviewFile = M4OSA_NULL;
202
203    /* Initialize Pto3GPP and MCS lists */
204    xVSS_context->pMCSparamsList = M4OSA_NULL;
205    xVSS_context->pPTo3GPPparamsList = M4OSA_NULL;
206    xVSS_context->pPTo3GPPcurrentParams = M4OSA_NULL;
207    xVSS_context->pMCScurrentParams = M4OSA_NULL;
208
209    xVSS_context->tempFileIndex = 0;
210
211    xVSS_context->targetedBitrate = 0;
212
213    xVSS_context->targetedTimescale = 0;
214
215    xVSS_context->pAudioMixContext = M4OSA_NULL;
216    xVSS_context->pAudioMixSettings = M4OSA_NULL;
217
218    /*FB: initialize to avoid crash when error during the editing*/
219    xVSS_context->pCurrentEditSettings = M4OSA_NULL;
220
221    /* Initialize state if all initializations are corrects */
222    xVSS_context->m_state = M4xVSS_kStateInitialized;
223
224    /* initialize MCS context*/
225    xVSS_context->pMCS_Ctxt = M4OSA_NULL;
226
227    *pContext = xVSS_context;
228
229    return M4NO_ERROR;
230}
231
232/**
233 ******************************************************************************
234 * prototype    M4xVSS_ReduceTranscode
235 * @brief        This function changes the given editing structure in order to
236 *                minimize the transcoding time.
237 * @note        The xVSS analyses this structure, and if needed, changes the
238 *                output parameters (Video codec, video size, audio codec,
239 *                audio nb of channels) to minimize the transcoding time.
240 *
241 * @param    pContext            (OUT) Pointer on the xVSS edit context to allocate
242 * @param    pSettings            (IN) Edition settings (allocated by the user)
243 * @return    M4NO_ERROR:            No error
244 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
245 * @return    M4ERR_ALLOC:        Memory allocation has failed
246 * @return    M4ERR_STATE:        This function cannot not be called at this time
247 ******************************************************************************
248 */
249M4OSA_ERR M4xVSS_ReduceTranscode( M4OSA_Context pContext,
250                                 M4VSS3GPP_EditSettings *pSettings )
251{
252    M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
253    M4OSA_ERR err = M4NO_ERROR;
254    M4VIDEOEDITING_ClipProperties fileProperties;
255    M4OSA_UInt8 i, j;
256    M4OSA_Bool bAudioTransition = M4OSA_FALSE;
257    M4OSA_Bool bIsBGMReplace = M4OSA_FALSE;
258    M4OSA_Bool bFound;
259    M4OSA_UInt32 videoConfig[9] =
260    {
261        0, 0, 0, 0, 0, 0, 0, 0, 0
262    };
263    /** Index <-> Video config **/
264    /* 0:        H263  SQCIF        */
265    /* 1:        H263  QCIF        */
266    /* 2:        H263  CIF        */
267    /* 3:        MPEG4 SQCIF        */
268    /* 4:        MPEG4 QQVGA        */
269    /* 5:        MPEG4 QCIF        */
270    /* 6:        MPEG4 QVGA        */
271    /* 7:        MPEG4 CIF        */
272    /* 8:        MPEG4 VGA        */
273    /****************************/
274    M4OSA_UInt32 audioConfig[3] =
275    {
276        0, 0, 0
277    };
278    /** Index <-> Audio config **/
279    /* 0:    AMR                    */
280    /* 1:    AAC    16kHz mono        */
281    /* 2:    AAC 16kHz stereo    */
282    /****************************/
283
284    /* Check state */
285    if( xVSS_context->m_state != M4xVSS_kStateInitialized \
286        && xVSS_context->m_state != M4xVSS_kStateOpened )
287    {
288        M4OSA_TRACE1_1(
289            "Bad state when calling M4xVSS_ReduceTranscode function! State is %d",
290            xVSS_context->m_state);
291        return M4ERR_STATE;
292    }
293
294    /* Check number of clips */
295    if( pSettings->uiClipNumber == 0 )
296    {
297        M4OSA_TRACE1_0("The number of input clip must be greater than 0 !");
298        return M4ERR_PARAMETER;
299    }
300
301    /* Check if there is a background music, and if its audio will replace input clip audio */
302    if( pSettings->xVSS.pBGMtrack != M4OSA_NULL )
303    {
304        if( pSettings->xVSS.pBGMtrack->uiAddVolume == 100 )
305        {
306            bIsBGMReplace = M4OSA_TRUE;
307        }
308    }
309
310    /* Parse all clips, and give occurences of each combination */
311    for ( i = 0; i < pSettings->uiClipNumber; i++ )
312    {
313        /* We ignore JPG input files as they are always transcoded */
314        if( pSettings->pClipList[i]->FileType == M4VIDEOEDITING_kFileType_3GPP )
315        {
316            /**
317            * UTF conversion: convert into the customer format*/
318            M4OSA_Void *pDecodedPath = pSettings->pClipList[i]->pFile;
319            M4OSA_UInt32 ConvertedSize = 0;
320
321            if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
322                != M4OSA_NULL && xVSS_context->
323                UTFConversionContext.pTempOutConversionBuffer
324                != M4OSA_NULL )
325            {
326                err = M4xVSS_internalConvertFromUTF8(xVSS_context,
327                    (M4OSA_Void *)pSettings->pClipList[i]->pFile,
328                    (M4OSA_Void *)xVSS_context->
329                    UTFConversionContext.pTempOutConversionBuffer,
330                    &ConvertedSize);
331
332                if( err != M4NO_ERROR )
333                {
334                    M4OSA_TRACE1_1("M4xVSS_ReduceTranscode:\
335                                   M4xVSS_internalConvertFromUTF8 returns err: 0x%x", err);
336                    return err;
337                }
338                pDecodedPath =
339                    xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
340            }
341            /**
342            * End of the utf conversion, now use the converted path*/
343            err = M4xVSS_internalGetProperties(xVSS_context, pDecodedPath,
344                &fileProperties);
345
346            //err = M4xVSS_internalGetProperties(xVSS_context, pSettings->pClipList[i]->pFile,
347            //     &fileProperties);
348            if( err != M4NO_ERROR )
349            {
350                M4OSA_TRACE1_1(
351                    "M4xVSS_sendCommand: M4xVSS_internalGetProperties returned 0x%x",
352                    err);
353                /* TODO: Translate error code of MCS to an xVSS error code ? */
354                return err;
355            }
356
357            /* Check best video settings */
358            if( fileProperties.uiVideoWidth == 128
359                && fileProperties.uiVideoHeight == 96 )
360            {
361                if( fileProperties.VideoStreamType == M4VIDEOEDITING_kH263 )
362                {
363                    videoConfig[0] += fileProperties.uiClipVideoDuration;
364                }
365                else if( ( fileProperties.VideoStreamType
366                    == M4VIDEOEDITING_kMPEG4) \
367                    || (fileProperties.VideoStreamType == M4VIDEOEDITING_kH264) )
368                {
369                    videoConfig[3] += fileProperties.uiClipVideoDuration;
370                }
371            }
372            else if( fileProperties.uiVideoWidth == 160
373                && fileProperties.uiVideoHeight == 120 )
374            {
375                if( ( fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4) \
376                    || (fileProperties.VideoStreamType == M4VIDEOEDITING_kH264) )
377                {
378                    videoConfig[4] += fileProperties.uiClipVideoDuration;
379                }
380            }
381            else if( fileProperties.uiVideoWidth == 176
382                && fileProperties.uiVideoHeight == 144 )
383            {
384                if( fileProperties.VideoStreamType == M4VIDEOEDITING_kH263 )
385                {
386                    videoConfig[1] += fileProperties.uiClipVideoDuration;
387                }
388                else if( ( fileProperties.VideoStreamType
389                    == M4VIDEOEDITING_kMPEG4) \
390                    || (fileProperties.VideoStreamType == M4VIDEOEDITING_kH264) )
391                {
392                    videoConfig[5] += fileProperties.uiClipVideoDuration;
393                }
394            }
395            else if( fileProperties.uiVideoWidth == 320
396                && fileProperties.uiVideoHeight == 240 )
397            {
398                if( ( fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4) \
399                    || (fileProperties.VideoStreamType == M4VIDEOEDITING_kH264) )
400                {
401                    videoConfig[6] += fileProperties.uiClipVideoDuration;
402                }
403            }
404            else if( fileProperties.uiVideoWidth == 352
405                && fileProperties.uiVideoHeight == 288 )
406            {
407                if( fileProperties.VideoStreamType == M4VIDEOEDITING_kH263 )
408                {
409                    videoConfig[2] += fileProperties.uiClipVideoDuration;
410                }
411                else if( ( fileProperties.VideoStreamType
412                    == M4VIDEOEDITING_kMPEG4) \
413                    || (fileProperties.VideoStreamType == M4VIDEOEDITING_kH264) )
414                {
415                    videoConfig[7] += fileProperties.uiClipVideoDuration;
416                }
417            }
418            else if( fileProperties.uiVideoWidth == 640
419                && fileProperties.uiVideoHeight == 480 )
420            {
421                if( ( fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4) \
422                    || (fileProperties.VideoStreamType == M4VIDEOEDITING_kH264) )
423                {
424                    videoConfig[8] += fileProperties.uiClipVideoDuration;
425                }
426            }
427
428            /* If there is a BGM that replaces existing audio track, we do not care about
429            audio track as it will be replaced */
430            /* If not, we try to minimize audio reencoding */
431            if( bIsBGMReplace == M4OSA_FALSE )
432            {
433                if( fileProperties.AudioStreamType == M4VIDEOEDITING_kAAC )
434                {
435                    if( fileProperties.uiSamplingFrequency == 16000 && \
436                        fileProperties.uiNbChannels == 1 )
437                    {
438                        audioConfig[1] += fileProperties.uiClipAudioDuration;
439                    }
440                    else if( fileProperties.uiSamplingFrequency == 16000 && \
441                        fileProperties.uiNbChannels == 2 )
442                    {
443                        audioConfig[2] += fileProperties.uiClipAudioDuration;
444                    }
445                }
446                else if( fileProperties.AudioStreamType
447                    == M4VIDEOEDITING_kAMR_NB )
448                {
449                    audioConfig[0] += fileProperties.uiClipAudioDuration;
450                }
451            }
452        }
453    }
454
455    /* Find best output video format (the most occuring combination) */
456    j = 0;
457    bFound = M4OSA_FALSE;
458
459    for ( i = 0; i < 9; i++ )
460    {
461        if( videoConfig[i] >= videoConfig[j] )
462        {
463            j = i;
464            bFound = M4OSA_TRUE;
465        }
466    }
467
468    if( bFound )
469    {
470        switch( j )
471        {
472            case 0:
473                pSettings->xVSS.outputVideoFormat = M4VIDEOEDITING_kH263;
474                pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kSQCIF;
475                break;
476
477            case 1:
478                pSettings->xVSS.outputVideoFormat = M4VIDEOEDITING_kH263;
479                pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kQCIF;
480                break;
481
482            case 2:
483                pSettings->xVSS.outputVideoFormat = M4VIDEOEDITING_kH263;
484                pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kCIF;
485                break;
486
487            case 3:
488                pSettings->xVSS.outputVideoFormat =
489                    (fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)
490                    ? M4VIDEOEDITING_kMPEG4 : M4VIDEOEDITING_kH264;
491                pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kSQCIF;
492                break;
493
494            case 4:
495                pSettings->xVSS.outputVideoFormat =
496                    (fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)
497                    ? M4VIDEOEDITING_kMPEG4 : M4VIDEOEDITING_kH264;
498                pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kQQVGA;
499                break;
500
501            case 5:
502                pSettings->xVSS.outputVideoFormat =
503                    (fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)
504                    ? M4VIDEOEDITING_kMPEG4 : M4VIDEOEDITING_kH264;
505                pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kQCIF;
506                break;
507
508            case 6:
509                pSettings->xVSS.outputVideoFormat =
510                    (fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)
511                    ? M4VIDEOEDITING_kMPEG4 : M4VIDEOEDITING_kH264;
512                pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kQVGA;
513                break;
514
515            case 7:
516                pSettings->xVSS.outputVideoFormat =
517                    (fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)
518                    ? M4VIDEOEDITING_kMPEG4 : M4VIDEOEDITING_kH264;
519                pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kCIF;
520                break;
521
522            case 8:
523                pSettings->xVSS.outputVideoFormat =
524                    (fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)
525                    ? M4VIDEOEDITING_kMPEG4 : M4VIDEOEDITING_kH264;
526                pSettings->xVSS.outputVideoSize = M4VIDEOEDITING_kVGA;
527                break;
528        }
529    }
530
531    /* Find best output audio format (the most occuring combination) */
532    j = 0;
533    bFound = M4OSA_FALSE;
534
535    for ( i = 0; i < 3; i++ )
536    {
537        if( audioConfig[i] >= audioConfig[j] )
538        {
539            j = i;
540            bFound = M4OSA_TRUE;
541        }
542    }
543
544    if( bFound )
545    {
546        switch( j )
547        {
548            case 0:
549                pSettings->xVSS.outputAudioFormat = M4VIDEOEDITING_kAMR_NB;
550                pSettings->xVSS.bAudioMono = M4OSA_TRUE;
551                break;
552
553            case 1:
554                pSettings->xVSS.outputAudioFormat = M4VIDEOEDITING_kAAC;
555                pSettings->xVSS.bAudioMono = M4OSA_TRUE;
556                break;
557
558            case 2:
559                pSettings->xVSS.outputAudioFormat = M4VIDEOEDITING_kAAC;
560                pSettings->xVSS.bAudioMono = M4OSA_FALSE;
561                break;
562        }
563    }
564
565    return M4NO_ERROR;
566}
567
568/**
569 ******************************************************************************
570 * prototype    M4OSA_ERR M4xVSS_SendCommand(M4OSA_Context pContext,
571 *                                         M4VSS3GPP_EditSettings* pSettings)
572 * @brief        This function gives to the xVSS an editing structure
573 * @note        The xVSS analyses this structure, and prepare edition
574 *                This function must be called after M4xVSS_Init, after
575 *                M4xVSS_CloseCommand, or after M4xVSS_PreviewStop.
576 *                After this function, the user must call M4xVSS_Step until
577 *                it returns another error than M4NO_ERROR.
578 *
579 * @param    pContext            (IN) Pointer on the xVSS edit context
580 * @param    pSettings            (IN) Edition settings (allocated by the user)
581 * @return    M4NO_ERROR:            No error
582 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
583 * @return    M4ERR_ALLOC:        Memory allocation has failed
584 * @return    M4ERR_STATE:        This function cannot not be called at this time
585 ******************************************************************************
586 */
587M4OSA_ERR M4xVSS_SendCommand( M4OSA_Context pContext,
588                             M4VSS3GPP_EditSettings *pSettings )
589{
590    M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
591    M4OSA_UInt8 i, j;
592    M4OSA_UInt8 nbOfSameClip = 0;
593    M4OSA_ERR err;
594    M4OSA_Bool isNewBGM = M4OSA_TRUE;
595    M4xVSS_Pto3GPP_params *pPto3GPP_last = M4OSA_NULL;
596    M4xVSS_MCS_params *pMCS_last = M4OSA_NULL;
597    M4OSA_UInt32 width, height, samplingFreq;
598    M4OSA_Bool bIsTranscoding = M4OSA_FALSE;
599    M4OSA_Int32 totalDuration;
600    M4OSA_UInt32 outputSamplingFrequency = 0;
601    M4OSA_UInt32 length = 0;
602    M4OSA_Int8 masterClip = -1;
603
604    i = 0;
605    /* Check state */
606    if( xVSS_context->m_state != M4xVSS_kStateInitialized \
607        && xVSS_context->m_state != M4xVSS_kStateOpened )
608    {
609        M4OSA_TRACE1_1(
610            "Bad state when calling M4xVSS_SendCommand function! State is %d",
611            xVSS_context->m_state);
612        return M4ERR_STATE;
613    }
614
615    /* State is back to initialized to allow call of cleanup function in case of error */
616    xVSS_context->m_state = M4xVSS_kStateInitialized;
617
618    /* Check if a previous sendCommand has been called */
619    if( xVSS_context->previousClipNumber != 0 )
620    {
621        M4OSA_UInt32 pCmpResult = 0;
622
623        /* Compare BGM input */
624        if( xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL \
625            && pSettings->xVSS.pBGMtrack != M4OSA_NULL )
626        {
627            pCmpResult = strcmp((const char *)xVSS_context->pSettings->xVSS.pBGMtrack->pFile,
628                (const char *)pSettings->xVSS.pBGMtrack->pFile);
629
630            if( pCmpResult == 0 )
631            {
632                /* Check if audio output parameters have changed */
633                if( xVSS_context->pSettings->xVSS.outputAudioFormat ==
634                    pSettings->xVSS.outputAudioFormat
635                    && xVSS_context->pSettings->xVSS.bAudioMono
636                    == pSettings->xVSS.bAudioMono )
637                {
638                    /* It means that BGM is the same as before, so, no need to redecode it */
639                    M4OSA_TRACE2_0(
640                        "BGM is the same as before, nothing to decode");
641                    isNewBGM = M4OSA_FALSE;
642                }
643                else
644                {
645                    /* We need to unallocate PCM preview file path in internal context */
646                    if( xVSS_context->pcmPreviewFile != M4OSA_NULL )
647                    {
648                        free(xVSS_context->pcmPreviewFile);
649                        xVSS_context->pcmPreviewFile = M4OSA_NULL;
650                    }
651                }
652            }
653            else
654            {
655                /* We need to unallocate PCM preview file path in internal context */
656                if( xVSS_context->pcmPreviewFile != M4OSA_NULL )
657                {
658                    free(xVSS_context->pcmPreviewFile);
659                    xVSS_context->pcmPreviewFile = M4OSA_NULL;
660                }
661            }
662        }
663
664        /* Check if output settings have changed */
665        if( xVSS_context->pSettings->xVSS.outputVideoSize
666            != pSettings->xVSS.outputVideoSize
667            || xVSS_context->pSettings->xVSS.outputVideoFormat
668            != pSettings->xVSS.outputVideoFormat
669            || xVSS_context->pSettings->xVSS.outputVideoProfile
670            != pSettings->xVSS.outputVideoProfile
671            || xVSS_context->pSettings->xVSS.outputVideoLevel
672            != pSettings->xVSS.outputVideoLevel
673            || xVSS_context->pSettings->xVSS.outputAudioFormat
674            != pSettings->xVSS.outputAudioFormat
675            || xVSS_context->pSettings->xVSS.bAudioMono
676            != pSettings->xVSS.bAudioMono
677            || xVSS_context->pSettings->xVSS.outputAudioSamplFreq
678            != pSettings->xVSS.outputAudioSamplFreq )
679        {
680            /* If it is the case, we can't reuse already transcoded/converted files */
681            /* so, we delete these files and remove them from chained list */
682            if( xVSS_context->pPTo3GPPparamsList != M4OSA_NULL )
683            {
684                M4xVSS_Pto3GPP_params *pParams =
685                    xVSS_context->pPTo3GPPparamsList;
686                M4xVSS_Pto3GPP_params *pParams_sauv;
687
688                while( pParams != M4OSA_NULL )
689                {
690                    if( pParams->pFileIn != M4OSA_NULL )
691                    {
692                        free(pParams->pFileIn);
693                        pParams->pFileIn = M4OSA_NULL;
694                    }
695
696                    if( pParams->pFileOut != M4OSA_NULL )
697                    {
698                        /* Delete temporary file */
699                        remove((const char *)pParams->pFileOut);
700                        free(pParams->pFileOut);
701                        pParams->pFileOut = M4OSA_NULL;
702                    }
703
704                    if( pParams->pFileTemp != M4OSA_NULL )
705                    {
706                        /* Delete temporary file */
707#ifdef M4xVSS_RESERVED_MOOV_DISK_SPACE
708
709                        remove((const char *)pParams->pFileTemp);
710                        free(pParams->pFileTemp);
711
712#endif /*M4xVSS_RESERVED_MOOV_DISK_SPACE*/
713
714                        pParams->pFileTemp = M4OSA_NULL;
715                    }
716                    pParams_sauv = pParams;
717                    pParams = pParams->pNext;
718                    free(pParams_sauv);
719                    pParams_sauv = M4OSA_NULL;
720                }
721                xVSS_context->pPTo3GPPparamsList = M4OSA_NULL;
722            }
723
724            if( xVSS_context->pMCSparamsList != M4OSA_NULL )
725            {
726                M4xVSS_MCS_params *pParams = xVSS_context->pMCSparamsList;
727                M4xVSS_MCS_params *pParams_sauv;
728                M4xVSS_MCS_params *pParams_bgm = M4OSA_NULL;
729
730                while( pParams != M4OSA_NULL )
731                {
732                    /* Here, we do not delete BGM */
733                    if( pParams->isBGM != M4OSA_TRUE )
734                    {
735                        if( pParams->pFileIn != M4OSA_NULL )
736                        {
737                            free(pParams->pFileIn);
738                            pParams->pFileIn = M4OSA_NULL;
739                        }
740
741                        if( pParams->pFileOut != M4OSA_NULL )
742                        {
743                            /* Delete temporary file */
744                            remove((const char *)pParams->pFileOut);
745                            free(pParams->pFileOut);
746                            pParams->pFileOut = M4OSA_NULL;
747                        }
748
749                        if( pParams->pFileTemp != M4OSA_NULL )
750                        {
751                            /* Delete temporary file */
752#ifdef M4xVSS_RESERVED_MOOV_DISK_SPACE
753
754                            remove((const char *)pParams->pFileTemp);
755                            free(pParams->pFileTemp);
756
757#endif /*M4xVSS_RESERVED_MOOV_DISK_SPACE*/
758
759                            pParams->pFileTemp = M4OSA_NULL;
760                        }
761                        pParams_sauv = pParams;
762                        pParams = pParams->pNext;
763                        free(pParams_sauv);
764                        pParams_sauv = M4OSA_NULL;
765                    }
766                    else
767                    {
768                        pParams_bgm = pParams;
769                        pParams = pParams->pNext;
770                        /*PR P4ME00003182 initialize this pointer because the following params
771                        element will be deallocated*/
772                        if( pParams != M4OSA_NULL
773                            && pParams->isBGM != M4OSA_TRUE )
774                        {
775                            pParams_bgm->pNext = M4OSA_NULL;
776                        }
777                    }
778                }
779                xVSS_context->pMCSparamsList = pParams_bgm;
780            }
781            /* Maybe need to implement framerate changing */
782            //xVSS_context->pSettings->videoFrameRate;
783        }
784
785        /* Unallocate previous xVSS_context->pSettings structure */
786        M4xVSS_freeSettings(xVSS_context->pSettings);
787
788        /*Unallocate output file path*/
789        if( xVSS_context->pSettings->pOutputFile != M4OSA_NULL )
790        {
791            free(xVSS_context->pSettings->pOutputFile);
792            xVSS_context->pSettings->pOutputFile = M4OSA_NULL;
793        }
794        xVSS_context->pSettings->uiOutputPathSize = 0;
795        xVSS_context->pOutputFile = M4OSA_NULL;
796    }
797
798    /**********************************
799    Clips registering
800    **********************************/
801
802    /* Copy settings from user given structure to our "local" structure */
803    xVSS_context->pSettings->xVSS.outputVideoFormat =
804        pSettings->xVSS.outputVideoFormat;
805    xVSS_context->pSettings->xVSS.outputVideoProfile =
806        pSettings->xVSS.outputVideoProfile;
807    xVSS_context->pSettings->xVSS.outputVideoLevel =
808        pSettings->xVSS.outputVideoLevel;
809    xVSS_context->pSettings->xVSS.outputVideoSize =
810        pSettings->xVSS.outputVideoSize;
811    xVSS_context->pSettings->xVSS.outputAudioFormat =
812        pSettings->xVSS.outputAudioFormat;
813    xVSS_context->pSettings->xVSS.bAudioMono = pSettings->xVSS.bAudioMono;
814    xVSS_context->pSettings->xVSS.outputAudioSamplFreq =
815        pSettings->xVSS.outputAudioSamplFreq;
816    /*xVSS_context->pSettings->pOutputFile = pSettings->pOutputFile;*/
817    /*FB: VAL CR P4ME00003076
818    The output video and audio bitrate are given by the user in the edition settings structure*/
819    xVSS_context->pSettings->xVSS.outputVideoBitrate =
820        pSettings->xVSS.outputVideoBitrate;
821    xVSS_context->pSettings->xVSS.outputAudioBitrate =
822        pSettings->xVSS.outputAudioBitrate;
823    xVSS_context->pSettings->PTVolLevel = pSettings->PTVolLevel;
824
825    /*FB: bug fix if the output path is given in M4xVSS_sendCommand*/
826
827    if( pSettings->pOutputFile != M4OSA_NULL
828        && pSettings->uiOutputPathSize > 0 )
829    {
830        M4OSA_Void *pDecodedPath = pSettings->pOutputFile;
831        /*As all inputs of the xVSS are in UTF8, convert the output file path into the
832        customer format*/
833        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
834            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
835            != M4OSA_NULL )
836        {
837            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
838                (M4OSA_Void *)pSettings->pOutputFile,
839                (M4OSA_Void *)xVSS_context->
840                UTFConversionContext.pTempOutConversionBuffer, &length);
841
842            if( err != M4NO_ERROR )
843            {
844                M4OSA_TRACE1_1("M4xVSS_SendCommand:\
845                               M4xVSS_internalConvertFromUTF8 returns err: 0x%x", err);
846                return err;
847            }
848            pDecodedPath =
849                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
850            pSettings->uiOutputPathSize = length;
851        }
852
853        xVSS_context->pSettings->pOutputFile = (M4OSA_Void *)M4OSA_32bitAlignedMalloc \
854            (pSettings->uiOutputPathSize + 1, M4VS,
855            (M4OSA_Char *)"output file path");
856
857        if( xVSS_context->pSettings->pOutputFile == M4OSA_NULL )
858        {
859            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
860            /*FB: to avoid leaks when there is an error in the send command*/
861            /* Free Send command */
862            M4xVSS_freeCommand(xVSS_context);
863            /**/
864            return M4ERR_ALLOC;
865        }
866        memcpy((void *)xVSS_context->pSettings->pOutputFile,
867            (void *)pDecodedPath, pSettings->uiOutputPathSize + 1);
868        xVSS_context->pSettings->uiOutputPathSize = pSettings->uiOutputPathSize;
869        xVSS_context->pOutputFile = xVSS_context->pSettings->pOutputFile;
870    }
871    else
872    {
873        xVSS_context->pSettings->pOutputFile = M4OSA_NULL;
874        xVSS_context->pSettings->uiOutputPathSize = 0;
875        xVSS_context->pOutputFile = M4OSA_NULL;
876    }
877    xVSS_context->pSettings->pTemporaryFile = pSettings->pTemporaryFile;
878    xVSS_context->pSettings->uiClipNumber = pSettings->uiClipNumber;
879    xVSS_context->pSettings->videoFrameRate = pSettings->videoFrameRate;
880    xVSS_context->pSettings->uiMasterClip =
881        0; /* With VSS 2.0, this new param is mandatory */
882    xVSS_context->pSettings->xVSS.pTextRenderingFct =
883        pSettings->xVSS.pTextRenderingFct; /* CR text handling */
884    xVSS_context->pSettings->xVSS.outputFileSize =
885        pSettings->xVSS.outputFileSize;
886
887    if( pSettings->xVSS.outputFileSize != 0 \
888        && pSettings->xVSS.outputAudioFormat != M4VIDEOEDITING_kAMR_NB )
889    {
890        M4OSA_TRACE1_0("M4xVSS_SendCommand: Impossible to limit file\
891                       size with other audio output than AAC");
892        return M4ERR_PARAMETER;
893    }
894    xVSS_context->nbStepTotal = 0;
895    xVSS_context->currentStep = 0;
896
897    if( xVSS_context->pSettings->xVSS.outputVideoFormat != M4VIDEOEDITING_kMPEG4
898        && xVSS_context->pSettings->xVSS.outputVideoFormat
899        != M4VIDEOEDITING_kH263
900        && xVSS_context->pSettings->xVSS.outputVideoFormat
901        != M4VIDEOEDITING_kH264 )
902    {
903        xVSS_context->pSettings->xVSS.outputVideoFormat =
904            M4VIDEOEDITING_kNoneVideo;
905    }
906
907    /* Get output width/height */
908    switch( xVSS_context->pSettings->xVSS.outputVideoSize )
909    {
910        case M4VIDEOEDITING_kSQCIF:
911            width = 128;
912            height = 96;
913            break;
914
915        case M4VIDEOEDITING_kQQVGA:
916            width = 160;
917            height = 120;
918            break;
919
920        case M4VIDEOEDITING_kQCIF:
921            width = 176;
922            height = 144;
923            break;
924
925        case M4VIDEOEDITING_kQVGA:
926            width = 320;
927            height = 240;
928            break;
929
930        case M4VIDEOEDITING_kCIF:
931            width = 352;
932            height = 288;
933            break;
934
935        case M4VIDEOEDITING_kVGA:
936            width = 640;
937            height = 480;
938            break;
939            /* +PR LV5807 */
940        case M4VIDEOEDITING_kWVGA:
941            width = 800;
942            height = 480;
943            break;
944
945        case M4VIDEOEDITING_kNTSC:
946            width = 720;
947            height = 480;
948            break;
949            /* -PR LV5807 */
950            /* +CR Google */
951        case M4VIDEOEDITING_k640_360:
952            width = 640;
953            height = 360;
954            break;
955
956        case M4VIDEOEDITING_k854_480:
957
958            // StageFright encoders require %16 resolution
959
960            width = M4ENCODER_854_480_Width;
961
962            height = 480;
963            break;
964
965        case M4VIDEOEDITING_k1280_720:
966            width = 1280;
967            height = 720;
968            break;
969
970        case M4VIDEOEDITING_k1080_720:
971            // StageFright encoders require %16 resolution
972            width = M4ENCODER_1080_720_Width;
973            height = 720;
974            break;
975
976        case M4VIDEOEDITING_k960_720:
977            width = 960;
978            height = 720;
979            break;
980
981        case M4VIDEOEDITING_k1920_1080:
982            width = 1920;
983            height = M4ENCODER_1920_1080_Height;
984            break;
985
986            /* -CR Google */
987        default: /* If output video size is not given, we take QCIF size */
988            width = 176;
989            height = 144;
990            xVSS_context->pSettings->xVSS.outputVideoSize =
991                M4VIDEOEDITING_kQCIF;
992            break;
993    }
994
995    /* Get output Sampling frequency */
996    switch( xVSS_context->pSettings->xVSS.outputAudioSamplFreq )
997    {
998        case M4VIDEOEDITING_k8000_ASF:
999            samplingFreq = 8000;
1000            break;
1001
1002        case M4VIDEOEDITING_k16000_ASF:
1003            samplingFreq = 16000;
1004            break;
1005
1006        case M4VIDEOEDITING_k22050_ASF:
1007            samplingFreq = 22050;
1008            break;
1009
1010        case M4VIDEOEDITING_k24000_ASF:
1011            samplingFreq = 24000;
1012            break;
1013
1014        case M4VIDEOEDITING_k32000_ASF:
1015            samplingFreq = 32000;
1016            break;
1017
1018        case M4VIDEOEDITING_k44100_ASF:
1019            samplingFreq = 44100;
1020            break;
1021
1022        case M4VIDEOEDITING_k48000_ASF:
1023            samplingFreq = 48000;
1024            break;
1025
1026        case M4VIDEOEDITING_kDefault_ASF:
1027        default:
1028            if( xVSS_context->pSettings->xVSS.outputAudioFormat
1029                == M4VIDEOEDITING_kAMR_NB )
1030            {
1031                samplingFreq = 8000;
1032            }
1033            else if( xVSS_context->pSettings->xVSS.outputAudioFormat
1034                == M4VIDEOEDITING_kAAC )
1035            {
1036                samplingFreq = 16000;
1037            }
1038            else
1039            {
1040                samplingFreq = 0;
1041            }
1042            break;
1043    }
1044
1045    /* Allocate clip/transitions if clip number is not null ... */
1046    if( 0 < xVSS_context->pSettings->uiClipNumber )
1047    {
1048        if( xVSS_context->pSettings->pClipList != M4OSA_NULL )
1049        {
1050            free((xVSS_context->pSettings->pClipList));
1051            xVSS_context->pSettings->pClipList = M4OSA_NULL;
1052        }
1053
1054        if( xVSS_context->pSettings->pTransitionList != M4OSA_NULL )
1055        {
1056            free(xVSS_context->pSettings->pTransitionList);
1057            xVSS_context->pSettings->pTransitionList = M4OSA_NULL;
1058        }
1059
1060        xVSS_context->pSettings->pClipList =
1061            (M4VSS3GPP_ClipSettings ** )M4OSA_32bitAlignedMalloc \
1062            (sizeof(M4VSS3GPP_ClipSettings *)*xVSS_context->pSettings->uiClipNumber,
1063            M4VS, (M4OSA_Char *)"xVSS, copy of pClipList");
1064
1065        if( xVSS_context->pSettings->pClipList == M4OSA_NULL )
1066        {
1067            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
1068            /*FB: to avoid leaks when there is an error in the send command*/
1069            /* Free Send command */
1070            M4xVSS_freeCommand(xVSS_context);
1071            /**/
1072            return M4ERR_ALLOC;
1073        }
1074        /* Set clip list to NULL */
1075        memset((void *)xVSS_context->pSettings->pClipList,0,
1076            sizeof(M4VSS3GPP_ClipSettings *)
1077            *xVSS_context->pSettings->uiClipNumber);
1078
1079        if( xVSS_context->pSettings->uiClipNumber > 1 )
1080        {
1081            xVSS_context->pSettings->pTransitionList =
1082                (M4VSS3GPP_TransitionSettings ** ) \
1083                M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_TransitionSettings *)                \
1084                *(xVSS_context->pSettings->uiClipNumber - 1), M4VS, (M4OSA_Char *) \
1085                "xVSS, copy of pTransitionList");
1086
1087            if( xVSS_context->pSettings->pTransitionList == M4OSA_NULL )
1088            {
1089                M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
1090                /*FB: to avoid leaks when there is an error in the send command*/
1091                /* Free Send command */
1092                M4xVSS_freeCommand(xVSS_context);
1093                /**/
1094                return M4ERR_ALLOC;
1095            }
1096            /* Set transition list to NULL */
1097            memset(
1098                (void *)xVSS_context->pSettings->pTransitionList,0,
1099                sizeof(M4VSS3GPP_TransitionSettings *)
1100                *(xVSS_context->pSettings->uiClipNumber - 1));
1101        }
1102        else
1103        {
1104            xVSS_context->pSettings->pTransitionList = M4OSA_NULL;
1105        }
1106    }
1107    /* else, there is a pb in the input settings structure */
1108    else
1109    {
1110        M4OSA_TRACE1_0("No clip in this settings list !!");
1111        /*FB: to avoid leaks when there is an error in the send command*/
1112        /* Free Send command */
1113        M4xVSS_freeCommand(xVSS_context);
1114        /**/
1115        return M4ERR_PARAMETER;
1116    }
1117
1118    /* RC Allocate effects settings */
1119    xVSS_context->pSettings->nbEffects = pSettings->nbEffects;
1120
1121    if( 0 < xVSS_context->pSettings->nbEffects )
1122    {
1123        xVSS_context->pSettings->Effects =
1124            (M4VSS3GPP_EffectSettings *)M4OSA_32bitAlignedMalloc \
1125            (xVSS_context->pSettings->nbEffects * sizeof(M4VSS3GPP_EffectSettings),
1126            M4VS, (M4OSA_Char *)"effects settings");
1127
1128        if( xVSS_context->pSettings->Effects == M4OSA_NULL )
1129        {
1130            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
1131            /*FB: to avoid leaks when there is an error in the send command*/
1132            /* Free Send command */
1133            M4xVSS_freeCommand(xVSS_context);
1134            /**/
1135            return M4ERR_ALLOC;
1136        }
1137        /*FB bug fix 19.03.2008: these pointers were not initialized -> crash when free*/
1138        for ( i = 0; i < xVSS_context->pSettings->nbEffects; i++ )
1139        {
1140            xVSS_context->pSettings->Effects[i].xVSS.pFramingFilePath =
1141                M4OSA_NULL;
1142            xVSS_context->pSettings->Effects[i].xVSS.pFramingBuffer =
1143                M4OSA_NULL;
1144            xVSS_context->pSettings->Effects[i].xVSS.pTextBuffer = M4OSA_NULL;
1145        }
1146        /**/
1147    }
1148
1149    if( xVSS_context->targetedTimescale == 0 )
1150    {
1151        M4OSA_UInt32 pTargetedTimeScale = 0;
1152
1153        err = M4xVSS_internalGetTargetedTimeScale(xVSS_context, pSettings,
1154            &pTargetedTimeScale);
1155
1156        if( M4NO_ERROR != err || pTargetedTimeScale == 0 )
1157        {
1158            M4OSA_TRACE1_1("M4xVSS_SendCommand: M4xVSS_internalGetTargetedTimeScale\
1159                           returned 0x%x", err);
1160            /*FB: to avoid leaks when there is an error in the send command*/
1161            /* Free Send command */
1162            M4xVSS_freeCommand(xVSS_context);
1163            /**/
1164            return err;
1165        }
1166        xVSS_context->targetedTimescale = pTargetedTimeScale;
1167    }
1168
1169    /* Initialize total duration variable */
1170    totalDuration = 0;
1171
1172    /* Parsing list of clips given by application, and prepare analyzing */
1173    for ( i = 0; i < xVSS_context->pSettings->uiClipNumber; i++ )
1174    {
1175        /* Allocate current clip */
1176        xVSS_context->pSettings->pClipList[i] =
1177            (M4VSS3GPP_ClipSettings *)M4OSA_32bitAlignedMalloc \
1178            (sizeof(M4VSS3GPP_ClipSettings), M4VS, (M4OSA_Char *)"clip settings");
1179
1180        if( xVSS_context->pSettings->pClipList[i] == M4OSA_NULL )
1181        {
1182            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
1183            /*FB: to avoid leaks when there is an error in the send command*/
1184            /* Free Send command */
1185            M4xVSS_freeCommand(xVSS_context);
1186            /**/
1187            return M4ERR_ALLOC;
1188        }
1189
1190        /* Copy clip settings from given structure to our xVSS_context structure */
1191        err =
1192            M4xVSS_DuplicateClipSettings(xVSS_context->pSettings->pClipList[i],
1193            pSettings->pClipList[i], M4OSA_TRUE);
1194
1195        if( err != M4NO_ERROR )
1196        {
1197            M4OSA_TRACE1_1(
1198                "M4xVSS_SendCommand: M4xVSS_DuplicateClipSettings return error 0x%x",
1199                err);
1200            /*FB: to avoid leaks when there is an error in the send command*/
1201            /* Free Send command */
1202            M4xVSS_freeCommand(xVSS_context);
1203            /**/
1204            return err;
1205        }
1206
1207        xVSS_context->pSettings->pClipList[i]->bTranscodingRequired =
1208            M4OSA_FALSE;
1209
1210        /* Because there is 1 less transition than clip number */
1211        if( i < xVSS_context->pSettings->uiClipNumber - 1 )
1212        {
1213            xVSS_context->pSettings->pTransitionList[i] =
1214                (M4VSS3GPP_TransitionSettings
1215                *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_TransitionSettings),
1216                M4VS, (M4OSA_Char *)"transition settings");
1217
1218            if( xVSS_context->pSettings->pTransitionList[i] == M4OSA_NULL )
1219            {
1220                M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
1221                /*FB: to avoid leaks when there is an error in the send command*/
1222                /* Free Send command */
1223                M4xVSS_freeCommand(xVSS_context);
1224                /**/
1225                return M4ERR_ALLOC;
1226            }
1227
1228            memcpy(
1229                (void *)xVSS_context->pSettings->pTransitionList[i],
1230                (void *)pSettings->pTransitionList[i],
1231                sizeof(M4VSS3GPP_TransitionSettings));
1232            /* Initialize external effect context to NULL, to know if input jpg has already been
1233            decoded or not */
1234            xVSS_context->pSettings->pTransitionList[i]->
1235                pExtVideoTransitionFctCtxt = M4OSA_NULL;
1236
1237            switch( xVSS_context->pSettings->
1238                pTransitionList[i]->VideoTransitionType )
1239            {
1240                    /* If transition type is alpha magic, we need to decode input file */
1241                case M4xVSS_kVideoTransitionType_AlphaMagic:
1242                    /* Allocate our alpha magic settings structure to have a copy of the
1243                    provided one */
1244                    xVSS_context->pSettings->pTransitionList[i]->      \
1245                     xVSS.transitionSpecific.pAlphaMagicSettings =
1246                        (M4xVSS_AlphaMagicSettings *)M4OSA_32bitAlignedMalloc \
1247                        (sizeof(M4xVSS_AlphaMagicSettings), M4VS,
1248                        (M4OSA_Char *)"Input Alpha magic settings structure");
1249
1250                    if( xVSS_context->pSettings->pTransitionList[i]-> \
1251                        xVSS.transitionSpecific.pAlphaMagicSettings == M4OSA_NULL )
1252                    {
1253                        M4OSA_TRACE1_0(
1254                            "Allocation error in M4xVSS_SendCommand");
1255                        /*FB: to avoid leaks when there is an error in the send command*/
1256                        /* Free Send command */
1257                        M4xVSS_freeCommand(xVSS_context);
1258                        /**/
1259                        return M4ERR_ALLOC;
1260                    }
1261                    /* Copy data from the provided alpha magic settings structure tou our
1262                    structure */
1263                    memcpy((void *)xVSS_context->pSettings->
1264                        pTransitionList[i]-> \
1265                        xVSS.transitionSpecific.pAlphaMagicSettings,
1266                        (void *)pSettings->pTransitionList[i]-> \
1267                        xVSS.transitionSpecific.pAlphaMagicSettings,
1268                        sizeof(M4xVSS_AlphaMagicSettings));
1269
1270                    /* Allocate our alpha magic input filename */
1271                    xVSS_context->pSettings->pTransitionList[i]-> \
1272                        xVSS.transitionSpecific.pAlphaMagicSettings->
1273                        pAlphaFilePath = M4OSA_32bitAlignedMalloc(
1274                        (strlen(pSettings->pTransitionList[i]-> \
1275                        xVSS.transitionSpecific.pAlphaMagicSettings->pAlphaFilePath)
1276                        + 1), M4VS, (M4OSA_Char *)"Alpha magic file path");
1277
1278                    if( xVSS_context->pSettings->pTransitionList[i]-> \
1279                        xVSS.transitionSpecific.pAlphaMagicSettings->pAlphaFilePath
1280                        == M4OSA_NULL )
1281                    {
1282                        M4OSA_TRACE1_0(
1283                            "Allocation error in M4xVSS_SendCommand");
1284                        /*FB: to avoid leaks when there is an error in the send command*/
1285                        /* Free Send command */
1286                        M4xVSS_freeCommand(xVSS_context);
1287                        /**/
1288                        return M4ERR_ALLOC;
1289                    }
1290                    /* Copy data from the provided alpha magic filename to our */
1291                    M4OSA_chrNCopy(
1292                        xVSS_context->pSettings->pTransitionList[i]->xVSS.
1293                        transitionSpecific.pAlphaMagicSettings->
1294                        pAlphaFilePath,
1295                        pSettings->pTransitionList[i]->xVSS.
1296                        transitionSpecific.pAlphaMagicSettings->
1297                        pAlphaFilePath, strlen(
1298                        pSettings->pTransitionList[i]->xVSS.
1299                        transitionSpecific.pAlphaMagicSettings->
1300                        pAlphaFilePath) + 1);
1301
1302                    /* Parse all transition to know if the input jpg has already been decoded */
1303                    for ( j = 0; j < i; j++ )
1304                    {
1305                        if( xVSS_context->pSettings->
1306                            pTransitionList[j]->VideoTransitionType
1307                            == M4xVSS_kVideoTransitionType_AlphaMagic )
1308                        {
1309                            M4OSA_UInt32 pCmpResult = 0;
1310                            pCmpResult = strcmp((const char *)xVSS_context->pSettings->
1311                                pTransitionList[i]->xVSS.
1312                                transitionSpecific.pAlphaMagicSettings->
1313                                pAlphaFilePath, (const char *)xVSS_context->pSettings->
1314                                pTransitionList[j]->xVSS.
1315                                transitionSpecific.
1316                                pAlphaMagicSettings->pAlphaFilePath);
1317
1318                            if( pCmpResult == 0 )
1319                            {
1320                                M4xVSS_internal_AlphaMagicSettings
1321                                    *alphaSettings;
1322
1323                                alphaSettings =
1324                                    (M4xVSS_internal_AlphaMagicSettings
1325                                    *)M4OSA_32bitAlignedMalloc(
1326                                    sizeof(
1327                                    M4xVSS_internal_AlphaMagicSettings),
1328                                    M4VS,
1329                                    (M4OSA_Char
1330                                    *)
1331                                    "Alpha magic settings structure 1");
1332
1333                                if( alphaSettings == M4OSA_NULL )
1334                                {
1335                                    M4OSA_TRACE1_0(
1336                                        "Allocation error in M4xVSS_SendCommand");
1337                                    /*FB: to avoid leaks when there is an error in the send
1338                                     command*/
1339                                    /* Free Send command */
1340                                    M4xVSS_freeCommand(xVSS_context);
1341                                    /**/
1342                                    return M4ERR_ALLOC;
1343                                }
1344                                alphaSettings->pPlane =
1345                                    ((M4xVSS_internal_AlphaMagicSettings *)(
1346                                    xVSS_context->pSettings->
1347                                    pTransitionList[j]->
1348                                    pExtVideoTransitionFctCtxt))->
1349                                    pPlane;
1350
1351                                if( xVSS_context->pSettings->
1352                                    pTransitionList[i]->xVSS.transitionSpecific.
1353                                    pAlphaMagicSettings->blendingPercent > 0
1354                                    && xVSS_context->pSettings->
1355                                    pTransitionList[i]->xVSS.
1356                                    transitionSpecific.
1357                                    pAlphaMagicSettings->blendingPercent
1358                                    <= 100 )
1359                                {
1360                                    alphaSettings->blendingthreshold =
1361                                        ( xVSS_context->pSettings->
1362                                        pTransitionList[i]->xVSS.
1363                                        transitionSpecific.
1364                                        pAlphaMagicSettings->
1365                                        blendingPercent) * 255 / 200;
1366                                }
1367                                else
1368                                {
1369                                    alphaSettings->blendingthreshold = 0;
1370                                }
1371                                alphaSettings->isreverse =
1372                                    xVSS_context->pSettings->
1373                                    pTransitionList[i]->xVSS.
1374                                    transitionSpecific.
1375                                    pAlphaMagicSettings->isreverse;
1376                                /* It means that the input jpg file for alpha magic has already
1377                                 been decoded -> no nedd to decode it again */
1378                                if( alphaSettings->blendingthreshold == 0 )
1379                                {
1380                                    xVSS_context->pSettings->
1381                                        pTransitionList[i]->
1382                                        ExtVideoTransitionFct =
1383                                        M4xVSS_AlphaMagic;
1384                                }
1385                                else
1386                                {
1387                                    xVSS_context->pSettings->
1388                                        pTransitionList[i]->
1389                                        ExtVideoTransitionFct =
1390                                        M4xVSS_AlphaMagicBlending;
1391                                }
1392                                xVSS_context->pSettings->pTransitionList[i]->
1393                                    pExtVideoTransitionFctCtxt = alphaSettings;
1394                                break;
1395                            }
1396                        }
1397                    }
1398
1399                    /* If the jpg has not been decoded yet ... */
1400                    if( xVSS_context->pSettings->
1401                        pTransitionList[i]->pExtVideoTransitionFctCtxt
1402                        == M4OSA_NULL )
1403                    {
1404                        M4VIFI_ImagePlane *outputPlane;
1405                        M4xVSS_internal_AlphaMagicSettings *alphaSettings;
1406                        /*UTF conversion support*/
1407                        M4OSA_Void *pDecodedPath = M4OSA_NULL;
1408
1409                        /*To support ARGB8888 : get the width and height */
1410                        M4OSA_UInt32 width_ARGB888 =
1411                            xVSS_context->pSettings->pTransitionList[i]->xVSS.
1412                            transitionSpecific.pAlphaMagicSettings->width;
1413                        M4OSA_UInt32 height_ARGB888 =
1414                            xVSS_context->pSettings->pTransitionList[i]->xVSS.
1415                            transitionSpecific.pAlphaMagicSettings->height;
1416                        M4OSA_TRACE1_1(
1417                            " TransitionListM4xVSS_SendCommand width State is %d",
1418                            width_ARGB888);
1419                        M4OSA_TRACE1_1(
1420                            " TransitionListM4xVSS_SendCommand height! State is %d",
1421                            height_ARGB888);
1422                        /* Allocate output plane */
1423                        outputPlane = (M4VIFI_ImagePlane *)M4OSA_32bitAlignedMalloc(3
1424                            * sizeof(M4VIFI_ImagePlane), M4VS, (M4OSA_Char
1425                            *)
1426                            "Output plane for Alpha magic transition");
1427
1428                        if( outputPlane == M4OSA_NULL )
1429                        {
1430                            M4OSA_TRACE1_0(
1431                                "Allocation error in M4xVSS_SendCommand");
1432                            /*FB: to avoid leaks when there is an error in the send command*/
1433                            /* Free Send command */
1434                            M4xVSS_freeCommand(xVSS_context);
1435                            /**/
1436                            return M4ERR_ALLOC;
1437                        }
1438
1439                        outputPlane[0].u_width = width;
1440                        outputPlane[0].u_height = height;
1441                        outputPlane[0].u_topleft = 0;
1442                        outputPlane[0].u_stride = width;
1443                        outputPlane[0].pac_data = (M4VIFI_UInt8
1444                            *)M4OSA_32bitAlignedMalloc(( width * height * 3)
1445                            >> 1,
1446                            M4VS,
1447                            (M4OSA_Char
1448                            *)
1449                            "Alloc for the Alpha magic pac_data output YUV");
1450                        ;
1451
1452                        if( outputPlane[0].pac_data == M4OSA_NULL )
1453                        {
1454                            free(outputPlane);
1455                            outputPlane = M4OSA_NULL;
1456                            M4OSA_TRACE1_0(
1457                                "Allocation error in M4xVSS_SendCommand");
1458                            /*FB: to avoid leaks when there is an error in the send command*/
1459                            /* Free Send command */
1460                            M4xVSS_freeCommand(xVSS_context);
1461                            /**/
1462                            return M4ERR_ALLOC;
1463                        }
1464                        outputPlane[1].u_width = width >> 1;
1465                        outputPlane[1].u_height = height >> 1;
1466                        outputPlane[1].u_topleft = 0;
1467                        outputPlane[1].u_stride = width >> 1;
1468                        outputPlane[1].pac_data = outputPlane[0].pac_data
1469                            + outputPlane[0].u_width * outputPlane[0].u_height;
1470                        outputPlane[2].u_width = width >> 1;
1471                        outputPlane[2].u_height = height >> 1;
1472                        outputPlane[2].u_topleft = 0;
1473                        outputPlane[2].u_stride = width >> 1;
1474                        outputPlane[2].pac_data = outputPlane[1].pac_data
1475                            + outputPlane[1].u_width * outputPlane[1].u_height;
1476
1477                        pDecodedPath =
1478                            xVSS_context->pSettings->pTransitionList[i]->xVSS.
1479                            transitionSpecific.pAlphaMagicSettings->
1480                            pAlphaFilePath;
1481                        /**
1482                        * UTF conversion: convert into the customer format, before being used*/
1483                        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
1484                            != M4OSA_NULL && xVSS_context->
1485                            UTFConversionContext.
1486                            pTempOutConversionBuffer != M4OSA_NULL )
1487                        {
1488                            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
1489                                (M4OSA_Void *)xVSS_context->pSettings->
1490                                pTransitionList[i]->xVSS.
1491                                transitionSpecific.
1492                                pAlphaMagicSettings->pAlphaFilePath,
1493                                (M4OSA_Void *)xVSS_context->
1494                                UTFConversionContext.
1495                                pTempOutConversionBuffer, &length);
1496
1497                            if( err != M4NO_ERROR )
1498                            {
1499                                M4OSA_TRACE1_1(
1500                                    "M4xVSS_SendCommand: pConvFromUTF8Fct returns err: 0x%x",
1501                                    err);
1502                                /* Free Send command */
1503                                M4xVSS_freeCommand(xVSS_context);
1504                                return err;
1505                            }
1506                            pDecodedPath =
1507                                xVSS_context->UTFConversionContext.
1508                                pTempOutConversionBuffer;
1509                        }
1510                        /**
1511                        End of the conversion, use the decoded path*/
1512                        /*To support ARGB8888 : convert + resizing from ARGB8888 to yuv420 */
1513
1514                        err = M4xVSS_internalConvertAndResizeARGB8888toYUV420(
1515                            pDecodedPath,
1516                            xVSS_context->pFileReadPtr, outputPlane,
1517                            width_ARGB888, height_ARGB888);
1518
1519                        if( err != M4NO_ERROR )
1520                        {
1521                            free(outputPlane[0].pac_data);
1522                            outputPlane[0].pac_data = M4OSA_NULL;
1523                            free(outputPlane);
1524                            outputPlane = M4OSA_NULL;
1525                            M4xVSS_freeCommand(xVSS_context);
1526                            M4OSA_TRACE1_1(
1527                                "M4xVSS_SendCommand: error when decoding alpha magic JPEG: 0x%x",
1528                                err);
1529                            return err;
1530                        }
1531
1532                        /* Allocate alpha settings structure */
1533                        alphaSettings =
1534                            (M4xVSS_internal_AlphaMagicSettings *)M4OSA_32bitAlignedMalloc(
1535                            sizeof(M4xVSS_internal_AlphaMagicSettings),
1536                            M4VS, (M4OSA_Char
1537                            *)"Alpha magic settings structure 2");
1538
1539                        if( alphaSettings == M4OSA_NULL )
1540                        {
1541                            M4OSA_TRACE1_0(
1542                                "Allocation error in M4xVSS_SendCommand");
1543                            /*FB: to avoid leaks when there is an error in the send command*/
1544                            /* Free Send command */
1545                            M4xVSS_freeCommand(xVSS_context);
1546                            /**/
1547                            return M4ERR_ALLOC;
1548                        }
1549                        alphaSettings->pPlane = outputPlane;
1550
1551                        if( xVSS_context->pSettings->pTransitionList[i]->xVSS.
1552                            transitionSpecific.pAlphaMagicSettings->
1553                            blendingPercent > 0 && xVSS_context->pSettings->
1554                            pTransitionList[i]->xVSS.
1555                            transitionSpecific.pAlphaMagicSettings->
1556                            blendingPercent <= 100 )
1557                        {
1558                            alphaSettings->blendingthreshold =
1559                                ( xVSS_context->pSettings->
1560                                pTransitionList[i]->xVSS.
1561                                transitionSpecific.pAlphaMagicSettings->
1562                                blendingPercent) * 255 / 200;
1563                        }
1564                        else
1565                        {
1566                            alphaSettings->blendingthreshold = 0;
1567                        }
1568                        alphaSettings->isreverse =
1569                            xVSS_context->pSettings->pTransitionList[i]->xVSS.
1570                            transitionSpecific.pAlphaMagicSettings->
1571                            isreverse;
1572
1573                        if( alphaSettings->blendingthreshold == 0 )
1574                        {
1575                            xVSS_context->pSettings->pTransitionList[i]->
1576                                ExtVideoTransitionFct = M4xVSS_AlphaMagic;
1577                        }
1578                        else
1579                        {
1580                            xVSS_context->pSettings->pTransitionList[i]->
1581                                ExtVideoTransitionFct =
1582                                M4xVSS_AlphaMagicBlending;
1583                        }
1584                        xVSS_context->pSettings->pTransitionList[i]->
1585                            pExtVideoTransitionFctCtxt = alphaSettings;
1586                    }
1587
1588                    break;
1589
1590                case M4xVSS_kVideoTransitionType_SlideTransition:
1591                    {
1592                        M4xVSS_internal_SlideTransitionSettings *slideSettings;
1593                        slideSettings =
1594                            (M4xVSS_internal_SlideTransitionSettings *)M4OSA_32bitAlignedMalloc(
1595                            sizeof(M4xVSS_internal_SlideTransitionSettings),
1596                            M4VS, (M4OSA_Char
1597                            *)"Internal slide transition settings");
1598
1599                        if( M4OSA_NULL == slideSettings )
1600                        {
1601                            M4OSA_TRACE1_0(
1602                                "Allocation error in M4xVSS_SendCommand");
1603                            /*FB: to avoid leaks when there is an error in the send command*/
1604                            /* Free Send command */
1605                            M4xVSS_freeCommand(xVSS_context);
1606                            /**/
1607                            return M4ERR_ALLOC;
1608                        }
1609                        /* Just copy the lone parameter from the input settings to the internal
1610                         context. */
1611
1612                        slideSettings->direction =
1613                            pSettings->pTransitionList[i]->xVSS.transitionSpecific.
1614                            pSlideTransitionSettings->direction;
1615
1616                        /* No need to keep our copy of the settings. */
1617                        xVSS_context->pSettings->pTransitionList[i]->
1618                            xVSS.transitionSpecific.pSlideTransitionSettings =
1619                            M4OSA_NULL;
1620                        xVSS_context->pSettings->pTransitionList[i]->
1621                            ExtVideoTransitionFct = &M4xVSS_SlideTransition;
1622                        xVSS_context->pSettings->pTransitionList[i]->
1623                            pExtVideoTransitionFctCtxt = slideSettings;
1624                    }
1625                    break;
1626
1627                case M4xVSS_kVideoTransitionType_FadeBlack:
1628                    {
1629                        xVSS_context->pSettings->pTransitionList[i]->
1630                            ExtVideoTransitionFct = &M4xVSS_FadeBlackTransition;
1631                    }
1632                    break;
1633
1634                case M4xVSS_kVideoTransitionType_External:
1635                    {
1636                        xVSS_context->pSettings->pTransitionList[i]->
1637                            ExtVideoTransitionFct =
1638                            pSettings->pTransitionList[i]->ExtVideoTransitionFct;
1639                        xVSS_context->pSettings->pTransitionList[i]->
1640                            pExtVideoTransitionFctCtxt =
1641                            pSettings->pTransitionList[i]->
1642                            pExtVideoTransitionFctCtxt;
1643                        xVSS_context->pSettings->pTransitionList[i]->
1644                            VideoTransitionType =
1645                            M4VSS3GPP_kVideoTransitionType_External;
1646                    }
1647                    break;
1648
1649                default:
1650                    break;
1651                } // switch
1652
1653            /* Update total_duration with transition duration */
1654            totalDuration -= xVSS_context->pSettings->
1655                pTransitionList[i]->uiTransitionDuration;
1656        }
1657
1658
1659        if( xVSS_context->pSettings->pClipList[i]->FileType
1660            == M4VIDEOEDITING_kFileType_ARGB8888 )
1661        {
1662            if(M4OSA_TRUE ==
1663                   xVSS_context->pSettings->pClipList[i]->xVSS.isPanZoom) {
1664                M4OSA_Char out_img[M4XVSS_MAX_PATH_LEN];
1665                M4OSA_Char out_img_tmp[M4XVSS_MAX_PATH_LEN];
1666                M4xVSS_Pto3GPP_params *pParams = M4OSA_NULL;
1667                M4OSA_Context pARGBFileIn;
1668                /*UTF conversion support*/
1669                M4OSA_Void *pDecodedPath = pSettings->pClipList[i]->pFile;
1670
1671                /* Parse Pto3GPP params chained list to know if input file has already been
1672                converted */
1673                if( xVSS_context->pPTo3GPPparamsList != M4OSA_NULL )
1674                {
1675                    M4OSA_UInt32 pCmpResult = 0;
1676
1677                    pParams = xVSS_context->pPTo3GPPparamsList;
1678                    /* We parse all Pto3gpp Param chained list */
1679                    while( pParams != M4OSA_NULL )
1680                    {
1681                        pCmpResult = strcmp((const char *)pSettings->pClipList[i]->pFile,
1682                            (const char *)pParams->pFileIn);
1683
1684                        if( pCmpResult == 0
1685                            && (pSettings->pClipList[i]->uiEndCutTime
1686                            == pParams->duration
1687                            || pSettings->pClipList[i]->xVSS.uiDuration
1688                            == pParams->duration)
1689                            && pSettings->pClipList[i]->xVSS.MediaRendering
1690                            == pParams->MediaRendering )
1691
1692
1693
1694                        {
1695                            /* Replace JPG filename with existing 3GP filename */
1696                            goto replaceARGB_3GP;
1697                        }
1698                        /* We need to update this variable, in case some pictures have been
1699                         added between two */
1700                        /* calls to M4xVSS_sendCommand */
1701                        pPto3GPP_last = pParams;
1702                        pParams = pParams->pNext;
1703                    }
1704                }
1705
1706                /* Construct output temporary 3GP filename */
1707                err = M4OSA_chrSPrintf(out_img, M4XVSS_MAX_PATH_LEN - 1, (M4OSA_Char *)"%simg%d.3gp",
1708                    xVSS_context->pTempPath, xVSS_context->tempFileIndex);
1709
1710                if( err != M4NO_ERROR )
1711                {
1712                    M4OSA_TRACE1_1("Error in M4OSA_chrSPrintf: 0x%x", err);
1713                    /*FB: to avoid leaks when there is an error in the send command*/
1714                    /* Free Send command */
1715                    M4xVSS_freeCommand(xVSS_context);
1716                    /**/
1717                    return err;
1718                }
1719
1720    #ifdef M4xVSS_RESERVED_MOOV_DISK_SPACE
1721
1722                err = M4OSA_chrSPrintf(out_img_tmp, M4XVSS_MAX_PATH_LEN - 1, "%simg%d.tmp",
1723                    xVSS_context->pTempPath, xVSS_context->tempFileIndex);
1724
1725                if( err != M4NO_ERROR )
1726                {
1727                    M4OSA_TRACE1_1("Error in M4OSA_chrSPrintf: 0x%x", err);
1728                    /*FB: to avoid leaks when there is an error in the send command*/
1729                    /* Free Send command */
1730                    M4xVSS_freeCommand(xVSS_context);
1731                    /**/
1732                    return err;
1733                }
1734
1735    #endif /*M4xVSS_RESERVED_MOOV_DISK_SPACE*/
1736
1737                xVSS_context->tempFileIndex++;
1738
1739                /* Allocate last element Pto3GPP params structure */
1740                pParams = (M4xVSS_Pto3GPP_params
1741                    *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_Pto3GPP_params),
1742                    M4VS, (M4OSA_Char *)"Element of Pto3GPP Params");
1743
1744                if( pParams == M4OSA_NULL )
1745                {
1746                    M4OSA_TRACE1_0(
1747                        "M4xVSS_sendCommand: Problem when allocating one element Pto3GPP Params");
1748                    /*FB: to avoid leaks when there is an error in the send command*/
1749                    /* Free Send command */
1750                    M4xVSS_freeCommand(xVSS_context);
1751                    /**/
1752                    return M4ERR_ALLOC;
1753                }
1754
1755                /* Initializes pfilexxx members of pParams to be able to free them correctly */
1756                pParams->pFileIn = M4OSA_NULL;
1757                pParams->pFileOut = M4OSA_NULL;
1758                pParams->pFileTemp = M4OSA_NULL;
1759                pParams->pNext = M4OSA_NULL;
1760                pParams->MediaRendering = M4xVSS_kResizing;
1761
1762                /*To support ARGB8888 :get the width and height */
1763                pParams->height = pSettings->pClipList[
1764                    i]->ClipProperties.uiStillPicHeight; //ARGB_Height;
1765                    pParams->width = pSettings->pClipList[
1766                        i]->ClipProperties.uiStillPicWidth; //ARGB_Width;
1767                        M4OSA_TRACE3_1("CLIP M4xVSS_SendCommand ARGB8888 H = %d", pParams->height);
1768                        M4OSA_TRACE3_1("CLIP M4xVSS_SendCommand ARGB8888 W = %d", pParams->width);
1769
1770                        if( xVSS_context->pPTo3GPPparamsList
1771                            == M4OSA_NULL ) /* Means it is the first element of the list */
1772                        {
1773                            /* Initialize the xVSS context with the first element of the list */
1774                            xVSS_context->pPTo3GPPparamsList = pParams;
1775
1776                            /* Save this element in case of other file to convert */
1777                            pPto3GPP_last = pParams;
1778                        }
1779                        else
1780                        {
1781                            /* Update next pointer of the previous last element of the chain */
1782                            pPto3GPP_last->pNext = pParams;
1783
1784                            /* Update save of last element of the chain */
1785                            pPto3GPP_last = pParams;
1786                        }
1787
1788                        /* Fill the last M4xVSS_Pto3GPP_params element */
1789                        pParams->duration =
1790                            xVSS_context->pSettings->pClipList[i]->uiEndCutTime;
1791                        /* If duration is filled, let's use it instead of EndCutTime */
1792                        if( xVSS_context->pSettings->pClipList[i]->xVSS.uiDuration != 0 )
1793                        {
1794                            pParams->duration =
1795                                xVSS_context->pSettings->pClipList[i]->xVSS.uiDuration;
1796                        }
1797
1798                        pParams->InputFileType = M4VIDEOEDITING_kFileType_ARGB8888;
1799
1800                        /**
1801                        * UTF conversion: convert into the customer format, before being used*/
1802                        pDecodedPath = xVSS_context->pSettings->pClipList[i]->pFile;
1803                        length = strlen(pDecodedPath);
1804
1805                        /**
1806                        * UTF conversion: convert into the customer format, before being used*/
1807                        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
1808                            != M4OSA_NULL && xVSS_context->
1809                            UTFConversionContext.pTempOutConversionBuffer
1810                            != M4OSA_NULL )
1811                        {
1812                            err = M4xVSS_internalConvertFromUTF8(xVSS_context, (M4OSA_Void
1813                                *)xVSS_context->pSettings->pClipList[i]->pFile,
1814                                (M4OSA_Void *)xVSS_context->
1815                                UTFConversionContext.pTempOutConversionBuffer,
1816                                &length);
1817
1818                            if( err != M4NO_ERROR )
1819                            {
1820                                M4OSA_TRACE1_1(
1821                                    "M4xVSS_SendCommand: pConvFromUTF8Fct returns err: 0x%x",
1822                                    err);
1823                                /* Free Send command */
1824                                M4xVSS_freeCommand(xVSS_context);
1825                                return err;
1826                            }
1827                            pDecodedPath =
1828                                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
1829                        }
1830
1831                        /**
1832                        * End of the UTF conversion, use the converted file path*/
1833                        pParams->pFileIn = (M4OSA_Void *)M4OSA_32bitAlignedMalloc(length + 1, M4VS,
1834                            (M4OSA_Char *)"Pto3GPP Params: file in");
1835
1836                        if( pParams->pFileIn == M4OSA_NULL )
1837                        {
1838                            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
1839                            /*FB: to avoid leaks when there is an error in the send command*/
1840                            /* Free Send command */
1841                            M4xVSS_freeCommand(xVSS_context);
1842                            /**/
1843                            return M4ERR_ALLOC;
1844                        }
1845                        memcpy((void *)pParams->pFileIn, (void *)pDecodedPath,
1846                            (length + 1)); /* Copy input file path */
1847
1848                        /* Check that JPG file is present on the FS (P4ME00002974) by just opening
1849                         and closing it */
1850                        err =
1851                            xVSS_context->pFileReadPtr->openRead(&pARGBFileIn, pDecodedPath,
1852                            M4OSA_kFileRead);
1853
1854                        if( err != M4NO_ERROR )
1855                        {
1856                            M4OSA_TRACE1_2("Can't open input jpg file %s, error: 0x%x\n",
1857                                pDecodedPath, err);
1858                            /* Free Send command */
1859                            M4xVSS_freeCommand(xVSS_context);
1860                            return err;
1861                        }
1862                        err = xVSS_context->pFileReadPtr->closeRead(pARGBFileIn);
1863
1864                        if( err != M4NO_ERROR )
1865                        {
1866                            M4OSA_TRACE1_2("Can't close input jpg file %s, error: 0x%x\n",
1867                                pDecodedPath, err);
1868                            /* Free Send command */
1869                            M4xVSS_freeCommand(xVSS_context);
1870                            return err;
1871                        }
1872
1873                        /**
1874                        * UTF conversion: convert into the customer format, before being used*/
1875                        pDecodedPath = out_img;
1876                        length = strlen(pDecodedPath);
1877
1878                        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
1879                            != M4OSA_NULL && xVSS_context->
1880                            UTFConversionContext.pTempOutConversionBuffer
1881                            != M4OSA_NULL )
1882                        {
1883                            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
1884                                (M4OSA_Void *)out_img, (M4OSA_Void *)xVSS_context->
1885                                UTFConversionContext.pTempOutConversionBuffer, &length);
1886
1887                            if( err != M4NO_ERROR )
1888                            {
1889                                M4OSA_TRACE1_1(
1890                                    "M4xVSS_SendCommand: pConvFromUTF8Fct returns err: 0x%x",
1891                                    err);
1892                                /* Free Send command */
1893                                M4xVSS_freeCommand(xVSS_context);
1894                                return err;
1895                            }
1896                            pDecodedPath =
1897                                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
1898                        }
1899
1900                        /**
1901                        * End of the UTF conversion, use the converted file path*/
1902                        pParams->pFileOut = (M4OSA_Void *)M4OSA_32bitAlignedMalloc((length + 1), M4VS,
1903                            (M4OSA_Char *)"Pto3GPP Params: file out");
1904
1905                        if( pParams->pFileOut == M4OSA_NULL )
1906                        {
1907                            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
1908                            /*FB: to avoid leaks when there is an error in the send command*/
1909                            /* Free Send command */
1910                            M4xVSS_freeCommand(xVSS_context);
1911                            /**/
1912                            return M4ERR_ALLOC;
1913                        }
1914                        memcpy((void *)pParams->pFileOut, (void *)pDecodedPath,
1915                            (length + 1)); /* Copy output file path */
1916
1917    #ifdef M4xVSS_RESERVED_MOOV_DISK_SPACE
1918                        /**
1919                        * UTF conversion: convert into the customer format, before being used*/
1920
1921                        pDecodedPath = out_img_tmp;
1922                        length = strlen(pDecodedPath);
1923
1924                        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
1925                            != M4OSA_NULL && xVSS_context->
1926                            UTFConversionContext.pTempOutConversionBuffer
1927                            != M4OSA_NULL )
1928                        {
1929                            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
1930                                (M4OSA_Void *)out_img_tmp, (M4OSA_Void *)xVSS_context->
1931                                UTFConversionContext.pTempOutConversionBuffer, &length);
1932
1933                            if( err != M4NO_ERROR )
1934                            {
1935                                M4OSA_TRACE1_1("M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8\
1936                                     returns err: 0x%x",
1937                                    err);
1938                                /* Free Send command */
1939                                M4xVSS_freeCommand(xVSS_context);
1940                                return err;
1941                            }
1942                            pDecodedPath =
1943                                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
1944                        }
1945
1946                        /**
1947                        * End of the UTF conversion, use the converted file path*/
1948                        pParams->pFileTemp = (M4OSA_Void *)M4OSA_32bitAlignedMalloc((length + 1), M4VS,
1949                            (M4OSA_Char *)"Pto3GPP Params: file temp");
1950
1951                        if( pParams->pFileTemp == M4OSA_NULL )
1952                        {
1953                            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
1954                            /*FB: to avoid leaks when there is an error in the send command*/
1955                            /* Free Send command */
1956                            M4xVSS_freeCommand(xVSS_context);
1957                            /**/
1958                            return M4ERR_ALLOC;
1959                        }
1960                        memcpy((void *)pParams->pFileTemp, (void *)pDecodedPath,
1961                            (length + 1)); /* Copy temporary file path */
1962
1963    #endif                         /*M4xVSS_RESERVED_MOOV_DISK_SPACE*/
1964
1965                        /* Fill PanAndZoom settings if needed */
1966
1967                        if( M4OSA_TRUE
1968                            == xVSS_context->pSettings->pClipList[i]->xVSS.isPanZoom )
1969                        {
1970                            pParams->isPanZoom =
1971                                xVSS_context->pSettings->pClipList[i]->xVSS.isPanZoom;
1972                            /* Check that Pan & Zoom parameters are corrects */
1973                            if( xVSS_context->pSettings->pClipList[i]->xVSS.PanZoomXa > 1000
1974                                || xVSS_context->pSettings->pClipList[i]->xVSS.PanZoomXa
1975                                <= 0 || xVSS_context->pSettings->pClipList[i]->xVSS.
1976                                PanZoomTopleftXa > 1000
1977                                || xVSS_context->pSettings->pClipList[i]->xVSS.
1978                                PanZoomTopleftYa > 1000
1979                                || xVSS_context->pSettings->pClipList[i]->xVSS.PanZoomXb
1980                                > 1000
1981                                || xVSS_context->pSettings->pClipList[i]->xVSS.PanZoomXb
1982                                <= 0 || xVSS_context->pSettings->pClipList[i]->xVSS.
1983                                PanZoomTopleftXb > 1000
1984                                || xVSS_context->pSettings->pClipList[i]->xVSS.
1985                                PanZoomTopleftYb > 1000)
1986                            {
1987                                M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
1988                                M4xVSS_freeCommand(xVSS_context);
1989                                return M4ERR_PARAMETER;
1990                            }
1991
1992                            pParams->PanZoomXa =
1993                                xVSS_context->pSettings->pClipList[i]->xVSS.PanZoomXa;
1994                            pParams->PanZoomTopleftXa =
1995                                xVSS_context->pSettings->
1996                                pClipList[i]->xVSS.PanZoomTopleftXa;
1997                            pParams->PanZoomTopleftYa =
1998                                xVSS_context->pSettings->
1999                                pClipList[i]->xVSS.PanZoomTopleftYa;
2000                            pParams->PanZoomXb =
2001                                xVSS_context->pSettings->pClipList[i]->xVSS.PanZoomXb;
2002                            pParams->PanZoomTopleftXb =
2003                                xVSS_context->pSettings->
2004                                pClipList[i]->xVSS.PanZoomTopleftXb;
2005                            pParams->PanZoomTopleftYb =
2006                                xVSS_context->pSettings->
2007                                pClipList[i]->xVSS.PanZoomTopleftYb;
2008                        }
2009                        else
2010                        {
2011                            pParams->isPanZoom = M4OSA_FALSE;
2012                        }
2013                        /*+ PR No: blrnxpsw#223*/
2014                        /*Intializing the Video Frame Rate as it may not be intialized*/
2015                        /*Other changes made is @ M4xVSS_Internal.c @ line 1518 in
2016                        M4xVSS_internalStartConvertPictureTo3gp*/
2017                        switch( xVSS_context->pSettings->videoFrameRate )
2018                        {
2019                            case M4VIDEOEDITING_k30_FPS:
2020                                pParams->framerate = 33;
2021                                break;
2022
2023                            case M4VIDEOEDITING_k25_FPS:
2024                                pParams->framerate = 40;
2025                                break;
2026
2027                            case M4VIDEOEDITING_k20_FPS:
2028                                pParams->framerate = 50;
2029                                break;
2030
2031                            case M4VIDEOEDITING_k15_FPS:
2032                                pParams->framerate = 66;
2033                                break;
2034
2035                            case M4VIDEOEDITING_k12_5_FPS:
2036                                pParams->framerate = 80;
2037                                break;
2038
2039                            case M4VIDEOEDITING_k10_FPS:
2040                                pParams->framerate = 100;
2041                                break;
2042
2043                            case M4VIDEOEDITING_k7_5_FPS:
2044                                pParams->framerate = 133;
2045                                break;
2046
2047                            case M4VIDEOEDITING_k5_FPS:
2048                                pParams->framerate = 200;
2049                                break;
2050
2051                            default:
2052                                /*Making Default Frame Rate @ 15 FPS*/
2053                                pParams->framerate = 66;
2054                                break;
2055                        }
2056                        /*-PR No: blrnxpsw#223*/
2057                        if( xVSS_context->pSettings->pClipList[i]->xVSS.MediaRendering
2058                            == M4xVSS_kCropping
2059                            || xVSS_context->pSettings->pClipList[i]->xVSS.
2060                            MediaRendering == M4xVSS_kBlackBorders
2061                            || xVSS_context->pSettings->pClipList[i]->xVSS.
2062                            MediaRendering == M4xVSS_kResizing )
2063                        {
2064                            pParams->MediaRendering =
2065                                xVSS_context->pSettings->pClipList[i]->xVSS.MediaRendering;
2066                        }
2067
2068                        pParams->pNext = M4OSA_NULL;
2069                        pParams->isCreated = M4OSA_FALSE;
2070                        xVSS_context->nbStepTotal++;
2071                       /* Set bTranscodingRequired to TRUE to indicate the kenburn video has
2072                        * been generated in analysis phase, and does not need to be tanscoded again
2073                        * in saving phase */
2074                        xVSS_context->pSettings->pClipList[i]->bTranscodingRequired =
2075                           M4OSA_TRUE;
2076
2077    replaceARGB_3GP:
2078                        /* Update total duration */
2079                        totalDuration += pParams->duration;
2080
2081                        /* Replacing in VSS structure the JPG file by the 3gp file */
2082                        xVSS_context->pSettings->pClipList[i]->FileType =
2083                            M4VIDEOEDITING_kFileType_3GPP;
2084
2085                        if( xVSS_context->pSettings->pClipList[i]->pFile != M4OSA_NULL )
2086                        {
2087                            free(xVSS_context->pSettings->pClipList[i]->pFile);
2088                            xVSS_context->pSettings->pClipList[i]->pFile = M4OSA_NULL;
2089                        }
2090
2091                        /**
2092                        * UTF conversion: convert into UTF8, before being used*/
2093                        pDecodedPath = pParams->pFileOut;
2094
2095                        if( xVSS_context->UTFConversionContext.pConvToUTF8Fct != M4OSA_NULL
2096                            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
2097                            != M4OSA_NULL )
2098                        {
2099                            err = M4xVSS_internalConvertToUTF8(xVSS_context,
2100                                (M4OSA_Void *)pParams->pFileOut,
2101                                (M4OSA_Void *)xVSS_context->
2102                                UTFConversionContext.pTempOutConversionBuffer,
2103                                &length);
2104
2105                            if( err != M4NO_ERROR )
2106                            {
2107                                M4OSA_TRACE1_1(
2108                                    "M4xVSS_SendCommand: M4xVSS_internalConvertToUTF8 returns err: \
2109                                    0x%x",err);
2110                                /* Free Send command */
2111                                M4xVSS_freeCommand(xVSS_context);
2112                                return err;
2113                            }
2114                            pDecodedPath =
2115                                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
2116                        }
2117                        else
2118                        {
2119                            length = strlen(pDecodedPath);
2120                        }
2121                        /**
2122                        * End of the UTF conversion, use the converted file path*/
2123                        xVSS_context->pSettings->pClipList[i]->pFile = M4OSA_32bitAlignedMalloc((length
2124                            + 1), M4VS, (M4OSA_Char *)"xVSS file path of ARGB to 3gp");
2125
2126                        if( xVSS_context->pSettings->pClipList[i]->pFile == M4OSA_NULL )
2127                        {
2128                            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
2129                            /*FB: to avoid leaks when there is an error in the send command*/
2130                            /* Free Send command */
2131                            M4xVSS_freeCommand(xVSS_context);
2132                            /**/
2133                            return M4ERR_ALLOC;
2134                        }
2135                        memcpy((void *)xVSS_context->pSettings->pClipList[i]->pFile,
2136                            (void *)pDecodedPath, (length + 1));
2137                        /*FB: add file path size because of UTF16 conversion*/
2138                        xVSS_context->pSettings->pClipList[i]->filePathSize = length+1;
2139            }
2140        }
2141        /************************
2142        3GP input file type case
2143        *************************/
2144        else if( xVSS_context->pSettings->pClipList[i]->FileType
2145            == M4VIDEOEDITING_kFileType_3GPP
2146            || xVSS_context->pSettings->pClipList[i]->FileType
2147            == M4VIDEOEDITING_kFileType_MP4
2148            || xVSS_context->pSettings->pClipList[i]->FileType
2149            == M4VIDEOEDITING_kFileType_M4V )
2150        {
2151            /*UTF conversion support*/
2152            M4OSA_Void *pDecodedPath = M4OSA_NULL;
2153
2154            /* Need to call MCS in case 3GP video/audio types are not compatible
2155            (H263/MPEG4 or AMRNB/AAC) */
2156            /* => Need to fill MCS_Params structure with the right parameters ! */
2157            /* Need also to parse MCS params struct to check if file has already been transcoded */
2158
2159            M4VIDEOEDITING_ClipProperties fileProperties;
2160            M4xVSS_MCS_params *pParams;
2161            M4OSA_Bool audioIsDifferent = M4OSA_FALSE;
2162            M4OSA_Bool videoIsDifferent = M4OSA_FALSE;
2163            M4OSA_Bool bAudioMono;
2164            /* Initialize file properties structure */
2165
2166            memset((void *) &fileProperties,0,
2167                sizeof(M4VIDEOEDITING_ClipProperties));
2168
2169            //fileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio;
2170
2171            /* Prevent from bad initializing of percentage cut time */
2172            if( xVSS_context->pSettings->pClipList[i]->xVSS.uiEndCutPercent
2173                            > 100 || xVSS_context->pSettings->pClipList[i]->xVSS.
2174                            uiBeginCutPercent > 100 )
2175            {
2176                /* These percentage cut time have probably not been initialized */
2177                /* Let's not use them by setting them to 0 */
2178                xVSS_context->pSettings->pClipList[i]->xVSS.uiEndCutPercent = 0;
2179                xVSS_context->pSettings->pClipList[i]->xVSS.uiBeginCutPercent =
2180                    0;
2181            }
2182
2183            /**
2184            * UTF conversion: convert into the customer format, before being used*/
2185            pDecodedPath = xVSS_context->pSettings->pClipList[i]->pFile;
2186
2187            if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
2188                != M4OSA_NULL && xVSS_context->
2189                UTFConversionContext.pTempOutConversionBuffer
2190                != M4OSA_NULL )
2191            {
2192                err = M4xVSS_internalConvertFromUTF8(xVSS_context, (M4OSA_Void
2193                    *)xVSS_context->pSettings->pClipList[i]->pFile,
2194                    (M4OSA_Void *)xVSS_context->
2195                    UTFConversionContext.pTempOutConversionBuffer,
2196                    &length);
2197
2198                if( err != M4NO_ERROR )
2199                {
2200                    M4OSA_TRACE1_1(
2201                        "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
2202                        err);
2203                    /* Free Send command */
2204                    M4xVSS_freeCommand(xVSS_context);
2205                    return err;
2206                }
2207                pDecodedPath =
2208                    xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
2209            }
2210            /**
2211            * End of the UTF conversion, use the converted file path*/
2212            err = M4xVSS_internalGetProperties(xVSS_context, pDecodedPath,
2213                &fileProperties);
2214
2215            if( err != M4NO_ERROR )
2216            {
2217                M4xVSS_freeCommand(xVSS_context);
2218                M4OSA_TRACE1_1(
2219                    "M4xVSS_sendCommand: M4xVSS_internalGetProperties returned 0x%x",
2220                    err);
2221                /* TODO: Translate error code of MCS to an xVSS error code */
2222                return err;
2223            }
2224
2225            /* Parse MCS params chained list to know if input file has already been converted */
2226            if( xVSS_context->pMCSparamsList != M4OSA_NULL )
2227            {
2228                M4OSA_UInt32 pCmpResult = 0;
2229
2230                pParams = xVSS_context->pMCSparamsList;
2231                /* We parse all MCS Param chained list */
2232                while( pParams != M4OSA_NULL )
2233                {
2234
2235                    /**
2236                    * UTF conversion: convert into UTF8, before being used*/
2237                    pDecodedPath = pParams->pFileIn;
2238
2239                    if( xVSS_context->UTFConversionContext.pConvToUTF8Fct
2240                        != M4OSA_NULL && xVSS_context->
2241                        UTFConversionContext.pTempOutConversionBuffer
2242                        != M4OSA_NULL )
2243                    {
2244                        err = M4xVSS_internalConvertToUTF8(xVSS_context,
2245                            (M4OSA_Void *)pParams->pFileIn,
2246                            (M4OSA_Void *)xVSS_context->
2247                            UTFConversionContext.
2248                            pTempOutConversionBuffer, &length);
2249
2250                        if( err != M4NO_ERROR )
2251                        {
2252                            M4OSA_TRACE1_1(
2253                                "M4xVSS_SendCommand: M4xVSS_internalConvertToUTF8 returns err:\
2254                                 0x%x", err);
2255                            /* Free Send command */
2256                            M4xVSS_freeCommand(xVSS_context);
2257                            return err;
2258                        }
2259                        pDecodedPath = xVSS_context->
2260                            UTFConversionContext.pTempOutConversionBuffer;
2261                    }
2262
2263                    /**
2264                    * End of the UTF conversion, use the converted file path*/
2265                    pCmpResult = strcmp((const char *)pSettings->pClipList[i]->pFile,
2266                        (const char *)pDecodedPath);
2267
2268                    /* If input filenames are the same, and if this is not a BGM, we can reuse
2269                    the transcoded file */
2270                    if( pCmpResult == 0 && pParams->isBGM == M4OSA_FALSE
2271                        && pParams->BeginCutTime
2272                        == pSettings->pClipList[i]->uiBeginCutTime
2273                        && (pParams->EndCutTime
2274                        == pSettings->pClipList[i]->uiEndCutTime
2275                        || pParams->EndCutTime
2276                        == pSettings->pClipList[i]->uiBeginCutTime
2277                        + pSettings->pClipList[i]->xVSS.uiDuration)
2278                        && pSettings->pClipList[i]->xVSS.MediaRendering
2279                        == pParams->MediaRendering )
2280                    {
2281                        if( pSettings->xVSS.pBGMtrack != M4OSA_NULL )
2282                        {
2283                            if( pSettings->xVSS.pBGMtrack->uiAddVolume == 100
2284                                || (pParams->OutputAudioFormat
2285                                == M4VIDEOEDITING_kNullAudio
2286                                && fileProperties.AudioStreamType
2287                                == pSettings->xVSS.outputAudioFormat)
2288                                || pParams->OutputAudioFormat
2289                                == pSettings->xVSS.outputAudioFormat
2290                                || fileProperties.AudioStreamType
2291                                == M4VIDEOEDITING_kNoneAudio )
2292                            {
2293                                /* Replace 3GP filename with transcoded 3GP filename */
2294                                goto replace3GP_3GP;
2295                            }
2296                        }
2297                        else if( ( pParams->OutputAudioFormat
2298                            == M4VIDEOEDITING_kNullAudio
2299                            && fileProperties.AudioStreamType
2300                            == pSettings->xVSS.outputAudioFormat)
2301                            || pParams->OutputAudioFormat
2302                            == pSettings->xVSS.outputAudioFormat
2303                            || fileProperties.AudioStreamType
2304                            == M4VIDEOEDITING_kNoneAudio )
2305                        {
2306                            /* Replace 3GP filename with transcoded 3GP filename */
2307                            goto replace3GP_3GP;
2308                        }
2309                    }
2310
2311                    /* We need to update this variable, in case some 3GP files have been added
2312                    between two */
2313                    /* calls to M4xVSS_sendCommand */
2314                    pMCS_last = pParams;
2315                    pParams = pParams->pNext;
2316                }
2317            }
2318
2319            /* If we have percentage information let's use it... */
2320            if( xVSS_context->pSettings->pClipList[i]->xVSS.uiEndCutPercent != 0
2321                || xVSS_context->pSettings->pClipList[i]->xVSS.uiBeginCutPercent
2322                != 0 )
2323            {
2324                /* If percentage information are not correct and if duration field is not filled */
2325                if( ( xVSS_context->pSettings->pClipList[i]->xVSS.
2326                    uiEndCutPercent
2327                    <= xVSS_context->pSettings->pClipList[i]->xVSS.
2328                    uiBeginCutPercent)
2329                    && xVSS_context->pSettings->pClipList[i]->xVSS.uiDuration
2330                    == 0 )
2331                {
2332                    M4OSA_TRACE1_0(
2333                        "M4xVSS_sendCommand: Bad percentage for begin and end cut time !");
2334                    M4xVSS_freeCommand(xVSS_context);
2335                    return M4ERR_PARAMETER;
2336                }
2337
2338                /* We transform the percentage into absolute time */
2339                xVSS_context->pSettings->pClipList[i]->uiBeginCutTime
2340                    = (M4OSA_UInt32)(
2341                    xVSS_context->pSettings->pClipList[i]->xVSS.
2342                    uiBeginCutPercent
2343                    * fileProperties.uiClipDuration / 100);
2344                xVSS_context->pSettings->pClipList[i]->uiEndCutTime
2345                    = (M4OSA_UInt32)(
2346                    xVSS_context->pSettings->pClipList[i]->xVSS.
2347                    uiEndCutPercent
2348                    * fileProperties.uiClipDuration / 100);
2349            }
2350            /* ...Otherwise, we use absolute time. */
2351            else
2352            {
2353                /* If endCutTime == 0, it means all the file is taken. Let's change to the file
2354                duration, to accurate preview. */
2355                if( xVSS_context->pSettings->pClipList[i]->uiEndCutTime == 0
2356                    || xVSS_context->pSettings->pClipList[i]->uiEndCutTime
2357                    > fileProperties.uiClipDuration )
2358                {
2359                    xVSS_context->pSettings->pClipList[i]->uiEndCutTime =
2360                        fileProperties.uiClipDuration;
2361                }
2362            }
2363
2364            /* If duration field is filled, it has priority on other fields on EndCutTime,
2365             so let's use it */
2366            if( xVSS_context->pSettings->pClipList[i]->xVSS.uiDuration != 0 )
2367            {
2368                xVSS_context->pSettings->pClipList[i]->uiEndCutTime =
2369                    xVSS_context->pSettings->pClipList[i]->uiBeginCutTime
2370                    +xVSS_context->pSettings->pClipList[i]->xVSS.uiDuration;
2371
2372                if( xVSS_context->pSettings->pClipList[i]->uiEndCutTime
2373                    > fileProperties.uiClipDuration )
2374                {
2375                    xVSS_context->pSettings->pClipList[i]->uiEndCutTime =
2376                        fileProperties.uiClipDuration;
2377                }
2378            }
2379
2380            /* If output video format is not set, we take video format of the first 3GP video */
2381            if( xVSS_context->pSettings->xVSS.outputVideoFormat
2382                == M4VIDEOEDITING_kNoneVideo )
2383            {
2384                //xVSS_context->pSettings->xVSS.outputVideoFormat = fileProperties.VideoStreamType;
2385                //M4OSA_TRACE2_1("Output video format is not set, set it to current clip: %d",
2386                // xVSS_context->pSettings->xVSS.outputVideoFormat);
2387                M4OSA_TRACE1_0(
2388                    "Output video format is not set, an error parameter is returned.");
2389                M4xVSS_freeCommand(xVSS_context);
2390                return M4ERR_PARAMETER;
2391            }
2392
2393            if( xVSS_context->pSettings->xVSS.outputAudioFormat
2394                == M4VIDEOEDITING_kNoneAudio )
2395            {
2396                //xVSS_context->pSettings->xVSS.outputAudioFormat = fileProperties.AudioStreamType;
2397                M4OSA_TRACE2_1(
2398                    "Output audio format is not set -> remove audio track of clip: %d",
2399                    i);
2400            }
2401
2402            if( fileProperties.uiNbChannels == 1 )
2403            {
2404                bAudioMono = M4OSA_TRUE;
2405            }
2406            else
2407            {
2408                bAudioMono = M4OSA_FALSE;
2409            }
2410
2411            if( fileProperties.AudioStreamType
2412                != xVSS_context->pSettings->xVSS.outputAudioFormat
2413                || (fileProperties.AudioStreamType == M4VIDEOEDITING_kAAC
2414                && (fileProperties.uiSamplingFrequency != samplingFreq
2415                || bAudioMono
2416                != xVSS_context->pSettings->xVSS.bAudioMono)) )
2417            {
2418                audioIsDifferent = M4OSA_TRUE;
2419                /* If we want to replace audio, there is no need to transcode audio */
2420                if( pSettings->xVSS.pBGMtrack != M4OSA_NULL )
2421                {
2422                    /* temp fix :PT volume not herad in the second clip */
2423                    if( /*(pSettings->xVSS.pBGMtrack->uiAddVolume == 100
2424                        && xVSS_context->pSettings->xVSS.outputFileSize == 0)
2425                        ||*/
2426                        fileProperties.AudioStreamType
2427                        == M4VIDEOEDITING_kNoneAudio ) /*11/12/2008 CR 3283 VAL for the MMS
2428                        use case, we need to transcode except the media without audio*/
2429                    {
2430                        audioIsDifferent = M4OSA_FALSE;
2431                    }
2432                }
2433                else if( fileProperties.AudioStreamType
2434                    == M4VIDEOEDITING_kNoneAudio )
2435                {
2436                    audioIsDifferent = M4OSA_FALSE;
2437                }
2438            }
2439            /* Here check the clip video profile and level, if it exceeds
2440             * the profile and level of export file, then the file needs
2441             * to be transcoded(do not do compress domain trim).
2442             * Also for MPEG4 fomart, always do transcoding since HW encoder
2443             * may use different time scale value than the input clip*/
2444           if ((fileProperties.uiVideoProfile >
2445                     xVSS_context->pSettings->xVSS.outputVideoProfile) ||
2446                (fileProperties.uiVideoLevel >
2447                     xVSS_context->pSettings->xVSS.outputVideoLevel) ||
2448                (fileProperties.VideoStreamType == M4VIDEOEDITING_kMPEG4)) {
2449               /* Set bTranscodingRequired to TRUE to indicate the video will be
2450                * transcoded in MCS. */
2451               xVSS_context->pSettings->pClipList[i]->bTranscodingRequired =
2452                   M4OSA_TRUE;
2453               videoIsDifferent = M4OSA_TRUE;
2454           }
2455
2456            if( videoIsDifferent == M4OSA_TRUE || audioIsDifferent == M4OSA_TRUE)
2457            {
2458                M4OSA_Char out_3gp[M4XVSS_MAX_PATH_LEN];
2459                M4OSA_Char out_3gp_tmp[M4XVSS_MAX_PATH_LEN];
2460
2461                /* Construct output temporary 3GP filename */
2462                err = M4OSA_chrSPrintf(out_3gp, M4XVSS_MAX_PATH_LEN - 1, (M4OSA_Char *)"%svid%d.3gp",
2463                    xVSS_context->pTempPath, xVSS_context->tempFileIndex);
2464
2465                if( err != M4NO_ERROR )
2466                {
2467                    M4OSA_TRACE1_1("Error in M4OSA_chrSPrintf: 0x%x", err);
2468                    return err;
2469                }
2470
2471#ifdef M4xVSS_RESERVED_MOOV_DISK_SPACE
2472
2473                err = M4OSA_chrSPrintf(out_3gp_tmp, M4XVSS_MAX_PATH_LEN - 1, "%svid%d.tmp",
2474                    xVSS_context->pTempPath, xVSS_context->tempFileIndex);
2475
2476                if( err != M4NO_ERROR )
2477                {
2478                    M4OSA_TRACE1_1("Error in M4OSA_chrSPrintf: 0x%x", err);
2479                    return err;
2480                }
2481
2482#endif /*M4xVSS_RESERVED_MOOV_DISK_SPACE*/
2483
2484                xVSS_context->tempFileIndex++;
2485
2486                pParams =
2487                    (M4xVSS_MCS_params *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_MCS_params),
2488                    M4VS, (M4OSA_Char *)"Element of MCS Params (for 3GP)");
2489
2490                if( pParams == M4OSA_NULL )
2491                {
2492                    M4OSA_TRACE1_0(
2493                        "M4xVSS_sendCommand: Problem when allocating one element MCS Params");
2494                    /*FB: to avoid leaks when there is an error in the send command*/
2495                    /* Free Send command */
2496                    M4xVSS_freeCommand(xVSS_context);
2497                    /**/
2498                    return M4ERR_ALLOC;
2499                }
2500                pParams->MediaRendering = M4xVSS_kResizing;
2501                pParams->videoclipnumber = i; // Indicates video clip index
2502
2503                if( xVSS_context->pMCSparamsList
2504                    == M4OSA_NULL ) /* Means it is the first element of the list */
2505                {
2506                    /* Initialize the xVSS context with the first element of the list */
2507                    xVSS_context->pMCSparamsList = pParams;
2508                }
2509                else
2510                {
2511                    /* Update next pointer of the previous last element of the chain */
2512                    pMCS_last->pNext = pParams;
2513                }
2514
2515                /* Save this element in case of other file to convert */
2516                pMCS_last = pParams;
2517
2518                /* Fill the last M4xVSS_MCS_params element */
2519                pParams->InputFileType = M4VIDEOEDITING_kFileType_3GPP;
2520                pParams->OutputFileType = M4VIDEOEDITING_kFileType_3GPP;
2521
2522                pParams->OutputVideoTimescale = xVSS_context->targetedTimescale;
2523
2524                /* We do not need to reencode video if its parameters do not differ */
2525                /* from output settings parameters */
2526                if( videoIsDifferent == M4OSA_TRUE )
2527                {
2528                    pParams->OutputVideoFormat =
2529                        xVSS_context->pSettings->xVSS.outputVideoFormat;
2530                    pParams->outputVideoProfile =
2531                        xVSS_context->pSettings->xVSS.outputVideoProfile;
2532                    pParams->outputVideoLevel =
2533                        xVSS_context->pSettings->xVSS.outputVideoLevel;
2534                    pParams->OutputVideoFrameRate =
2535                        xVSS_context->pSettings->videoFrameRate;
2536                    pParams->OutputVideoFrameSize =
2537                        xVSS_context->pSettings->xVSS.outputVideoSize;
2538
2539                    /*FB: VAL CR P4ME00003076
2540                    The output video bitrate is now directly given by the user in the edition
2541                    settings structure If the bitrate given by the user is irrelevant
2542                    (the MCS minimum and maximum video bitrate are used),
2543                    the output video bitrate is hardcoded according to the output video size*/
2544                    if( xVSS_context->pSettings->xVSS.outputVideoBitrate
2545                        >= M4VIDEOEDITING_k16_KBPS
2546                        && xVSS_context->pSettings->xVSS.outputVideoBitrate
2547                        <= M4VIDEOEDITING_k8_MBPS ) /*+ New Encoder bitrates */
2548                    {
2549                        pParams->OutputVideoBitrate =
2550                            xVSS_context->pSettings->xVSS.outputVideoBitrate;
2551                    }
2552                    else
2553                    {
2554                        switch( xVSS_context->pSettings->xVSS.outputVideoSize )
2555                        {
2556                            case M4VIDEOEDITING_kSQCIF:
2557                                pParams->OutputVideoBitrate =
2558                                    M4VIDEOEDITING_k48_KBPS;
2559                                break;
2560
2561                            case M4VIDEOEDITING_kQQVGA:
2562                                pParams->OutputVideoBitrate =
2563                                    M4VIDEOEDITING_k64_KBPS;
2564                                break;
2565
2566                            case M4VIDEOEDITING_kQCIF:
2567                                pParams->OutputVideoBitrate =
2568                                    M4VIDEOEDITING_k128_KBPS;
2569                                break;
2570
2571                            case M4VIDEOEDITING_kQVGA:
2572                                pParams->OutputVideoBitrate =
2573                                    M4VIDEOEDITING_k384_KBPS;
2574                                break;
2575
2576                            case M4VIDEOEDITING_kCIF:
2577                                pParams->OutputVideoBitrate =
2578                                    M4VIDEOEDITING_k384_KBPS;
2579                                break;
2580
2581                            case M4VIDEOEDITING_kVGA:
2582                                pParams->OutputVideoBitrate =
2583                                    M4VIDEOEDITING_k512_KBPS;
2584                                break;
2585
2586                            default: /* Should not happen !! */
2587                                pParams->OutputVideoBitrate =
2588                                    M4VIDEOEDITING_k64_KBPS;
2589                                break;
2590                        }
2591                    }
2592                }
2593                else
2594                {
2595                    pParams->outputVideoProfile =
2596                        xVSS_context->pSettings->xVSS.outputVideoProfile;
2597                    pParams->outputVideoLevel =
2598                        xVSS_context->pSettings->xVSS.outputVideoLevel;
2599                    pParams->OutputVideoFormat = M4VIDEOEDITING_kNullVideo;
2600                    pParams->OutputVideoFrameRate =
2601                        M4VIDEOEDITING_k15_FPS; /* Must be set, otherwise, MCS returns an error */
2602                }
2603
2604                if( audioIsDifferent == M4OSA_TRUE )
2605                {
2606                    pParams->OutputAudioFormat =
2607                        xVSS_context->pSettings->xVSS.outputAudioFormat;
2608
2609                    switch( xVSS_context->pSettings->xVSS.outputAudioFormat )
2610                    {
2611                        case M4VIDEOEDITING_kNoneAudio:
2612                            break;
2613
2614                        case M4VIDEOEDITING_kAMR_NB:
2615                            pParams->OutputAudioBitrate =
2616                                M4VIDEOEDITING_k12_2_KBPS;
2617                            pParams->bAudioMono = M4OSA_TRUE;
2618                            pParams->OutputAudioSamplingFrequency =
2619                                M4VIDEOEDITING_kDefault_ASF;
2620                            break;
2621
2622                        case M4VIDEOEDITING_kAAC:
2623                            {
2624                                /*FB: VAL CR P4ME00003076
2625                                The output audio bitrate in the AAC case is now directly given by
2626                                the user in the edition settings structure
2627                                If the bitrate given by the user is irrelevant or undefined
2628                                (the MCS minimum and maximum audio bitrate are used),
2629                                the output audio bitrate is hard coded according to the output
2630                                audio sampling frequency*/
2631
2632                                /*Check if the audio bitrate is correctly defined*/
2633
2634                                /*Mono
2635                                MCS values for AAC Mono are min: 16kbps and max: 192 kbps*/
2636                                if( xVSS_context->pSettings->xVSS.outputAudioBitrate
2637                                    >= M4VIDEOEDITING_k16_KBPS
2638                                    && xVSS_context->pSettings->
2639                                    xVSS.outputAudioBitrate
2640                                    <= M4VIDEOEDITING_k192_KBPS
2641                                    && xVSS_context->pSettings->xVSS.bAudioMono
2642                                    == M4OSA_TRUE )
2643                                {
2644                                    pParams->OutputAudioBitrate =
2645                                        xVSS_context->pSettings->
2646                                        xVSS.outputAudioBitrate;
2647                                }
2648                                /*Stereo
2649                                MCS values for AAC Mono are min: 32kbps and max: 192 kbps*/
2650                                else if( xVSS_context->pSettings->
2651                                    xVSS.outputAudioBitrate
2652                                    >= M4VIDEOEDITING_k32_KBPS
2653                                    && xVSS_context->pSettings->
2654                                    xVSS.outputAudioBitrate
2655                                    <= M4VIDEOEDITING_k192_KBPS
2656                                    && xVSS_context->pSettings->xVSS.bAudioMono
2657                                    == M4OSA_FALSE )
2658                                {
2659                                    pParams->OutputAudioBitrate =
2660                                        xVSS_context->pSettings->
2661                                        xVSS.outputAudioBitrate;
2662                                }
2663
2664                                /*The audio bitrate is hard coded according to the output audio
2665                                 sampling frequency*/
2666                                else
2667                                {
2668                                    switch( xVSS_context->pSettings->
2669                                        xVSS.outputAudioSamplFreq )
2670                                    {
2671                                        case M4VIDEOEDITING_k16000_ASF:
2672                                            pParams->OutputAudioBitrate =
2673                                                M4VIDEOEDITING_k24_KBPS;
2674                                            break;
2675
2676                                        case M4VIDEOEDITING_k22050_ASF:
2677                                        case M4VIDEOEDITING_k24000_ASF:
2678                                            pParams->OutputAudioBitrate =
2679                                                M4VIDEOEDITING_k32_KBPS;
2680                                            break;
2681
2682                                        case M4VIDEOEDITING_k32000_ASF:
2683                                            pParams->OutputAudioBitrate =
2684                                                M4VIDEOEDITING_k48_KBPS;
2685                                            break;
2686
2687                                        case M4VIDEOEDITING_k44100_ASF:
2688                                        case M4VIDEOEDITING_k48000_ASF:
2689                                            pParams->OutputAudioBitrate =
2690                                                M4VIDEOEDITING_k64_KBPS;
2691                                            break;
2692
2693                                        default:
2694                                            pParams->OutputAudioBitrate =
2695                                                M4VIDEOEDITING_k64_KBPS;
2696                                            break;
2697                                    }
2698
2699                                    if( xVSS_context->pSettings->xVSS.bAudioMono
2700                                        == M4OSA_FALSE )
2701                                    {
2702                                        /* Output bitrate have to be doubled */
2703                                        pParams->OutputAudioBitrate +=
2704                                            pParams->OutputAudioBitrate;
2705                                    }
2706                                }
2707
2708                                pParams->bAudioMono =
2709                                    xVSS_context->pSettings->xVSS.bAudioMono;
2710
2711                                if( xVSS_context->pSettings->
2712                                    xVSS.outputAudioSamplFreq
2713                                    == M4VIDEOEDITING_k8000_ASF )
2714                                {
2715                                    /* Prevent from unallowed sampling frequencies */
2716                                    pParams->OutputAudioSamplingFrequency =
2717                                        M4VIDEOEDITING_kDefault_ASF;
2718                                }
2719                                else
2720                                {
2721                                    pParams->OutputAudioSamplingFrequency =
2722                                        xVSS_context->pSettings->
2723                                        xVSS.outputAudioSamplFreq;
2724                                }
2725                                break;
2726                            }
2727
2728                        default: /* Should not happen !! */
2729                            pParams->OutputAudioFormat = M4VIDEOEDITING_kAMR_NB;
2730                            pParams->OutputAudioBitrate =
2731                                M4VIDEOEDITING_k12_2_KBPS;
2732                            pParams->bAudioMono = M4OSA_TRUE;
2733                            pParams->OutputAudioSamplingFrequency =
2734                                M4VIDEOEDITING_kDefault_ASF;
2735                            break;
2736                        }
2737                }
2738                else
2739                {
2740                    pParams->OutputAudioFormat = M4VIDEOEDITING_kNullAudio;
2741                }
2742
2743                /**
2744                * UTF conversion: convert into the customer format, before being used*/
2745                pDecodedPath = xVSS_context->pSettings->pClipList[i]->pFile;
2746                length = strlen(pDecodedPath);
2747
2748                if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
2749                    != M4OSA_NULL && xVSS_context->
2750                    UTFConversionContext.pTempOutConversionBuffer
2751                    != M4OSA_NULL )
2752                {
2753                    err = M4xVSS_internalConvertFromUTF8(xVSS_context,
2754                        (M4OSA_Void *)xVSS_context->pSettings->
2755                        pClipList[i]->pFile,
2756                        (M4OSA_Void *)xVSS_context->
2757                        UTFConversionContext.pTempOutConversionBuffer,
2758                        &length);
2759
2760                    if( err != M4NO_ERROR )
2761                    {
2762                        M4OSA_TRACE1_1(
2763                            "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
2764                            err);
2765                        /* Free Send command */
2766                        M4xVSS_freeCommand(xVSS_context);
2767                        return err;
2768                    }
2769                    pDecodedPath = xVSS_context->
2770                        UTFConversionContext.pTempOutConversionBuffer;
2771                }
2772
2773                /**
2774                * End of the UTF conversion, use the converted file path*/
2775                pParams->pFileIn =
2776                    (M4OSA_Void *)M4OSA_32bitAlignedMalloc((length + 1), M4VS,
2777                    (M4OSA_Char *)"MCS 3GP Params: file in");
2778
2779                if( pParams->pFileIn == M4OSA_NULL )
2780                {
2781                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
2782                    /*FB: to avoid leaks when there is an error in the send command*/
2783                    /* Free Send command */
2784                    M4xVSS_freeCommand(xVSS_context);
2785                    /**/
2786                    return M4ERR_ALLOC;
2787                }
2788                memcpy((void *)pParams->pFileIn, (void *)pDecodedPath,
2789                    (length + 1)); /* Copy input file path */
2790
2791                /**
2792                * UTF conversion: convert into the customer format, before being used*/
2793                pDecodedPath = out_3gp;
2794                length = strlen(pDecodedPath);
2795
2796                if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
2797                    != M4OSA_NULL && xVSS_context->
2798                    UTFConversionContext.pTempOutConversionBuffer
2799                    != M4OSA_NULL )
2800                {
2801                    err = M4xVSS_internalConvertFromUTF8(xVSS_context,
2802                        (M4OSA_Void *)out_3gp, (M4OSA_Void *)xVSS_context->
2803                        UTFConversionContext.pTempOutConversionBuffer,
2804                        &length);
2805
2806                    if( err != M4NO_ERROR )
2807                    {
2808                        M4OSA_TRACE1_1(
2809                            "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
2810                            err);
2811                        /* Free Send command */
2812                        M4xVSS_freeCommand(xVSS_context);
2813                        return err;
2814                    }
2815                    pDecodedPath = xVSS_context->
2816                        UTFConversionContext.pTempOutConversionBuffer;
2817                }
2818
2819                /**
2820                * End of the UTF conversion, use the converted file path*/
2821                pParams->pFileOut =
2822                    (M4OSA_Void *)M4OSA_32bitAlignedMalloc((length + 1), M4VS,
2823                    (M4OSA_Char *)"MCS 3GP Params: file out");
2824
2825                if( pParams->pFileOut == M4OSA_NULL )
2826                {
2827                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
2828                    /*FB: to avoid leaks when there is an error in the send command*/
2829                    /* Free Send command */
2830                    M4xVSS_freeCommand(xVSS_context);
2831                    /**/
2832                    return M4ERR_ALLOC;
2833                }
2834                memcpy((void *)pParams->pFileOut, (void *)pDecodedPath,
2835                    (length + 1)); /* Copy output file path */
2836
2837#ifdef M4xVSS_RESERVED_MOOV_DISK_SPACE
2838                /**
2839                * UTF conversion: convert into the customer format, before being used*/
2840
2841                pDecodedPath = out_3gp_tmp;
2842                length = strlen(pDecodedPath);
2843
2844                if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
2845                    != M4OSA_NULL && xVSS_context->
2846                    UTFConversionContext.pTempOutConversionBuffer
2847                    != M4OSA_NULL )
2848                {
2849                    err = M4xVSS_internalConvertFromUTF8(xVSS_context,
2850                        (M4OSA_Void *)out_3gp_tmp,
2851                        (M4OSA_Void *)xVSS_context->
2852                        UTFConversionContext.pTempOutConversionBuffer,
2853                        &length);
2854
2855                    if( err != M4NO_ERROR )
2856                    {
2857                        M4OSA_TRACE1_1(
2858                            "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
2859                            err);
2860                        /* Free Send command */
2861                        M4xVSS_freeCommand(xVSS_context);
2862                        return err;
2863                    }
2864                    pDecodedPath = xVSS_context->
2865                        UTFConversionContext.pTempOutConversionBuffer;
2866                }
2867
2868                /**
2869                * End of the UTF conversion, use the converted file path*/
2870                pParams->pFileTemp =
2871                    (M4OSA_Void *)M4OSA_32bitAlignedMalloc((length + 1), M4VS,
2872                    (M4OSA_Char *)"MCS 3GP Params: file temp");
2873
2874                if( pParams->pFileTemp == M4OSA_NULL )
2875                {
2876                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
2877                    /*FB: to avoid leaks when there is an error in the send command*/
2878                    /* Free Send command */
2879                    M4xVSS_freeCommand(xVSS_context);
2880                    /**/
2881                    return M4ERR_ALLOC;
2882                }
2883                memcpy((void *)pParams->pFileTemp, (void *)pDecodedPath,
2884                    (length + 1)); /* Copy temporary file path */
2885
2886#else
2887
2888                pParams->pFileTemp = M4OSA_NULL;
2889
2890#endif /*M4xVSS_RESERVED_MOOV_DISK_SPACE*/
2891
2892                /*FB 2008/10/20 keep media aspect ratio, add media rendering parameter*/
2893
2894                if( xVSS_context->pSettings->pClipList[i]->xVSS.MediaRendering
2895                    == M4xVSS_kCropping
2896                    || xVSS_context->pSettings->pClipList[i]->xVSS.
2897                    MediaRendering == M4xVSS_kBlackBorders
2898                    || xVSS_context->pSettings->pClipList[i]->xVSS.
2899                    MediaRendering == M4xVSS_kResizing )
2900                {
2901                    pParams->MediaRendering =
2902                        xVSS_context->pSettings->pClipList[i]->xVSS.
2903                        MediaRendering;
2904                }
2905
2906                /*FB: transcoding per parts*/
2907                pParams->BeginCutTime =
2908                    xVSS_context->pSettings->pClipList[i]->uiBeginCutTime;
2909                pParams->EndCutTime =
2910                    xVSS_context->pSettings->pClipList[i]->uiEndCutTime;
2911
2912                pParams->pNext = M4OSA_NULL;
2913                pParams->isBGM = M4OSA_FALSE;
2914                pParams->isCreated = M4OSA_FALSE;
2915                xVSS_context->nbStepTotal++;
2916                bIsTranscoding = M4OSA_TRUE;
2917
2918replace3GP_3GP:
2919                /* Update total duration */
2920                totalDuration +=
2921                    xVSS_context->pSettings->pClipList[i]->uiEndCutTime
2922                    - xVSS_context->pSettings->pClipList[i]->uiBeginCutTime;
2923
2924                /* Replacing in VSS structure the original 3GP file by the transcoded 3GP file */
2925                xVSS_context->pSettings->pClipList[i]->FileType =
2926                    M4VIDEOEDITING_kFileType_3GPP;
2927
2928                if( xVSS_context->pSettings->pClipList[i]->pFile != M4OSA_NULL )
2929                {
2930                    free(xVSS_context->pSettings->pClipList[i]->pFile);
2931                    xVSS_context->pSettings->pClipList[i]->pFile = M4OSA_NULL;
2932                }
2933
2934                /**
2935                * UTF conversion: convert into the customer format, before being used*/
2936                pDecodedPath = pParams->pFileOut;
2937
2938                if( xVSS_context->UTFConversionContext.pConvToUTF8Fct
2939                    != M4OSA_NULL && xVSS_context->
2940                    UTFConversionContext.pTempOutConversionBuffer
2941                    != M4OSA_NULL )
2942                {
2943                    err = M4xVSS_internalConvertToUTF8(xVSS_context,
2944                        (M4OSA_Void *)pParams->pFileOut,
2945                        (M4OSA_Void *)xVSS_context->
2946                        UTFConversionContext.pTempOutConversionBuffer,
2947                        &length);
2948
2949                    if( err != M4NO_ERROR )
2950                    {
2951                        M4OSA_TRACE1_1(
2952                            "M4xVSS_SendCommand: M4xVSS_internalConvertToUTF8 returns err: 0x%x",
2953                            err);
2954                        /* Free Send command */
2955                        M4xVSS_freeCommand(xVSS_context);
2956                        return err;
2957                    }
2958                    pDecodedPath = xVSS_context->
2959                        UTFConversionContext.pTempOutConversionBuffer;
2960                }
2961                else
2962                {
2963                    length = strlen(pDecodedPath);
2964                }
2965                /**
2966                * End of the UTF conversion, use the converted file path*/
2967                xVSS_context->pSettings->pClipList[i]->pFile = M4OSA_32bitAlignedMalloc(
2968                    (length + 1),
2969                    M4VS, (M4OSA_Char *)"xVSS file path of 3gp to 3gp");
2970
2971                if( xVSS_context->pSettings->pClipList[i]->pFile == M4OSA_NULL )
2972                {
2973                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
2974                    /*FB: to avoid leaks when there is an error in the send command*/
2975                    /* Free Send command */
2976                    M4xVSS_freeCommand(xVSS_context);
2977                    /**/
2978                    return M4ERR_ALLOC;
2979                }
2980                memcpy((void *)xVSS_context->pSettings->pClipList[i]->pFile,
2981                    (void *)pDecodedPath, (length + 1));
2982                /*FB: add file path size because of UTF 16 conversion*/
2983                xVSS_context->pSettings->pClipList[i]->filePathSize = length+1;
2984
2985                /* We define master clip as first 3GP input clip */
2986                /*if(xVSS_context->pSettings->uiMasterClip == 0 && fileProperties.
2987                AudioStreamType != M4VIDEOEDITING_kNoneAudio)
2988                {
2989                xVSS_context->pSettings->uiMasterClip = i;
2990                }*/
2991            }
2992            else
2993            {
2994                /* Update total duration */
2995                totalDuration +=
2996                    xVSS_context->pSettings->pClipList[i]->uiEndCutTime
2997                    - xVSS_context->pSettings->pClipList[i]->uiBeginCutTime;
2998            }
2999            /* We define master clip as first 3GP input clip */
3000            if( masterClip == -1
3001                && fileProperties.AudioStreamType != M4VIDEOEDITING_kNoneAudio )
3002            {
3003                masterClip = i;
3004                xVSS_context->pSettings->uiMasterClip = i;
3005            }
3006
3007        }
3008        /**************************
3009        Other input file type case
3010        ***************************/
3011        else
3012        {
3013            M4OSA_TRACE1_0("Bad file type as input clip");
3014            /*FB: to avoid leaks when there is an error in the send command*/
3015            /* Free Send command */
3016            M4xVSS_freeCommand(xVSS_context);
3017            /**/
3018            return M4ERR_PARAMETER;
3019        }
3020    }
3021
3022    /*********************************************************
3023    * Parse all effects to make some adjustment for framing, *
3024    * text and to transform relative time into absolute time *
3025    **********************************************************/
3026    for ( j = 0; j < xVSS_context->pSettings->nbEffects; j++ )
3027    {
3028        /* Copy effect to "local" structure */
3029        memcpy((void *) &(xVSS_context->pSettings->Effects[j]),
3030            (void *) &(pSettings->Effects[j]),
3031            sizeof(M4VSS3GPP_EffectSettings));
3032
3033        /* Prevent from bad initializing of effect percentage time */
3034        if( xVSS_context->pSettings->Effects[j].xVSS.uiDurationPercent > 100
3035            || xVSS_context->pSettings->Effects[j].xVSS.uiStartPercent > 100 )
3036        {
3037            /* These percentage time have probably not been initialized */
3038            /* Let's not use them by setting them to 0 */
3039            xVSS_context->pSettings->Effects[j].xVSS.uiDurationPercent = 0;
3040            xVSS_context->pSettings->Effects[j].xVSS.uiStartPercent = 0;
3041        }
3042
3043        /* If we have percentage information let's use it... Otherwise, we use absolute time. */
3044        if( xVSS_context->pSettings->Effects[j].xVSS.uiDurationPercent != 0 )
3045        {
3046            xVSS_context->pSettings->
3047                Effects[j].uiStartTime = (M4OSA_UInt32)(totalDuration
3048                * xVSS_context->pSettings->Effects[j].xVSS.uiStartPercent
3049                / 100);
3050            /* The percentage of effect duration is based on the duration of the clip -
3051            start time */
3052            xVSS_context->pSettings->
3053                Effects[j].uiDuration = (M4OSA_UInt32)(totalDuration
3054                * xVSS_context->pSettings->Effects[j].xVSS.uiDurationPercent
3055                / 100);
3056        }
3057
3058        /* If there is a framing effect, we need to allocate framing effect structure */
3059        if( xVSS_context->pSettings->Effects[j].VideoEffectType
3060            == M4xVSS_kVideoEffectType_Framing )
3061        {
3062#ifdef DECODE_GIF_ON_SAVING
3063
3064            M4xVSS_FramingContext *framingCtx;
3065            /*UTF conversion support*/
3066            M4OSA_Void *pDecodedPath = M4OSA_NULL;
3067
3068#else
3069
3070            M4xVSS_FramingStruct *framingCtx;
3071
3072#endif /*DECODE_GIF_ON_SAVING*/
3073
3074            M4OSA_Char *pExt2 = M4OSA_NULL;
3075            M4VIFI_ImagePlane *pPlane =
3076                xVSS_context->pSettings->Effects[j].xVSS.pFramingBuffer;
3077            M4OSA_Int32 result1, result2;
3078
3079            /* Copy framing file path */
3080            if( pSettings->Effects[j].xVSS.pFramingFilePath != M4OSA_NULL )
3081            {
3082                xVSS_context->pSettings->
3083                    Effects[j].xVSS.pFramingFilePath = M4OSA_32bitAlignedMalloc(
3084                    strlen(pSettings->Effects[j].xVSS.pFramingFilePath)
3085                    + 1, M4VS, (M4OSA_Char *)"Local Framing file path");
3086
3087                if( xVSS_context->pSettings->Effects[j].xVSS.pFramingFilePath
3088                    == M4OSA_NULL )
3089                {
3090                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3091                    /*FB: to avoid leaks when there is an error in the send command*/
3092                    /* Free Send command */
3093                    M4xVSS_freeCommand(xVSS_context);
3094                    /**/
3095                    return M4ERR_ALLOC;
3096                }
3097                memcpy((void *)xVSS_context->pSettings->
3098                    Effects[j].xVSS.pFramingFilePath,
3099                    (void *)pSettings->
3100                    Effects[j].xVSS.pFramingFilePath, strlen(
3101                    pSettings->Effects[j].xVSS.pFramingFilePath) + 1);
3102
3103                pExt2 =
3104                    xVSS_context->pSettings->Effects[j].xVSS.pFramingFilePath;
3105            }
3106
3107#ifdef DECODE_GIF_ON_SAVING
3108
3109            framingCtx = (M4xVSS_FramingContext
3110                *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingContext),
3111                M4VS, (M4OSA_Char *)"Context of the framing effect");
3112
3113            if( framingCtx == M4OSA_NULL )
3114            {
3115                M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3116                /*FB: to avoid leaks when there is an error in the send command*/
3117                /* Free Send command */
3118                M4xVSS_freeCommand(xVSS_context);
3119                /**/
3120                return M4ERR_ALLOC;
3121            }
3122            framingCtx->aFramingCtx = M4OSA_NULL;
3123            framingCtx->aFramingCtx_last = M4OSA_NULL;
3124            framingCtx->pSPSContext = M4OSA_NULL;
3125            framingCtx->outputVideoSize =
3126                xVSS_context->pSettings->xVSS.outputVideoSize;
3127            framingCtx->topleft_x =
3128                xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3129            framingCtx->topleft_y =
3130                xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3131            framingCtx->bEffectResize =
3132                xVSS_context->pSettings->Effects[j].xVSS.bResize;
3133            framingCtx->pEffectFilePath =
3134                xVSS_context->pSettings->Effects[j].xVSS.pFramingFilePath;
3135            framingCtx->pFileReadPtr = xVSS_context->pFileReadPtr;
3136            framingCtx->pFileWritePtr = xVSS_context->pFileWritePtr;
3137            framingCtx->effectDuration =
3138                xVSS_context->pSettings->Effects[j].uiDuration;
3139            framingCtx->b_IsFileGif = M4OSA_FALSE;
3140            framingCtx->alphaBlendingStruct = M4OSA_NULL;
3141            framingCtx->b_animated = M4OSA_FALSE;
3142
3143            /* Output ratio for the effect is stored in uiFiftiesOutFrameRate parameters of the
3144            extended xVSS effects structure */
3145            if( xVSS_context->pSettings->Effects[j].xVSS.uiFiftiesOutFrameRate
3146                != 0 )
3147            {
3148                framingCtx->frameDurationRatio =
3149                    (M4OSA_Float)(( xVSS_context->pSettings->
3150                    Effects[j].xVSS.uiFiftiesOutFrameRate) / 1000.0);
3151            }
3152            else
3153            {
3154                framingCtx->frameDurationRatio = 1.0;
3155            }
3156
3157            /*Alpha blending*/
3158            /*Check if the alpha blending parameters are corrects*/
3159            if( pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime > 100 )
3160            {
3161                pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime = 0;
3162            }
3163
3164            if( pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime > 100 )
3165            {
3166                pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime = 0;
3167            }
3168
3169            if( pSettings->Effects[j].xVSS.uialphaBlendingEnd > 100 )
3170            {
3171                pSettings->Effects[j].xVSS.uialphaBlendingEnd = 100;
3172            }
3173
3174            if( pSettings->Effects[j].xVSS.uialphaBlendingMiddle > 100 )
3175            {
3176                pSettings->Effects[j].xVSS.uialphaBlendingMiddle = 100;
3177            }
3178
3179            if( pSettings->Effects[j].xVSS.uialphaBlendingStart > 100 )
3180            {
3181                pSettings->Effects[j].xVSS.uialphaBlendingStart = 100;
3182            }
3183
3184            if( pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime > 0
3185                || pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime > 0 )
3186            {
3187                /*Allocate the alpha blending structure*/
3188                framingCtx->alphaBlendingStruct =
3189                    (M4xVSS_internalEffectsAlphaBlending *)M4OSA_32bitAlignedMalloc(
3190                    sizeof(M4xVSS_internalEffectsAlphaBlending),
3191                    M4VS, (M4OSA_Char *)"alpha blending structure");
3192
3193                if( framingCtx->alphaBlendingStruct == M4OSA_NULL )
3194                {
3195                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3196                    M4xVSS_freeCommand(xVSS_context);
3197                    return M4ERR_ALLOC;
3198                }
3199                /*Fill the alpha blending structure*/
3200                framingCtx->alphaBlendingStruct->m_fadeInTime =
3201                    pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime;
3202                framingCtx->alphaBlendingStruct->m_fadeOutTime =
3203                    pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime;
3204                framingCtx->alphaBlendingStruct->m_end =
3205                    pSettings->Effects[j].xVSS.uialphaBlendingEnd;
3206                framingCtx->alphaBlendingStruct->m_middle =
3207                    pSettings->Effects[j].xVSS.uialphaBlendingMiddle;
3208                framingCtx->alphaBlendingStruct->m_start =
3209                    pSettings->Effects[j].xVSS.uialphaBlendingStart;
3210
3211                if( pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime
3212                    + pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime
3213                        > 100 )
3214                {
3215                    framingCtx->alphaBlendingStruct->m_fadeOutTime =
3216                        100 - framingCtx->alphaBlendingStruct->m_fadeInTime;
3217                }
3218            }
3219
3220            /**
3221            * UTF conversion: convert into the customer format, before being used*/
3222            pDecodedPath =
3223                xVSS_context->pSettings->Effects[j].xVSS.pFramingFilePath;
3224            length = strlen(pDecodedPath);
3225
3226            if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
3227                != M4OSA_NULL && xVSS_context->
3228                UTFConversionContext.pTempOutConversionBuffer
3229                != M4OSA_NULL )
3230            {
3231                err = M4xVSS_internalConvertFromUTF8(xVSS_context,
3232                    (M4OSA_Void *)xVSS_context->pSettings->
3233                    Effects[j].xVSS.pFramingFilePath,
3234                    (M4OSA_Void *)xVSS_context->
3235                    UTFConversionContext.pTempOutConversionBuffer,
3236                    &length);
3237
3238                if( err != M4NO_ERROR )
3239                {
3240                    M4OSA_TRACE1_1(
3241                        "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
3242                        err);
3243                    /* Free Send command */
3244                    M4xVSS_freeCommand(xVSS_context);
3245                    return err;
3246                }
3247                pDecodedPath =
3248                    xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
3249            }
3250
3251            /**
3252            * End of the UTF conversion, use the converted file path*/
3253            framingCtx->pEffectFilePath = M4OSA_32bitAlignedMalloc(length + 1, M4VS,
3254                (M4OSA_Char *)"Local Framing file path");
3255
3256            if( framingCtx->pEffectFilePath == M4OSA_NULL )
3257            {
3258                M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3259                /*FB: to avoid leaks when there is an error in the send command*/
3260                /* Free Send command */
3261                M4xVSS_freeCommand(xVSS_context);
3262                /**/
3263                return M4ERR_ALLOC;
3264            }
3265            memcpy((void *)framingCtx->pEffectFilePath,
3266                (void *)pDecodedPath, length + 1);
3267
3268            /* Save framing structure associated with corresponding effect */
3269            xVSS_context->pSettings->Effects[j].pExtVideoEffectFctCtxt =
3270                framingCtx;
3271
3272#else
3273
3274            framingCtx = (M4xVSS_FramingStruct
3275                *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingStruct),
3276                M4VS, (M4OSA_Char *)"Context of the framing effect");
3277
3278            if( framingCtx == M4OSA_NULL )
3279            {
3280                M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3281                /*FB: to avoid leaks when there is an error in the send command*/
3282                /* Free Send command */
3283                M4xVSS_freeCommand(xVSS_context);
3284                /**/
3285                return M4ERR_ALLOC;
3286            }
3287
3288            framingCtx->topleft_x =
3289                xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3290            framingCtx->topleft_y =
3291                xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3292
3293            /* BugFix 1.2.0: Leak when decoding error */
3294            framingCtx->FramingRgb = M4OSA_NULL;
3295            framingCtx->FramingYuv = M4OSA_NULL;
3296            framingCtx->pNext = framingCtx;
3297            /* Save framing structure associated with corresponding effect */
3298            xVSS_context->pSettings->Effects[j].pExtVideoEffectFctCtxt =
3299                framingCtx;
3300
3301#endif /*DECODE_GIF_ON_SAVING*/
3302
3303            if( pExt2 != M4OSA_NULL )
3304            {
3305                /* Decode the image associated to the effect, and fill framing structure */
3306                pExt2 += (strlen((const char *)pExt2) - 4);
3307
3308                result1 = strcmp((const char *)pExt2,(const char *)".rgb");
3309                result2 = strcmp((const char *)pExt2,(const char *)".RGB");
3310
3311                if( 0 == result1 || 0 == result2 )
3312                {
3313#ifdef DECODE_GIF_ON_SAVING
3314
3315                    framingCtx->aFramingCtx =
3316                        (M4xVSS_FramingStruct
3317                        *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingStruct),
3318                        M4VS,
3319                        (M4OSA_Char
3320                        *)
3321                        "M4xVSS_internalDecodeGIF: Context of the framing effect");
3322
3323                    if( framingCtx->aFramingCtx == M4OSA_NULL )
3324                    {
3325                        M4OSA_TRACE1_0(
3326                            "Allocation error in M4xVSS_SendCommand");
3327                        /* TODO: Translate error code of SPS to an xVSS error code */
3328                        M4xVSS_freeCommand(xVSS_context);
3329                        return M4ERR_ALLOC;
3330                    }
3331                    framingCtx->aFramingCtx->pCurrent =
3332                        M4OSA_NULL; /* Only used by the first element of the chain */
3333                    framingCtx->aFramingCtx->previousClipTime = -1;
3334                    framingCtx->aFramingCtx->FramingYuv = M4OSA_NULL;
3335                    framingCtx->aFramingCtx->FramingRgb = M4OSA_NULL;
3336                    framingCtx->aFramingCtx->topleft_x =
3337                        xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3338                    framingCtx->aFramingCtx->topleft_y =
3339                        xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3340                    /*To support ARGB8888 : get the width and height */
3341
3342                    framingCtx->aFramingCtx->width =
3343                        xVSS_context->pSettings->Effects[j].xVSS.width;
3344                    framingCtx->aFramingCtx->height =
3345                        xVSS_context->pSettings->Effects[j].xVSS.height;
3346                    M4OSA_TRACE1_1("FRAMMING BEFORE M4xVSS_SendCommand  %d",
3347                        framingCtx->aFramingCtx->width);
3348                    M4OSA_TRACE1_1("FRAMMING BEFORE M4xVSS_SendCommand  %d",
3349                        framingCtx->aFramingCtx->height);
3350
3351#endif
3352
3353                    err = M4xVSS_internalConvertARGB888toYUV420_FrammingEffect(
3354                        xVSS_context,
3355                        &(xVSS_context->pSettings->Effects[j]),
3356                        framingCtx->aFramingCtx,xVSS_context->pSettings->xVSS.outputVideoSize);
3357                    M4OSA_TRACE3_1("FRAMING WIDTH BEFORE M4xVSS_SendCommand  %d",
3358                        framingCtx->aFramingCtx->width);
3359                    M4OSA_TRACE3_1("FRAMING HEIGHT BEFORE M4xVSS_SendCommand  %d",
3360                        framingCtx->aFramingCtx->height);
3361
3362                    if( err != M4NO_ERROR )
3363                    {
3364                        M4OSA_TRACE1_1(
3365                            "M4xVSS_SendCommand: M4xVSS_internalDecodePNG returned 0x%x",
3366                            err);
3367                        /* TODO: Translate error code of SPS to an xVSS error code */
3368                        M4xVSS_freeCommand(xVSS_context);
3369                        return err;
3370                    }
3371                }
3372                else
3373                {
3374                    M4OSA_TRACE1_1(
3375                        "M4xVSS_SendCommand: Not supported still picture format 0x%x",
3376                        err);
3377                    /*FB: to avoid leaks when there is an error in the send command*/
3378                    /* Free Send command */
3379                    M4xVSS_freeCommand(xVSS_context);
3380                    /**/
3381                    return M4ERR_PARAMETER;
3382                }
3383            }
3384            else if( pPlane != M4OSA_NULL )
3385            {
3386#ifdef DECODE_GIF_ON_SAVING
3387
3388                framingCtx->aFramingCtx = (M4xVSS_FramingStruct
3389                    *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingStruct),
3390                    M4VS, (M4OSA_Char *)"Context of the framing effect");
3391
3392                if( framingCtx->aFramingCtx == M4OSA_NULL )
3393                {
3394                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3395                    /*FB: to avoid leaks when there is an error in the send command*/
3396                    /* Free Send command */
3397                    M4xVSS_freeCommand(xVSS_context);
3398                    /**/
3399                    return M4ERR_ALLOC;
3400                }
3401
3402                framingCtx->aFramingCtx->topleft_x =
3403                    xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3404                framingCtx->aFramingCtx->topleft_y =
3405                    xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3406
3407                /* BugFix 1.2.0: Leak when decoding error */
3408                framingCtx->aFramingCtx->FramingRgb = M4OSA_NULL;
3409                framingCtx->aFramingCtx->FramingYuv = M4OSA_NULL;
3410                framingCtx->aFramingCtx->pNext = framingCtx->aFramingCtx;
3411                framingCtx->aFramingCtx->pCurrent = framingCtx->aFramingCtx;
3412                framingCtx->aFramingCtx->duration = 0;
3413                framingCtx->aFramingCtx->previousClipTime = -1;
3414                framingCtx->aFramingCtx->FramingRgb =
3415                    xVSS_context->pSettings->Effects[j].xVSS.pFramingBuffer;
3416                /* Force input RGB buffer to even size to avoid errors in YUV conversion */
3417                framingCtx->aFramingCtx->FramingRgb->u_width =
3418                    framingCtx->aFramingCtx->FramingRgb->u_width & ~1;
3419                framingCtx->aFramingCtx->FramingRgb->u_height =
3420                    framingCtx->aFramingCtx->FramingRgb->u_height & ~1;
3421                /* Input RGB plane is provided, let's convert it to YUV420, and update framing
3422                structure  */
3423                err = M4xVSS_internalConvertRGBtoYUV(framingCtx->aFramingCtx);
3424
3425#else
3426
3427                framingCtx->FramingRgb =
3428                    xVSS_context->pSettings->Effects[j].xVSS.pFramingBuffer;
3429                /* Force input RGB buffer to even size to avoid errors in YUV conversion */
3430                framingCtx->FramingRgb.u_width =
3431                    framingCtx->FramingRgb.u_width & ~1;
3432                framingCtx->FramingRgb.u_height =
3433                    framingCtx->FramingRgb.u_height & ~1;
3434                /* Input RGB plane is provided, let's convert it to YUV420, and update framing
3435                 structure  */
3436                err = M4xVSS_internalConvertRGBtoYUV(framingCtx);
3437
3438#endif
3439
3440                if( err != M4NO_ERROR )
3441                {
3442                    M4OSA_TRACE1_1(
3443                        "M4xVSS_sendCommand: error when converting RGB to YUV: 0w%x",
3444                        err);
3445                    /*FB: to avoid leaks when there is an error in the send command*/
3446                    /* Free Send command */
3447                    M4xVSS_freeCommand(xVSS_context);
3448                    /**/
3449                    return err;
3450                }
3451            }
3452            else
3453            {
3454                M4OSA_TRACE1_0(
3455                    "M4xVSS_sendCommand: No input image/plane provided for framing effect.");
3456                /*FB: to avoid leaks when there is an error in the send command*/
3457                /* Free Send command */
3458                M4xVSS_freeCommand(xVSS_context);
3459                /**/
3460                return M4ERR_PARAMETER;
3461            }
3462        }
3463        /* CR: Add text handling with external text interface */
3464        /* If effect type is text, we call external text function to get RGB 565 buffer */
3465        if( xVSS_context->pSettings->Effects[j].VideoEffectType
3466            == M4xVSS_kVideoEffectType_Text )
3467        {
3468            /* Call the font engine function pointer to get RGB565 buffer */
3469            /* We transform text effect into framing effect from buffer */
3470            if( xVSS_context->pSettings->xVSS.pTextRenderingFct != M4OSA_NULL )
3471            {
3472                /*FB: add UTF convertion for text buffer*/
3473                M4OSA_Void *pDecodedPath = M4OSA_NULL;
3474#ifdef DECODE_GIF_ON_SAVING
3475
3476                M4xVSS_FramingContext *framingCtx;
3477
3478#else
3479
3480                M4xVSS_FramingStruct *framingCtx;
3481
3482#endif /*DECODE_GIF_ON_SAVING*/
3483
3484#ifdef DECODE_GIF_ON_SAVING
3485
3486                framingCtx = (M4xVSS_FramingContext
3487                    *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingContext),
3488                    M4VS, (M4OSA_Char *)"Context of the framing effect");
3489
3490                if( framingCtx == M4OSA_NULL )
3491                {
3492                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3493                    /*FB: to avoid leaks when there is an error in the send command*/
3494                    /* Free Send command */
3495                    M4xVSS_freeCommand(xVSS_context);
3496                    /**/
3497                    return M4ERR_ALLOC;
3498                }
3499                framingCtx->aFramingCtx = M4OSA_NULL;
3500                framingCtx->aFramingCtx_last = M4OSA_NULL;
3501                framingCtx->pSPSContext = M4OSA_NULL;
3502                framingCtx->outputVideoSize =
3503                    xVSS_context->pSettings->xVSS.outputVideoSize;
3504                framingCtx->topleft_x =
3505                    xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3506                framingCtx->topleft_y =
3507                    xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3508                framingCtx->bEffectResize =
3509                    xVSS_context->pSettings->Effects[j].xVSS.bResize;
3510                framingCtx->pEffectFilePath =
3511                    xVSS_context->pSettings->Effects[j].xVSS.pFramingFilePath;
3512                framingCtx->pFileReadPtr = xVSS_context->pFileReadPtr;
3513                framingCtx->pFileWritePtr = xVSS_context->pFileWritePtr;
3514                framingCtx->effectDuration =
3515                    xVSS_context->pSettings->Effects[j].uiDuration;
3516                framingCtx->b_IsFileGif = M4OSA_FALSE;
3517                framingCtx->b_animated = M4OSA_FALSE;
3518                framingCtx->alphaBlendingStruct = M4OSA_NULL;
3519
3520                /* Save framing structure associated with corresponding effect */
3521                xVSS_context->pSettings->Effects[j].pExtVideoEffectFctCtxt =
3522                    framingCtx;
3523
3524                framingCtx->aFramingCtx = (M4xVSS_FramingStruct
3525                    *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingStruct),
3526                    M4VS, (M4OSA_Char *)"Context of the framing effect");
3527
3528                if( framingCtx->aFramingCtx == M4OSA_NULL )
3529                {
3530                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3531                    /*FB: to avoid leaks when there is an error in the send command*/
3532                    /* Free Send command */
3533                    M4xVSS_freeCommand(xVSS_context);
3534                    /**/
3535                    return M4ERR_ALLOC;
3536                }
3537
3538                framingCtx->aFramingCtx->topleft_x =
3539                    xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3540                framingCtx->aFramingCtx->topleft_y =
3541                    xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3542
3543                /* BugFix 1.2.0: Leak when decoding error */
3544                framingCtx->aFramingCtx->FramingRgb = M4OSA_NULL;
3545                framingCtx->aFramingCtx->FramingYuv = M4OSA_NULL;
3546                framingCtx->aFramingCtx->pNext = framingCtx->aFramingCtx;
3547                framingCtx->aFramingCtx->pCurrent = framingCtx->aFramingCtx;
3548                framingCtx->aFramingCtx->duration = 0;
3549                framingCtx->aFramingCtx->previousClipTime = -1;
3550
3551                /*Alpha blending*/
3552                /*Check if the alpha blending parameters are corrects*/
3553                if( pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime > 100 )
3554                {
3555                    pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime = 0;
3556                }
3557
3558                if( pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime > 100 )
3559                {
3560                    pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime = 0;
3561                }
3562
3563                if( pSettings->Effects[j].xVSS.uialphaBlendingEnd > 100 )
3564                {
3565                    pSettings->Effects[j].xVSS.uialphaBlendingEnd = 100;
3566                }
3567
3568                if( pSettings->Effects[j].xVSS.uialphaBlendingMiddle > 100 )
3569                {
3570                    pSettings->Effects[j].xVSS.uialphaBlendingMiddle = 100;
3571                }
3572
3573                if( pSettings->Effects[j].xVSS.uialphaBlendingStart > 100 )
3574                {
3575                    pSettings->Effects[j].xVSS.uialphaBlendingStart = 100;
3576                }
3577
3578                if( pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime > 0
3579                    || pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime
3580                    > 0 )
3581                {
3582                    /*Allocate the alpha blending structure*/
3583                    framingCtx->alphaBlendingStruct =
3584                        (M4xVSS_internalEffectsAlphaBlending *)M4OSA_32bitAlignedMalloc(
3585                        sizeof(M4xVSS_internalEffectsAlphaBlending),
3586                        M4VS, (M4OSA_Char *)"alpha blending structure");
3587
3588                    if( framingCtx->alphaBlendingStruct == M4OSA_NULL )
3589                    {
3590                        M4OSA_TRACE1_0(
3591                            "Allocation error in M4xVSS_SendCommand");
3592                        M4xVSS_freeCommand(xVSS_context);
3593                        return M4ERR_ALLOC;
3594                    }
3595                    /*Fill the alpha blending structure*/
3596                    framingCtx->alphaBlendingStruct->m_fadeInTime =
3597                        pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime;
3598                    framingCtx->alphaBlendingStruct->m_fadeOutTime =
3599                        pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime;
3600                    framingCtx->alphaBlendingStruct->m_end =
3601                        pSettings->Effects[j].xVSS.uialphaBlendingEnd;
3602                    framingCtx->alphaBlendingStruct->m_middle =
3603                        pSettings->Effects[j].xVSS.uialphaBlendingMiddle;
3604                    framingCtx->alphaBlendingStruct->m_start =
3605                        pSettings->Effects[j].xVSS.uialphaBlendingStart;
3606
3607                    if( pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime
3608                        + pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime
3609                            > 100 )
3610                    {
3611                        framingCtx->alphaBlendingStruct->m_fadeOutTime =
3612                            100 - framingCtx->alphaBlendingStruct->m_fadeInTime;
3613                    }
3614                }
3615#else
3616
3617                framingCtx = (M4xVSS_FramingStruct
3618                    *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingStruct),
3619                    M4VS, (M4OSA_Char
3620                    *)"Context of the framing effect (for text)");
3621
3622                if( framingCtx == M4OSA_NULL )
3623                {
3624                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3625                    /*FB: to avoid leaks when there is an error in the send command*/
3626                    /* Free Send command */
3627                    M4xVSS_freeCommand(xVSS_context);
3628                    /**/
3629                    return M4ERR_ALLOC;
3630                }
3631
3632                framingCtx->topleft_x =
3633                    xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3634                framingCtx->topleft_y =
3635                    xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3636                framingCtx->FramingRgb = M4OSA_NULL;
3637
3638                /* BugFix 1.2.0: Leak when decoding error */
3639                framingCtx->FramingYuv = M4OSA_NULL;
3640                framingCtx->pNext = framingCtx;
3641
3642#endif
3643                /* Save framing structure associated with corresponding effect */
3644
3645                xVSS_context->pSettings->Effects[j].pExtVideoEffectFctCtxt =
3646                    framingCtx;
3647
3648                /* FB: changes for Video Artist: memcopy pTextBuffer so that it can be changed
3649                after a complete analysis*/
3650                if( pSettings->Effects[j].xVSS.pTextBuffer == M4OSA_NULL )
3651                {
3652                    M4OSA_TRACE1_0("M4xVSS_SendCommand: pTextBuffer is null");
3653                    M4xVSS_freeCommand(xVSS_context);
3654                    return M4ERR_PARAMETER;
3655                }
3656
3657                /*Convert text buffer into customer format before being used*/
3658                /**
3659                * UTF conversion: convert into the customer format, before being used*/
3660                pDecodedPath = pSettings->Effects[j].xVSS.pTextBuffer;
3661                xVSS_context->pSettings->Effects[j].xVSS.textBufferSize =
3662                    pSettings->Effects[j].xVSS.textBufferSize;
3663
3664                if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
3665                    != M4OSA_NULL && xVSS_context->
3666                    UTFConversionContext.pTempOutConversionBuffer
3667                    != M4OSA_NULL )
3668                {
3669                    err = M4xVSS_internalConvertFromUTF8(xVSS_context,
3670                        (M4OSA_Void *)pSettings->
3671                        Effects[j].xVSS.pTextBuffer,
3672                        (M4OSA_Void *)xVSS_context->
3673                        UTFConversionContext.pTempOutConversionBuffer,
3674                        &length);
3675
3676                    if( err != M4NO_ERROR )
3677                    {
3678                        M4OSA_TRACE1_1(
3679                            "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
3680                            err);
3681                        /* Free Send command */
3682                        M4xVSS_freeCommand(xVSS_context);
3683                        return err;
3684                    }
3685                    pDecodedPath = xVSS_context->
3686                        UTFConversionContext.pTempOutConversionBuffer;
3687                    xVSS_context->pSettings->Effects[j].xVSS.textBufferSize =
3688                        length;
3689                }
3690                /**
3691                * End of the UTF conversion, use the converted file path*/
3692
3693                xVSS_context->pSettings->
3694                    Effects[j].xVSS.pTextBuffer = M4OSA_32bitAlignedMalloc(
3695                    xVSS_context->pSettings->Effects[j].xVSS.textBufferSize + 1,
3696                    M4VS, (M4OSA_Char *)"Local text buffer effect");
3697
3698                //xVSS_context->pSettings->Effects[j].xVSS.pTextBuffer =
3699                // M4OSA_32bitAlignedMalloc(strlen(pSettings->Effects[j].xVSS.pTextBuffer)+1,
3700                // M4VS, "Local text buffer effect");
3701                if( xVSS_context->pSettings->Effects[j].xVSS.pTextBuffer
3702                    == M4OSA_NULL )
3703                {
3704                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3705                    /*FB: to avoid leaks when there is an error in the send command*/
3706                    /* Free Send command */
3707                    M4xVSS_freeCommand(xVSS_context);
3708                    /**/
3709                    return M4ERR_ALLOC;
3710                }
3711
3712                if( pSettings->Effects[j].xVSS.pTextBuffer != M4OSA_NULL )
3713                {
3714                    //memcpy((M4OSA_MemAddr8)xVSS_context->pSettings->Effects[j]
3715                    //.xVSS.pTextBuffer, (M4OSA_MemAddr8)pSettings->Effects[j].xVSS.pTextBuffer,
3716                    // strlen(pSettings->Effects[j].xVSS.pTextBuffer)+1);
3717                    memcpy((void *)xVSS_context->pSettings->
3718                        Effects[j].xVSS.pTextBuffer,
3719                        (void *)pDecodedPath, xVSS_context->pSettings->
3720                        Effects[j].xVSS.textBufferSize + 1);
3721                }
3722
3723                /*Allocate the text RGB buffer*/
3724                framingCtx->aFramingCtx->FramingRgb =
3725                    (M4VIFI_ImagePlane *)M4OSA_32bitAlignedMalloc(sizeof(M4VIFI_ImagePlane),
3726                    M4VS,
3727                    (M4OSA_Char *)"RGB structure for the text effect");
3728
3729                if( framingCtx->aFramingCtx->FramingRgb == M4OSA_NULL )
3730                {
3731                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3732                    /*FB: to avoid leaks when there is an error in the send command*/
3733                    /* Free Send command */
3734                    M4xVSS_freeCommand(xVSS_context);
3735                    /**/
3736                    return M4ERR_ALLOC;
3737                }
3738
3739                if( xVSS_context->pSettings->Effects[j].xVSS.uiTextBufferWidth
3740                    == 0 || xVSS_context->pSettings->
3741                    Effects[j].xVSS.uiTextBufferHeight == 0 )
3742                {
3743                    M4OSA_TRACE1_0(
3744                        "M4xVSS_SendCommand: text plane width and height are not defined");
3745                    /*FB: to avoid leaks when there is an error in the send command*/
3746                    /* Free Send command */
3747                    M4xVSS_freeCommand(xVSS_context);
3748                    /**/
3749                    return M4ERR_PARAMETER;
3750                }
3751                /* Allocate input RGB text buffer and force it to even size to avoid errors in
3752                 YUV conversion */
3753                framingCtx->aFramingCtx->FramingRgb->u_width =
3754                    xVSS_context->pSettings->
3755                    Effects[j].xVSS.uiTextBufferWidth & ~1;
3756                framingCtx->aFramingCtx->FramingRgb->u_height =
3757                    xVSS_context->pSettings->
3758                    Effects[j].xVSS.uiTextBufferHeight & ~1;
3759                framingCtx->aFramingCtx->FramingRgb->u_stride =
3760                    2 * framingCtx->aFramingCtx->FramingRgb->u_width;
3761                framingCtx->aFramingCtx->FramingRgb->u_topleft = 0;
3762                framingCtx->aFramingCtx->FramingRgb->pac_data =
3763                    (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(
3764                    framingCtx->aFramingCtx->FramingRgb->u_height
3765                    * framingCtx->aFramingCtx->FramingRgb->u_stride,
3766                    M4VS, (M4OSA_Char *)"Text RGB plane->pac_data");
3767
3768                if( framingCtx->aFramingCtx->FramingRgb->pac_data
3769                    == M4OSA_NULL )
3770                {
3771                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3772                    /*FB: to avoid leaks when there is an error in the send command*/
3773                    /* Free Send command */
3774                    M4xVSS_freeCommand(xVSS_context);
3775                    /**/
3776                    return M4ERR_ALLOC;
3777                }
3778
3779#ifdef DECODE_GIF_ON_SAVING
3780                /**/
3781                /* Call text rendering function */
3782
3783                err = xVSS_context->pSettings->xVSS.pTextRenderingFct(
3784                    xVSS_context->pSettings->Effects[j].xVSS.pRenderingData,
3785                    xVSS_context->pSettings->
3786                    Effects[j].xVSS.pTextBuffer,
3787                    xVSS_context->pSettings->
3788                    Effects[j].xVSS.textBufferSize,
3789                    &(framingCtx->aFramingCtx->FramingRgb));
3790
3791                if( err != M4NO_ERROR )
3792                {
3793                    M4OSA_TRACE1_0("Text rendering external function failed\n");
3794                    M4xVSS_freeCommand(xVSS_context);
3795                    return err;
3796                }
3797
3798                /* Check that RGB buffer is set */
3799                if( framingCtx->aFramingCtx->FramingRgb == M4OSA_NULL )
3800                {
3801                    M4OSA_TRACE1_0(
3802                        "Text rendering function did not set RGB buffer correctly !");
3803                    M4xVSS_freeCommand(xVSS_context);
3804                    return M4ERR_PARAMETER;
3805                }
3806
3807                /* Convert RGB plane to YUV420 and update framing structure */
3808                err = M4xVSS_internalConvertRGBtoYUV(framingCtx->aFramingCtx);
3809
3810                if( err != M4NO_ERROR )
3811                {
3812                    M4OSA_TRACE1_1(
3813                        "M4xVSS_sendCommand: error when converting RGB to YUV: 0w%x",
3814                        err);
3815                    M4xVSS_freeCommand(xVSS_context);
3816                    return err;
3817                }
3818
3819#else
3820                /**/
3821                /* Call text rendering function */
3822
3823                err = xVSS_context->pSettings->xVSS.pTextRenderingFct(
3824                    xVSS_context->pSettings->Effects[j].xVSS.pRenderingData,
3825                    xVSS_context->pSettings->
3826                    Effects[j].xVSS.pTextBuffer,
3827                    xVSS_context->pSettings->
3828                    Effects[j].xVSS.textBufferSize,
3829                    &(framingCtx->FramingRgb));
3830
3831                if( err != M4NO_ERROR )
3832                {
3833                    M4OSA_TRACE1_0("Text rendering external function failed\n");
3834                    M4xVSS_freeCommand(xVSS_context);
3835                    return err;
3836                }
3837
3838                /* Check that RGB buffer is set */
3839                if( framingCtx->FramingRgb == M4OSA_NULL )
3840                {
3841                    M4OSA_TRACE1_0(
3842                        "Text rendering function did not set RGB buffer correctly !");
3843                    M4xVSS_freeCommand(xVSS_context);
3844                    return M4ERR_PARAMETER;
3845                }
3846
3847                /* Convert RGB plane to YUV420 and update framing structure */
3848                err = M4xVSS_internalConvertRGBtoYUV(framingCtx);
3849
3850                if( err != M4NO_ERROR )
3851                {
3852                    M4OSA_TRACE1_1(
3853                        "M4xVSS_sendCommand: error when converting RGB to YUV: 0w%x",
3854                        err);
3855                    M4xVSS_freeCommand(xVSS_context);
3856                    return err;
3857                }
3858
3859#endif /*DECODE_GIF_ON_SAVING*/
3860
3861                /* Change internally effect type from "text" to framing */
3862
3863                xVSS_context->pSettings->Effects[j].VideoEffectType =
3864                    M4xVSS_kVideoEffectType_Framing;
3865                xVSS_context->pSettings->Effects[j].xVSS.bResize = M4OSA_FALSE;
3866            }
3867            else
3868            {
3869                M4OSA_TRACE1_0(
3870                    "M4xVSS_sendCommand: No text rendering function set !!");
3871                M4xVSS_freeCommand(xVSS_context);
3872                return M4ERR_PARAMETER;
3873            }
3874        }
3875
3876        /* Allocate the structure to store the data needed by the Fifties effect */
3877        else if( xVSS_context->pSettings->Effects[j].VideoEffectType
3878            == M4xVSS_kVideoEffectType_Fifties )
3879        {
3880            M4xVSS_FiftiesStruct *fiftiesCtx;
3881
3882            /* Check the expected frame rate for the fifties effect (must be above 0) */
3883            if( 0 == xVSS_context->pSettings->
3884                Effects[j].xVSS.uiFiftiesOutFrameRate )
3885            {
3886                M4OSA_TRACE1_0(
3887                    "The frame rate for the fifties effect must be greater than 0 !");
3888                M4xVSS_freeCommand(xVSS_context);
3889                return M4ERR_PARAMETER;
3890            }
3891
3892            fiftiesCtx = (M4xVSS_FiftiesStruct
3893                *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FiftiesStruct),
3894                M4VS, (M4OSA_Char *)"Context of the fifties effect");
3895
3896            if( fiftiesCtx == M4OSA_NULL )
3897            {
3898                M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3899                /* Free Send command */
3900                M4xVSS_freeCommand(xVSS_context);
3901                return M4ERR_ALLOC;
3902            }
3903
3904            fiftiesCtx->previousClipTime = -1;
3905            fiftiesCtx->fiftiesEffectDuration = 1000 / xVSS_context->pSettings->
3906                Effects[j].xVSS.uiFiftiesOutFrameRate;
3907            fiftiesCtx->shiftRandomValue = 0;
3908            fiftiesCtx->stripeRandomValue = 0;
3909
3910            /* Save the structure associated with corresponding effect */
3911            xVSS_context->pSettings->Effects[j].pExtVideoEffectFctCtxt =
3912                fiftiesCtx;
3913        }
3914
3915        /* Allocate the structure to store the data needed by the Color effect */
3916        else if( xVSS_context->pSettings->Effects[j].VideoEffectType
3917            == M4xVSS_kVideoEffectType_ColorRGB16
3918            || xVSS_context->pSettings->Effects[j].VideoEffectType
3919            == M4xVSS_kVideoEffectType_BlackAndWhite
3920            || xVSS_context->pSettings->Effects[j].VideoEffectType
3921            == M4xVSS_kVideoEffectType_Pink
3922            || xVSS_context->pSettings->Effects[j].VideoEffectType
3923            == M4xVSS_kVideoEffectType_Green
3924            || xVSS_context->pSettings->Effects[j].VideoEffectType
3925            == M4xVSS_kVideoEffectType_Sepia
3926            || xVSS_context->pSettings->Effects[j].VideoEffectType
3927            == M4xVSS_kVideoEffectType_Negative
3928            || xVSS_context->pSettings->Effects[j].VideoEffectType
3929            == M4xVSS_kVideoEffectType_Gradient )
3930        {
3931            M4xVSS_ColorStruct *ColorCtx;
3932
3933            ColorCtx =
3934                (M4xVSS_ColorStruct *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_ColorStruct),
3935                M4VS, (M4OSA_Char *)"Context of the color effect");
3936
3937            if( ColorCtx == M4OSA_NULL )
3938            {
3939                M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3940                /* Free Send command */
3941                M4xVSS_freeCommand(xVSS_context);
3942                return M4ERR_ALLOC;
3943            }
3944
3945            ColorCtx->colorEffectType =
3946                xVSS_context->pSettings->Effects[j].VideoEffectType;
3947
3948            if( xVSS_context->pSettings->Effects[j].VideoEffectType
3949                == M4xVSS_kVideoEffectType_ColorRGB16
3950                || xVSS_context->pSettings->Effects[j].VideoEffectType
3951                == M4xVSS_kVideoEffectType_Gradient )
3952            {
3953                ColorCtx->rgb16ColorData =
3954                    xVSS_context->pSettings->Effects[j].xVSS.uiRgb16InputColor;
3955            }
3956            else
3957            {
3958                ColorCtx->rgb16ColorData = 0;
3959            }
3960
3961            /* Save the structure associated with corresponding effect */
3962            xVSS_context->pSettings->Effects[j].pExtVideoEffectFctCtxt =
3963                ColorCtx;
3964        }
3965    }
3966
3967    /**********************************
3968    Background music registering
3969    **********************************/
3970    if( pSettings->xVSS.pBGMtrack != M4OSA_NULL && isNewBGM == M4OSA_TRUE )
3971    {
3972#ifdef PREVIEW_ENABLED
3973
3974        M4xVSS_MCS_params *pParams;
3975        M4OSA_Char *out_pcm;
3976        /*UTF conversion support*/
3977        M4OSA_Void *pDecodedPath = M4OSA_NULL;
3978
3979#endif
3980
3981        /* We save output file pointer, because we will need to use it when saving audio mixed
3982         file (last save step) */
3983
3984        xVSS_context->pOutputFile = xVSS_context->pSettings->pOutputFile;
3985        xVSS_context->pTemporaryFile = xVSS_context->pSettings->pTemporaryFile;
3986
3987        /* If a previous BGM has already been registered, delete it */
3988        /* Here can be implemented test to know if the same BGM is registered */
3989        if( xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
3990        {
3991            if( xVSS_context->pSettings->xVSS.pBGMtrack->pFile != M4OSA_NULL )
3992            {
3993                free(xVSS_context->pSettings->xVSS.pBGMtrack->
3994                    pFile);
3995                xVSS_context->pSettings->xVSS.pBGMtrack->pFile = M4OSA_NULL;
3996            }
3997            free(xVSS_context->pSettings->xVSS.pBGMtrack);
3998            xVSS_context->pSettings->xVSS.pBGMtrack = M4OSA_NULL;
3999        }
4000
4001        /* Allocate BGM */
4002        xVSS_context->pSettings->xVSS.pBGMtrack =
4003            (M4xVSS_BGMSettings *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_BGMSettings), M4VS,
4004            (M4OSA_Char *)"xVSS_context->pSettings->xVSS.pBGMtrack");
4005
4006        if( xVSS_context->pSettings->xVSS.pBGMtrack == M4OSA_NULL )
4007        {
4008            M4xVSS_freeCommand(xVSS_context);
4009            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
4010            return M4ERR_ALLOC;
4011        }
4012
4013        /* Copy input structure to our structure */
4014        memcpy((void *)xVSS_context->pSettings->xVSS.pBGMtrack,
4015            (void *)pSettings->xVSS.pBGMtrack,
4016            sizeof(M4xVSS_BGMSettings));
4017        /* Allocate file name, and copy file name buffer to our structure */
4018        xVSS_context->pSettings->xVSS.pBGMtrack->pFile =
4019            M4OSA_32bitAlignedMalloc((strlen(pSettings->xVSS.pBGMtrack->pFile)
4020            + 1), M4VS, (M4OSA_Char *)"xVSS BGM file path");
4021
4022        if( xVSS_context->pSettings->xVSS.pBGMtrack->pFile == M4OSA_NULL )
4023        {
4024            M4xVSS_freeCommand(xVSS_context);
4025            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
4026            return M4ERR_ALLOC;
4027        }
4028        memcpy((void *)xVSS_context->pSettings->xVSS.pBGMtrack->pFile,
4029            (void *)pSettings->xVSS.pBGMtrack->pFile,
4030            strlen(pSettings->xVSS.pBGMtrack->pFile) + 1);
4031
4032#ifdef PREVIEW_ENABLED
4033        /* Decode BGM track to pcm output file */
4034
4035        pParams =
4036            (M4xVSS_MCS_params *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_MCS_params), M4VS,
4037            (M4OSA_Char *)"Element of MCS Params (for BGM)");
4038
4039        if( pParams == M4OSA_NULL )
4040        {
4041            M4xVSS_freeCommand(xVSS_context);
4042            M4OSA_TRACE1_0(
4043                "M4xVSS_sendCommand: Problem when allocating one element MCS Params");
4044            return M4ERR_ALLOC;
4045        }
4046
4047        /* Initialize the pointers in case of problem (PR 2273) */
4048        pParams->pFileIn = M4OSA_NULL;
4049        pParams->pFileOut = M4OSA_NULL;
4050        pParams->pFileTemp = M4OSA_NULL;
4051        pParams->pNext = M4OSA_NULL;
4052        pParams->BeginCutTime = 0;
4053        pParams->EndCutTime = 0;
4054
4055        if( xVSS_context->pMCSparamsList
4056            == M4OSA_NULL ) /* Means it is the first element of the list */
4057        {
4058            /* Initialize the xVSS context with the first element of the list */
4059            xVSS_context->pMCSparamsList = pParams;
4060
4061        }
4062        else
4063        {
4064            M4xVSS_MCS_params *pParams_temp = xVSS_context->pMCSparamsList;
4065            M4xVSS_MCS_params *pParams_prev = M4OSA_NULL;
4066
4067            /* Parse MCS params chained list to find and delete BGM element */
4068            while( pParams_temp != M4OSA_NULL )
4069            {
4070                if( pParams_temp->isBGM == M4OSA_TRUE )
4071                {
4072                    /* Remove this element */
4073                    if( pParams_temp->pFileIn != M4OSA_NULL )
4074                    {
4075                        free(pParams_temp->pFileIn);
4076                        pParams_temp->pFileIn = M4OSA_NULL;
4077                    }
4078
4079                    if( pParams_temp->pFileOut != M4OSA_NULL )
4080                    {
4081                        /* Remove PCM temporary file */
4082                        remove((const char *)pParams_temp->pFileOut);
4083                        free(pParams_temp->pFileOut);
4084                        pParams_temp->pFileOut = M4OSA_NULL;
4085                    }
4086                    /* Chain previous element with next element = remove BGM chained
4087                         list element */
4088                    if( pParams_prev != M4OSA_NULL )
4089                    {
4090                        pParams_prev->pNext = pParams_temp->pNext;
4091                    }
4092                    /* If current pointer is the first of the chained list and next pointer of
4093                    the chained list is NULL */
4094                    /* it means that there was only one element in the list */
4095                    /* => we put the context variable to NULL to reaffect the first chained list
4096                     element */
4097                    if( pParams_temp == xVSS_context->pMCSparamsList
4098                        && pParams_temp->pNext == M4OSA_NULL )
4099                    {
4100                        xVSS_context->pMCSparamsList = M4OSA_NULL;
4101                    }
4102                    /* In that case, BGM pointer is the first one, but there are others elements
4103                     after it */
4104                    /* So, we need to change first chained list element */
4105                    else if( pParams_temp->pNext != M4OSA_NULL
4106                        && pParams_prev == M4OSA_NULL )
4107                    {
4108                        xVSS_context->pMCSparamsList = pParams_temp->pNext;
4109                    }
4110
4111                    if( pParams_temp->pNext != M4OSA_NULL )
4112                    {
4113                        pParams_prev = pParams_temp->pNext;
4114                        free(pParams_temp);
4115                        pParams_temp = M4OSA_NULL;
4116                        pParams_temp = pParams_prev;
4117                    }
4118                    else
4119                    {
4120                        free(pParams_temp);
4121                        pParams_temp = M4OSA_NULL;
4122                    }
4123                }
4124                else
4125                {
4126                    pParams_prev = pParams_temp;
4127                    pParams_temp = pParams_temp->pNext;
4128                }
4129            }
4130            /* We need to initialize the last element of the chained list to be able to add new
4131             BGM element */
4132            pMCS_last = pParams_prev;
4133
4134            if( xVSS_context->pMCSparamsList == M4OSA_NULL )
4135            {
4136                /* In that case, it means that there was only one element in the chained list */
4137                /* So, we need to save the new params*/
4138                xVSS_context->pMCSparamsList = pParams;
4139            }
4140            else
4141            {
4142                /* Update next pointer of the previous last element of the chain */
4143                pMCS_last->pNext = pParams;
4144            }
4145
4146        }
4147
4148        /* Fill the last M4xVSS_MCS_params element */
4149        pParams->InputFileType =
4150            xVSS_context->pSettings->xVSS.pBGMtrack->FileType;
4151        pParams->OutputFileType = M4VIDEOEDITING_kFileType_PCM;
4152        pParams->OutputVideoFormat = M4VIDEOEDITING_kNoneVideo;
4153        pParams->OutputVideoFrameSize = M4VIDEOEDITING_kQCIF;
4154        pParams->OutputVideoFrameRate = M4VIDEOEDITING_k15_FPS;
4155
4156        if( xVSS_context->pSettings->xVSS.outputAudioFormat
4157            == M4VIDEOEDITING_kAAC )
4158        {
4159            pParams->OutputAudioFormat = M4VIDEOEDITING_kAAC;
4160            pParams->OutputAudioSamplingFrequency = M4VIDEOEDITING_kDefault_ASF;
4161
4162            /*FB: VAL CR P4ME00003076
4163            The output audio bitrate in the AAC case is now directly given by the user*/
4164            /*Check if the audio bitrate is correctly defined*/
4165            /*Mono
4166            MCS values for AAC Mono are min: 16kbps and max: 192 kbps*/
4167            if( xVSS_context->pSettings->xVSS.outputAudioBitrate
4168                >= M4VIDEOEDITING_k16_KBPS
4169                && xVSS_context->pSettings->xVSS.outputAudioBitrate
4170                <= M4VIDEOEDITING_k192_KBPS
4171                && xVSS_context->pSettings->xVSS.bAudioMono == M4OSA_TRUE )
4172            {
4173                pParams->OutputAudioBitrate =
4174                    xVSS_context->pSettings->xVSS.outputAudioBitrate;
4175            }
4176            /*Stereo
4177            MCS values for AAC Mono are min: 32kbps and max: 192 kbps*/
4178            else if( xVSS_context->pSettings->xVSS.outputAudioBitrate
4179                >= M4VIDEOEDITING_k32_KBPS
4180                && xVSS_context->pSettings->xVSS.outputAudioBitrate
4181                <= M4VIDEOEDITING_k192_KBPS
4182                && xVSS_context->pSettings->xVSS.bAudioMono == M4OSA_FALSE )
4183            {
4184                pParams->OutputAudioBitrate =
4185                    xVSS_context->pSettings->xVSS.outputAudioBitrate;
4186            }
4187            else
4188            {
4189                pParams->OutputAudioBitrate = M4VIDEOEDITING_k32_KBPS;
4190            }
4191            pParams->bAudioMono = xVSS_context->pSettings->xVSS.bAudioMono;
4192        }
4193        else
4194        {
4195            pParams->OutputAudioFormat = M4VIDEOEDITING_kAMR_NB;
4196            pParams->OutputAudioSamplingFrequency = M4VIDEOEDITING_kDefault_ASF;
4197            pParams->OutputAudioBitrate = M4VIDEOEDITING_k12_2_KBPS;
4198            pParams->bAudioMono = M4OSA_TRUE;
4199        }
4200        pParams->OutputVideoBitrate = M4VIDEOEDITING_kUndefinedBitrate;
4201
4202        /* Prepare output filename */
4203        /* 21 is the size of "preview_16000_2.pcm" + \0 */
4204        out_pcm =
4205            (M4OSA_Char *)M4OSA_32bitAlignedMalloc(strlen(xVSS_context->pTempPath)
4206            + 21, M4VS, (M4OSA_Char *)"Temp char* for pcmPreviewFile");
4207
4208        if( out_pcm == M4OSA_NULL )
4209        {
4210            M4xVSS_freeCommand(xVSS_context);
4211            M4OSA_TRACE1_0("Allocation error in M4xVSS_Init");
4212            return M4ERR_ALLOC;
4213        }
4214
4215        /* Copy temporary path to final preview path string */
4216        M4OSA_chrNCopy(out_pcm, xVSS_context->pTempPath,
4217            strlen(xVSS_context->pTempPath) + 1);
4218
4219        /* Depending of the output sample frequency and nb of channels, we construct preview
4220        output filename */
4221        if( xVSS_context->pSettings->xVSS.outputAudioFormat
4222            == M4VIDEOEDITING_kAAC )
4223        {
4224            /* Construct output temporary PCM filename */
4225            if( xVSS_context->pSettings->xVSS.bAudioMono == M4OSA_TRUE )
4226            {
4227                strncat((char *)out_pcm, (const char *)"preview_16000_1.pcm\0",
4228                    20);
4229            }
4230            else
4231            {
4232                strncat((char *)out_pcm, (const char *)"preview_16000_2.pcm\0",
4233                    20);
4234            }
4235        }
4236        else if( xVSS_context->pSettings->xVSS.outputAudioFormat
4237            == M4VIDEOEDITING_kAMR_NB )
4238        {
4239            /* Construct output temporary PCM filename */
4240            strncat((char *)out_pcm, (const char *)"preview_08000_1.pcm\0", 20);
4241        }
4242        else
4243        {
4244            if( out_pcm != M4OSA_NULL )
4245            {
4246                free(out_pcm);
4247                out_pcm = M4OSA_NULL;
4248            }
4249            M4xVSS_freeCommand(xVSS_context);
4250            M4OSA_TRACE1_0("Bad audio output format \n");
4251            return M4ERR_PARAMETER;
4252        }
4253
4254        xVSS_context->pcmPreviewFile = out_pcm;
4255
4256        /**
4257        * UTF conversion: convert into the customer format, before being used*/
4258        pDecodedPath = out_pcm;
4259        length = strlen(pDecodedPath);
4260
4261        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
4262            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
4263            != M4OSA_NULL )
4264        {
4265            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
4266                (M4OSA_Void *)out_pcm, (M4OSA_Void *)xVSS_context->
4267                UTFConversionContext.pTempOutConversionBuffer, &length);
4268
4269            if( err != M4NO_ERROR )
4270            {
4271                M4OSA_TRACE1_1(
4272                    "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
4273                    err);
4274                /* Free Send command */
4275                M4xVSS_freeCommand(xVSS_context);
4276                return err;
4277            }
4278            pDecodedPath =
4279                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
4280        }
4281
4282        /**
4283        * End of the UTF conversion, use the converted file path*/
4284        xVSS_context->pcmPreviewFile =
4285            (M4OSA_Void *)M4OSA_32bitAlignedMalloc(length + 1, M4VS,
4286            (M4OSA_Char *)"pcmPreviewFile");
4287
4288        if( xVSS_context->pcmPreviewFile == M4OSA_NULL )
4289        {
4290            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
4291            free(out_pcm);
4292            out_pcm = M4OSA_NULL;
4293            /*FB: to avoid leaks when there is an error in the send command*/
4294            /* Free Send command */
4295            M4xVSS_freeCommand(xVSS_context);
4296            /**/
4297            return M4ERR_ALLOC;
4298        }
4299        memcpy((void *)xVSS_context->pcmPreviewFile, (void *)pDecodedPath, length + 1);
4300
4301        /* Free temporary output filename */
4302        if( out_pcm != M4OSA_NULL )
4303        {
4304            free(out_pcm);
4305            out_pcm = M4OSA_NULL;
4306        }
4307
4308        pParams->pFileOut = M4OSA_32bitAlignedMalloc((length + 1), M4VS,
4309            (M4OSA_Char *)"MCS BGM Params: file out");
4310
4311        if( pParams->pFileOut == M4OSA_NULL )
4312        {
4313            M4xVSS_freeCommand(xVSS_context);
4314            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
4315            return M4ERR_ALLOC;
4316        }
4317        pParams->pFileTemp = M4OSA_NULL;
4318
4319        memcpy((void *)pParams->pFileOut,(void *) xVSS_context->pcmPreviewFile,
4320            (length + 1)); /* Copy output file path */
4321
4322        /**
4323        * UTF conversion: convert into the customer format, before being used*/
4324
4325        pDecodedPath = xVSS_context->pSettings->xVSS.pBGMtrack->pFile;
4326        length = strlen(pDecodedPath);
4327
4328        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
4329            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
4330            != M4OSA_NULL )
4331        {
4332            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
4333                (M4OSA_Void *)xVSS_context->pSettings->xVSS.pBGMtrack->
4334                pFile, (M4OSA_Void *)xVSS_context->
4335                UTFConversionContext.pTempOutConversionBuffer, &length);
4336
4337            if( err != M4NO_ERROR )
4338            {
4339                M4OSA_TRACE1_1(
4340                    "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
4341                    err);
4342                /* Free Send command */
4343                M4xVSS_freeCommand(xVSS_context);
4344                return err;
4345            }
4346            pDecodedPath =
4347                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
4348        }
4349
4350        /**
4351        * End of the UTF conversion, use the converted file path*/
4352        pParams->pFileIn = (M4OSA_Void *)M4OSA_32bitAlignedMalloc((length + 1), M4VS,
4353            (M4OSA_Char *)"MCS BGM Params: file in");
4354
4355        if( pParams->pFileIn == M4OSA_NULL )
4356        {
4357            M4xVSS_freeCommand(xVSS_context);
4358            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
4359            return M4ERR_ALLOC;
4360        }
4361        memcpy((void *)pParams->pFileIn, (void *)pDecodedPath,
4362            (length + 1)); /* Copy input file path */
4363
4364        pParams->isBGM = M4OSA_TRUE;
4365        pParams->isCreated = M4OSA_FALSE;
4366        xVSS_context->nbStepTotal++;
4367        bIsTranscoding = M4OSA_TRUE;
4368#endif /* PREVIEW_ENABLED */
4369
4370    }
4371    else if( pSettings->xVSS.pBGMtrack != M4OSA_NULL
4372        && isNewBGM == M4OSA_FALSE )
4373    {
4374#ifdef PREVIEW_ENABLED
4375        /* BGM is the same as previously, no need to redecode audio */
4376        /* Need to update MCS params chained list, to signal M4xVSS_step function to skip
4377        BGM decoding */
4378
4379        M4xVSS_MCS_params *pParams_temp = xVSS_context->pMCSparamsList;
4380        M4xVSS_MCS_params *pParams_prev = M4OSA_NULL;
4381
4382#endif /* PREVIEW_ENABLED */
4383        /* We save output file pointer, because we will need to use it when saving audio
4384         mixed file (last save step) */
4385
4386        xVSS_context->pOutputFile = xVSS_context->pSettings->pOutputFile;
4387        xVSS_context->pTemporaryFile = xVSS_context->pSettings->pTemporaryFile;
4388
4389        /* Re-write BGM settings in case they have changed between two sendCommand */
4390        xVSS_context->pSettings->xVSS.pBGMtrack->uiAddCts =
4391            pSettings->xVSS.pBGMtrack->uiAddCts;
4392        xVSS_context->pSettings->xVSS.pBGMtrack->uiAddVolume =
4393            pSettings->xVSS.pBGMtrack->uiAddVolume;
4394        xVSS_context->pSettings->xVSS.pBGMtrack->uiBeginLoop =
4395            pSettings->xVSS.pBGMtrack->uiBeginLoop;
4396        xVSS_context->pSettings->xVSS.pBGMtrack->uiEndLoop =
4397            pSettings->xVSS.pBGMtrack->uiEndLoop;
4398
4399#ifdef PREVIEW_ENABLED
4400        /* Parse MCS params chained list to find and delete BGM element */
4401
4402        while( pParams_temp != M4OSA_NULL )
4403        {
4404            if( pParams_temp->isBGM == M4OSA_TRUE )
4405            {
4406                pParams_temp->isCreated = M4OSA_TRUE;
4407                break;
4408            }
4409            pParams_prev = pParams_temp;
4410            pParams_temp = pParams_temp->pNext;
4411        }
4412
4413#endif /* PREVIEW_ENABLED */
4414
4415        M4OSA_TRACE2_0("M4xVSS_SendCommand has been recalled, BGM is the same");
4416    }
4417    else
4418    {
4419        M4OSA_TRACE1_0("No BGM in this xVSS command");
4420
4421        if( xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
4422        {
4423#ifdef PREVIEW_ENABLED
4424            /* Need to remove MCS previous params chained list */
4425
4426            M4xVSS_MCS_params *pParams_temp = xVSS_context->pMCSparamsList;
4427            M4xVSS_MCS_params *pParams_prev = M4OSA_NULL;
4428
4429            /* Parse MCS params chained list to find and delete BGM element */
4430            while( pParams_temp != M4OSA_NULL )
4431            {
4432                if( pParams_temp->isBGM == M4OSA_TRUE )
4433                {
4434                    /* Remove this element */
4435                    if( pParams_temp->pFileIn != M4OSA_NULL )
4436                    {
4437                        free(pParams_temp->pFileIn);
4438                        pParams_temp->pFileIn = M4OSA_NULL;
4439                    }
4440
4441                    if( pParams_temp->pFileOut != M4OSA_NULL )
4442                    {
4443                        free(pParams_temp->pFileOut);
4444                        pParams_temp->pFileOut = M4OSA_NULL;
4445                    }
4446                    /* Chain previous element with next element */
4447                    if( pParams_prev != M4OSA_NULL )
4448                    {
4449                        pParams_prev->pNext = pParams_temp->pNext;
4450                    }
4451                    /* If current pointer is the first of the chained list and next pointer
4452                     of the chained list is NULL */
4453                    /* it means that there was only one element in the list */
4454                    /* => we put the context variable to NULL */
4455                    if( pParams_temp == xVSS_context->pMCSparamsList
4456                        && pParams_temp->pNext == M4OSA_NULL )
4457                    {
4458                        free(pParams_temp);
4459                        xVSS_context->pMCSparamsList = M4OSA_NULL;
4460                    }
4461                    /* In that case, BGM pointer is the first one, but there are others
4462                     elements after it */
4463                    /* So, we need to change first chained list element */
4464                    else if( pParams_temp->pNext != M4OSA_NULL )
4465                    {
4466                        xVSS_context->pMCSparamsList = pParams_temp->pNext;
4467                        free(pParams_temp);
4468                        pParams_temp = M4OSA_NULL;
4469                    }
4470                    /* In all other cases, nothing else to do except freeing the chained
4471                    list element */
4472                    else
4473                    {
4474                        free(pParams_temp);
4475                        pParams_temp = M4OSA_NULL;
4476                    }
4477                    break;
4478                }
4479                pParams_prev = pParams_temp;
4480                pParams_temp = pParams_temp->pNext;
4481            }
4482
4483#endif /* PREVIEW_ENABLED */
4484            /* Here, we unallocate all BGM components and put xVSS_context->pSettings->
4485            xVSS.pBGMtrack to NULL */
4486
4487            if( xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
4488            {
4489                if( xVSS_context->pSettings->xVSS.pBGMtrack->pFile
4490                    != M4OSA_NULL )
4491                {
4492                    free(xVSS_context->pSettings->xVSS.pBGMtrack->pFile);
4493                    xVSS_context->pSettings->xVSS.pBGMtrack->pFile = M4OSA_NULL;
4494                }
4495                free(xVSS_context->pSettings->xVSS.pBGMtrack);
4496                xVSS_context->pSettings->xVSS.pBGMtrack = M4OSA_NULL;
4497            }
4498        }
4499    }
4500
4501    /* Changed to be able to mix with video only files -> in case no master clip is found
4502    (i.e only JPG input or video only input) */
4503    /* and if there is a BGM, we force the added volume to 100 (i.e replace audio) */
4504
4505    if( masterClip == -1
4506        && xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
4507    {
4508        /* In that case, it means that no input 3GP file has a video track.
4509        Therefore, if a mixing is asked, it will fail. Thus, we force replace audio. */
4510        xVSS_context->pSettings->xVSS.pBGMtrack->uiAddVolume = 100;
4511    }
4512
4513    /* Save clip number to know if a M4xVSS_sendCommand has already been called */
4514    xVSS_context->previousClipNumber = xVSS_context->pSettings->uiClipNumber;
4515
4516    /* Change state */
4517    xVSS_context->m_state = M4xVSS_kStateAnalyzing;
4518
4519    /* In case of MMS use case, we compute here the max video bitrate */
4520    /* In case of too low bitrate, a specific warning is returned */
4521    if( xVSS_context->pSettings->xVSS.outputFileSize != 0 && totalDuration > 0 )
4522    {
4523        M4OSA_UInt32 targetedBitrate = 0;
4524        M4VIDEOEDITING_ClipProperties fileProperties;
4525        M4OSA_Double ratio;
4526
4527        if( xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
4528        {
4529            if( xVSS_context->pSettings->xVSS.pBGMtrack->uiAddVolume
4530                == 100 ) /* We are in "replace audio mode, need to check the filetype */
4531            {
4532                if( xVSS_context->pSettings->xVSS.pBGMtrack->FileType
4533                    == M4VIDEOEDITING_kFileType_3GPP )
4534                {
4535                    M4OSA_Void *pDecodedPath;
4536                    /**
4537                    * UTF conversion: convert into the customer format, before being used*/
4538                    pDecodedPath =
4539                        xVSS_context->pSettings->xVSS.pBGMtrack->pFile;
4540                    length = strlen(pDecodedPath);
4541
4542                    if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
4543                        != M4OSA_NULL && xVSS_context->
4544                        UTFConversionContext.pTempOutConversionBuffer
4545                        != M4OSA_NULL )
4546                    {
4547                        err = M4xVSS_internalConvertFromUTF8(xVSS_context,
4548                            (M4OSA_Void *)xVSS_context->pSettings->
4549                            xVSS.pBGMtrack->pFile,
4550                            (M4OSA_Void *)xVSS_context->
4551                            UTFConversionContext.
4552                            pTempOutConversionBuffer, &length);
4553
4554                        if( err != M4NO_ERROR )
4555                        {
4556                            M4OSA_TRACE1_1("M4xVSS_SendCommand: \
4557                                M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
4558                                err);
4559                            /* Free Send command */
4560                            M4xVSS_freeCommand(xVSS_context);
4561                            return err;
4562                        }
4563                        pDecodedPath = xVSS_context->
4564                            UTFConversionContext.pTempOutConversionBuffer;
4565                    }
4566
4567                    /**
4568                    * End of the UTF conversion, use the converted file path*/
4569                    err =
4570                        M4xVSS_internalGetProperties(xVSS_context, pDecodedPath,
4571                        &fileProperties);
4572
4573                    /* Get the properties of the BGM track */
4574                    /*err = M4xVSS_internalGetProperties(xVSS_context, xVSS_context->pSettings->
4575                    xVSS.pBGMtrack->pFile, &fileProperties);*/
4576                    if( err != M4NO_ERROR )
4577                    {
4578                        M4OSA_TRACE1_1(
4579                            "M4xVSS_sendCommand: M4xVSS_internalGetProperties returned an error:\
4580                             0x%x", err);
4581                        return err;
4582                    }
4583
4584                    if( fileProperties.AudioStreamType
4585                        != M4VIDEOEDITING_kAMR_NB )
4586                    {
4587                        M4OSA_TRACE1_0(
4588                            "M4xVSS_sendCommand: Impossible to use MMS mode with BGM != AMR-NB");
4589                        return M4ERR_PARAMETER;
4590                    }
4591                }
4592                else if( xVSS_context->pSettings->xVSS.pBGMtrack->FileType
4593                    != M4VIDEOEDITING_kFileType_AMR
4594                    && xVSS_context->pSettings->xVSS.pBGMtrack->FileType
4595                    != M4VIDEOEDITING_kFileType_MP3 )
4596                {
4597                    M4OSA_TRACE1_0("M4xVSS_sendCommand: Bad input BGM file");
4598                    return M4ERR_PARAMETER;
4599                }
4600            }
4601        }
4602
4603        /* Compute targeted bitrate, with 8% margin (moov) */
4604        if( totalDuration > 1000 )
4605        {
4606            targetedBitrate =
4607                (M4OSA_UInt32)(( xVSS_context->pSettings->xVSS.outputFileSize
4608                * 8 * 0.84) / (totalDuration / 1000));
4609        }
4610        else
4611        {
4612            targetedBitrate = 0;
4613        }
4614
4615        /* Remove audio bitrate */
4616        if( targetedBitrate >= 12200 )
4617        {
4618            targetedBitrate -= 12200; /* Only AMR is supported in MMS case */
4619        }
4620        else
4621        {
4622            targetedBitrate = 0;
4623        }
4624
4625        /* Compute an indicator of "complexity" depending on nb of sequences and total duration */
4626        /* The highest is the number of sequences, the more there are some I frames */
4627        /* In that case, it is necessary to reduce the target bitrate */
4628        ratio =
4629            (M4OSA_Double)((M4OSA_Double)(xVSS_context->pSettings->uiClipNumber
4630            * 100000) / (M4OSA_Double)(totalDuration));
4631        M4OSA_TRACE2_3(
4632            "Ratio clip_nb/duration = %f\nTargeted bitrate = %d\nTotal duration: %d",
4633            (M4OSA_Double)((M4OSA_Double)(xVSS_context->pSettings->uiClipNumber
4634            * 100000) / (M4OSA_Double)(totalDuration)),
4635            targetedBitrate, totalDuration);
4636
4637        if( ratio > 50 && ratio <= 75 )
4638        {
4639            /* It means that there is a potential risk of having a higher file size
4640            than specified */
4641            targetedBitrate -= (M4OSA_UInt32)(targetedBitrate * 0.1);
4642            M4OSA_TRACE2_2(
4643                "New bitrate1 !!\nRatio clip_nb/duration = %f\nTargeted bitrate = %d",
4644                ratio, targetedBitrate);
4645        }
4646        else if( ratio > 75 )
4647        {
4648            targetedBitrate -= (M4OSA_UInt32)(targetedBitrate * 0.15);
4649            M4OSA_TRACE2_2(
4650                "New bitrate2 !!\nRatio clip_nb/duration = %f\nTargeted bitrate = %d",
4651                ratio, targetedBitrate);
4652        }
4653
4654        /*CR 3283 MMS use case for VAL:
4655        Decrease the output file size to keep a margin of 5%
4656        The writer will stop when the targeted output file size will be reached*/
4657        xVSS_context->pSettings->xVSS.outputFileSize -=
4658            (M4OSA_UInt32)(xVSS_context->pSettings->xVSS.outputFileSize * 0.05);
4659
4660        switch( xVSS_context->pSettings->xVSS.outputVideoSize )
4661        {
4662            case M4VIDEOEDITING_kSQCIF:
4663                if( targetedBitrate < 32000 )
4664                {
4665                    xVSS_context->targetedBitrate = 32000;
4666                    return M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED;
4667                }
4668                break;
4669
4670            case M4VIDEOEDITING_kQQVGA:
4671                if( targetedBitrate < 32000 )              /*48000)*/
4672                {
4673                    xVSS_context->targetedBitrate = 32000; /*48000;*/
4674                    return M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED;
4675                }
4676                break;
4677
4678            case M4VIDEOEDITING_kQCIF:
4679                if( targetedBitrate < 48000 )              /*64000)*/
4680                {
4681                    xVSS_context->targetedBitrate = 48000; /*64000;*/
4682                    return M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED;
4683                }
4684                break;
4685
4686            case M4VIDEOEDITING_kQVGA:
4687                if( targetedBitrate < 64000 )              /*128000)*/
4688                {
4689                    xVSS_context->targetedBitrate = 64000; /*128000;*/
4690                    return M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED;
4691                }
4692                break;
4693
4694            case M4VIDEOEDITING_kCIF:
4695                if( targetedBitrate < 128000 )
4696                {
4697                    xVSS_context->targetedBitrate = 128000;
4698                    return M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED;
4699                }
4700                break;
4701
4702            case M4VIDEOEDITING_kVGA:
4703                if( targetedBitrate < 192000 )
4704                {
4705                    xVSS_context->targetedBitrate = 192000;
4706                    return M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED;
4707                }
4708                break;
4709
4710            default:
4711                /* Cannot happen */
4712                M4OSA_TRACE1_0(
4713                    "M4xVSS_sendCommand: Error in output fileSize !");
4714                return M4ERR_PARAMETER;
4715                break;
4716        }
4717        xVSS_context->targetedBitrate = (M4OSA_UInt32)targetedBitrate;
4718    }
4719
4720    if( bIsTranscoding )
4721    {
4722        return M4VSS3GPP_WAR_TRANSCODING_NECESSARY;
4723    }
4724    else
4725    {
4726        return M4NO_ERROR;
4727    }
4728}
4729
4730/**
4731 ******************************************************************************
4732 * prototype    M4OSA_ERR M4xVSS_SaveStart(M4OSA_Context pContext, M4OSA_Char* pFilePath)
4733 * @brief        This function prepare the save
4734 * @note        The xVSS create 3GP edited final file
4735 *                This function must be called once M4xVSS_Step has returned
4736 *                M4VSS3GPP_WAR_ANALYZING_DONE
4737 *                After this function, the user must call M4xVSS_Step until
4738 *                it returns another error than M4NO_ERROR.
4739 *
4740 * @param    pContext            (IN) Pointer on the xVSS edit context
4741 * @param    pFilePath            (IN) If the user wants to provide a different
4742 *                                output filename, else can be NULL (allocated by the user)
4743 * @return    M4NO_ERROR:            No error
4744 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
4745 * @return    M4ERR_ALLOC:        Memory allocation has failed
4746 * @return    M4ERR_STATE:        This function cannot not be called at this time
4747 ******************************************************************************
4748 */
4749M4OSA_ERR M4xVSS_SaveStart( M4OSA_Context pContext, M4OSA_Void *pFilePath,
4750                           M4OSA_UInt32 filePathSize )
4751{
4752    M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
4753    M4OSA_ERR err;
4754
4755    /*Add for UTF conversion: copy the pSettings structure into a new pCurrentEditSettings*/
4756    M4VSS3GPP_EditSettings *pEditSavingSettings = M4OSA_NULL;
4757    M4OSA_UInt8 i, j;
4758    M4OSA_UInt32 offset = 0;
4759    M4OSA_UInt8 nbEffects = 0;
4760    /*only for UTF conversion support*/
4761    M4OSA_Void *pDecodedPath = M4OSA_NULL;
4762    M4OSA_UInt32 length = 0;
4763    /**/
4764
4765    /* Check state */
4766    if( xVSS_context->m_state != M4xVSS_kStateOpened )
4767    {
4768        M4OSA_TRACE1_1(
4769            "Bad state when calling M4xVSS_SaveStart function! State is %d",
4770            xVSS_context->m_state);
4771        return M4ERR_STATE;
4772    }
4773
4774    /* RC: to temporary handle changing of output filepath */
4775    /* TO BE CHANGED CLEANLY WITH A MALLOC/MEMCPY !!!! */
4776    if( pFilePath != M4OSA_NULL )
4777    {
4778        if( xVSS_context->pSettings->pOutputFile != M4OSA_NULL )
4779        {
4780            /*it means that pOutputFile has been allocated in M4xVSS_sendCommand()*/
4781            free(xVSS_context->pSettings->pOutputFile);
4782            xVSS_context->pSettings->pOutputFile = M4OSA_NULL;
4783            xVSS_context->pSettings->uiOutputPathSize = 0;
4784        }
4785
4786        pDecodedPath = pFilePath;
4787        /*As all inputs of the xVSS are in UTF8, convert the output file path into the customer
4788         format*/
4789        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
4790            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
4791            != M4OSA_NULL )
4792        {
4793            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
4794                (M4OSA_Void *)pFilePath, (M4OSA_Void *)xVSS_context->
4795                UTFConversionContext.pTempOutConversionBuffer, &length);
4796
4797            if( err != M4NO_ERROR )
4798            {
4799                M4OSA_TRACE1_1(
4800                    "M4xVSS_SaveStart: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
4801                    err);
4802                return err;
4803            }
4804            pDecodedPath =
4805                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
4806            filePathSize = length;
4807        }
4808
4809        xVSS_context->pOutputFile =
4810            (M4OSA_Void *)M4OSA_32bitAlignedMalloc(filePathSize + 1, M4VS,
4811            (M4OSA_Char *)"M4xVSS_SaveStart: output file");
4812
4813        if( xVSS_context->pOutputFile == M4OSA_NULL )
4814        {
4815            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
4816            return M4ERR_ALLOC;
4817        }
4818        memcpy((void *)xVSS_context->pOutputFile, (void *)pDecodedPath, filePathSize + 1);
4819        xVSS_context->pOutputFile[filePathSize] = '\0';
4820        xVSS_context->pSettings->pOutputFile = xVSS_context->pOutputFile;
4821        xVSS_context->pSettings->uiOutputPathSize = filePathSize;
4822    }
4823
4824    /**
4825    ***/
4826
4827    /*FB: Add for UTF conversion: copy the pSettings structure into a new pCurrentEditSettings*/
4828    /*It is the same principle as in the PreviewStart()*/
4829    pEditSavingSettings =
4830        (M4VSS3GPP_EditSettings *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_EditSettings),
4831        M4VS, (M4OSA_Char *)"Saving, copy of VSS structure");
4832
4833    if( pEditSavingSettings == M4OSA_NULL )
4834    {
4835        M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
4836
4837        if( xVSS_context->pOutputFile != M4OSA_NULL )
4838        {
4839            free(xVSS_context->pOutputFile);
4840            xVSS_context->pOutputFile = M4OSA_NULL;
4841        }
4842        return M4ERR_ALLOC;
4843    }
4844
4845    /* Copy settings from input structure */
4846    memcpy((void *) &(pEditSavingSettings->xVSS),
4847        (void *) &(xVSS_context->pSettings->xVSS),
4848        sizeof(M4xVSS_EditSettings));
4849
4850    /* Initialize pEditSavingSettings structure */
4851    pEditSavingSettings->xVSS.pBGMtrack = M4OSA_NULL;
4852
4853    pEditSavingSettings->videoFrameRate =
4854        xVSS_context->pSettings->videoFrameRate;
4855    pEditSavingSettings->uiClipNumber = xVSS_context->pSettings->uiClipNumber;
4856    pEditSavingSettings->uiMasterClip =
4857        xVSS_context->pSettings->uiMasterClip; /* VSS2.0 mandatory parameter */
4858
4859    /* Allocate savingSettings.pClipList/pTransitions structure */
4860    pEditSavingSettings->pClipList = (M4VSS3GPP_ClipSettings *
4861        * )M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_ClipSettings *)
4862        *pEditSavingSettings->uiClipNumber,
4863        M4VS, (M4OSA_Char *)"xVSS, saving , copy of pClipList");
4864
4865    if( pEditSavingSettings->pClipList == M4OSA_NULL )
4866    {
4867        M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
4868
4869        if( xVSS_context->pOutputFile != M4OSA_NULL )
4870        {
4871            free(xVSS_context->pOutputFile);
4872            xVSS_context->pOutputFile = M4OSA_NULL;
4873        }
4874        return M4ERR_ALLOC;
4875    }
4876
4877    if( pEditSavingSettings->uiClipNumber > 1 )
4878    {
4879        pEditSavingSettings->pTransitionList = (M4VSS3GPP_TransitionSettings *
4880            * )M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_TransitionSettings *)
4881            *(pEditSavingSettings->uiClipNumber - 1),
4882            M4VS, (M4OSA_Char *)"xVSS, saving, copy of pTransitionList");
4883
4884        if( pEditSavingSettings->pTransitionList == M4OSA_NULL )
4885        {
4886            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
4887
4888            if( xVSS_context->pOutputFile != M4OSA_NULL )
4889            {
4890                free(xVSS_context->pOutputFile);
4891                xVSS_context->pOutputFile = M4OSA_NULL;
4892            }
4893            return M4ERR_ALLOC;
4894        }
4895    }
4896    else
4897    {
4898        pEditSavingSettings->pTransitionList = M4OSA_NULL;
4899    }
4900
4901    for ( i = 0; i < pEditSavingSettings->uiClipNumber; i++ )
4902    {
4903        pEditSavingSettings->pClipList[i] = (M4VSS3GPP_ClipSettings
4904            *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_ClipSettings),
4905            M4VS, (M4OSA_Char *)"saving clip settings");
4906
4907        if( pEditSavingSettings->pClipList[i] == M4OSA_NULL )
4908        {
4909            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
4910
4911            if( xVSS_context->pOutputFile != M4OSA_NULL )
4912            {
4913                free(xVSS_context->pOutputFile);
4914                xVSS_context->pOutputFile = M4OSA_NULL;
4915            }
4916            return M4ERR_ALLOC;
4917        }
4918
4919        if( i < pEditSavingSettings->uiClipNumber
4920            - 1 ) /* Because there is 1 less transition than clip number */
4921        {
4922            pEditSavingSettings->pTransitionList[i] =
4923                (M4VSS3GPP_TransitionSettings
4924                *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_TransitionSettings),
4925                M4VS, (M4OSA_Char *)"saving transition settings");
4926
4927            if( pEditSavingSettings->pTransitionList[i] == M4OSA_NULL )
4928            {
4929                M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
4930
4931                if( xVSS_context->pOutputFile != M4OSA_NULL )
4932                {
4933                    free(xVSS_context->pOutputFile);
4934                    xVSS_context->pOutputFile = M4OSA_NULL;
4935                }
4936                return M4ERR_ALLOC;
4937            }
4938        }
4939    }
4940
4941    for ( i = 0; i < xVSS_context->pSettings->uiClipNumber; i++ )
4942    {
4943        // Add MP4 file support
4944
4945        if( ( xVSS_context->pSettings->pClipList[i]->FileType
4946            == M4VIDEOEDITING_kFileType_3GPP)
4947            || (xVSS_context->pSettings->pClipList[i]->FileType
4948            == M4VIDEOEDITING_kFileType_MP4)
4949            || (xVSS_context->pSettings->pClipList[i]->FileType
4950            == M4VIDEOEDITING_kFileType_M4V)
4951            || (xVSS_context->pSettings->pClipList[i]->FileType
4952            == M4VIDEOEDITING_kFileType_ARGB8888))
4953
4954        {
4955            /* Copy data from given structure to our saving structure */
4956            M4xVSS_DuplicateClipSettings(pEditSavingSettings->pClipList[i],
4957                xVSS_context->pSettings->pClipList[i],
4958                M4OSA_FALSE /* remove effects */);
4959
4960            /**
4961            * UTF conversion: convert into the customer format, before being used*/
4962            pDecodedPath = pEditSavingSettings->pClipList[i]->pFile;
4963            length = strlen(pDecodedPath);
4964
4965            if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
4966                != M4OSA_NULL && xVSS_context->
4967                UTFConversionContext.pTempOutConversionBuffer
4968                != M4OSA_NULL )
4969            {
4970                err =
4971                    M4xVSS_internalConvertFromUTF8(xVSS_context, (M4OSA_Void
4972                    *)pEditSavingSettings->pClipList[i]->pFile,
4973                    (M4OSA_Void *)xVSS_context->
4974                    UTFConversionContext.pTempOutConversionBuffer,
4975                    &length);
4976
4977                if( err != M4NO_ERROR )
4978                {
4979                    M4OSA_TRACE1_1(
4980                        "M4xVSS_SaveStart: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
4981                        err);
4982
4983                    if( xVSS_context->pOutputFile != M4OSA_NULL )
4984                    {
4985                        free(xVSS_context->pOutputFile);
4986                        xVSS_context->pOutputFile = M4OSA_NULL;
4987                    }
4988                    return err;
4989                }
4990                pDecodedPath = xVSS_context->
4991                    UTFConversionContext.pTempOutConversionBuffer;
4992
4993                /**
4994                * End of the UTF conversion, use the converted file path*/
4995                free(
4996                    pEditSavingSettings->pClipList[i]->pFile);
4997                pEditSavingSettings->pClipList[i]->pFile = (M4OSA_Void
4998                    *)M4OSA_32bitAlignedMalloc((length + 1),
4999                    M4VS, (M4OSA_Char *)"saving transition settings");
5000
5001                if( pEditSavingSettings->pClipList[i]->pFile == M4OSA_NULL )
5002                {
5003                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
5004
5005                    if( xVSS_context->pOutputFile != M4OSA_NULL )
5006                    {
5007                        free(xVSS_context->pOutputFile);
5008                        xVSS_context->pOutputFile = M4OSA_NULL;
5009                    }
5010                    return M4ERR_ALLOC;
5011                }
5012                memcpy((void *)pEditSavingSettings->pClipList[i]->pFile,
5013                    (void *)pDecodedPath, length + 1);
5014            }
5015            /*FB: add file path size because of UTF 16 conversion*/
5016            pEditSavingSettings->pClipList[i]->filePathSize = length+1;
5017
5018            if( i
5019                < xVSS_context->pSettings->uiClipNumber
5020                - 1 ) /* Because there is 1 less transition than clip number */
5021            {
5022                memcpy(
5023                    (void *)pEditSavingSettings->pTransitionList[i],
5024                    (void *)xVSS_context->pSettings->
5025                    pTransitionList[i],
5026                    sizeof(M4VSS3GPP_TransitionSettings));
5027            }
5028        }
5029        else
5030        {
5031            M4OSA_TRACE1_0(
5032                "M4xVSS_SaveStart: Error when parsing xVSS_context->pSettings->pClipList[i]:\
5033                 Bad file type");
5034
5035            if( xVSS_context->pOutputFile != M4OSA_NULL )
5036            {
5037                free(xVSS_context->pOutputFile);
5038                xVSS_context->pOutputFile = M4OSA_NULL;
5039            }
5040            return M4ERR_PARAMETER;
5041        }
5042    }
5043
5044    /* Count the number of video effects, used to know how much memory is needed to allocate*/
5045    /* FB 2008/10/15: removed : not compatible with M4VSS3GPP_kVideoEffectType_None
5046    for(j=0;j<xVSS_context->pSettings->nbEffects;j++)
5047    {
5048    if(xVSS_context->pSettings->Effects[j].VideoEffectType != M4VSS3GPP_kVideoEffectType_None)
5049    {
5050    nbEffects++;
5051    }
5052    }*/
5053    nbEffects = xVSS_context->pSettings->nbEffects;
5054
5055    /* Allocate effects saving structure with correct number of effects */
5056    if( nbEffects != 0 )
5057    {
5058        pEditSavingSettings->Effects =
5059            (M4VSS3GPP_EffectSettings *)M4OSA_32bitAlignedMalloc(nbEffects
5060            * sizeof(M4VSS3GPP_EffectSettings), M4VS, (M4OSA_Char
5061            *)"Saving settings, effects table of structure settings");
5062
5063        if( pEditSavingSettings->Effects == M4OSA_NULL )
5064        {
5065            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
5066
5067            if( xVSS_context->pOutputFile != M4OSA_NULL )
5068            {
5069                free(xVSS_context->pOutputFile);
5070                xVSS_context->pOutputFile = M4OSA_NULL;
5071            }
5072            return M4ERR_ALLOC;
5073        }
5074
5075        /* Just copy effect structure to saving structure, as effects time are now */
5076        /* relative to output clip time*/
5077        memcpy((void *)pEditSavingSettings->Effects,
5078            (void *)xVSS_context->pSettings->Effects,
5079            nbEffects * sizeof(M4VSS3GPP_EffectSettings));
5080    }
5081    else
5082    {
5083        pEditSavingSettings->Effects = M4OSA_NULL;
5084        pEditSavingSettings->nbEffects = 0;
5085    }
5086    pEditSavingSettings->nbEffects = nbEffects;
5087
5088    if( pFilePath != M4OSA_NULL )
5089    {
5090        pEditSavingSettings->pOutputFile = pFilePath;
5091    }
5092
5093    /* Save pointer of saving video editor to use in step function */
5094    xVSS_context->pCurrentEditSettings = pEditSavingSettings;
5095
5096    /* Change output file name to temporary output file name, because final file will be
5097     generated by audio mixer */
5098    if( xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
5099    {
5100
5101        M4OSA_Char out_3gp[M4XVSS_MAX_PATH_LEN];
5102        M4OSA_Char out_3gp_tmp[M4XVSS_MAX_PATH_LEN];
5103
5104        /**/
5105        pEditSavingSettings->xVSS.pBGMtrack =
5106            (M4xVSS_BGMSettings *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_BGMSettings), M4VS,
5107            (M4OSA_Char
5108            *)"Saving settings, effects table of structure settings");
5109
5110        if( pEditSavingSettings->xVSS.pBGMtrack == M4OSA_NULL )
5111        {
5112            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
5113
5114            if( xVSS_context->pOutputFile != M4OSA_NULL )
5115            {
5116                free(xVSS_context->pOutputFile);
5117                xVSS_context->pOutputFile = M4OSA_NULL;
5118            }
5119            return M4ERR_ALLOC;
5120        }
5121
5122        /* Just copy effect structure to saving structure, as effects time are now */
5123        /* relative to output clip time*/
5124        memcpy((void *)pEditSavingSettings->xVSS.pBGMtrack,
5125            (void *)xVSS_context->pSettings->xVSS.pBGMtrack,
5126            sizeof(M4xVSS_BGMSettings));
5127
5128        /* Allocate file name, and copy file name buffer to our structure */
5129        pEditSavingSettings->xVSS.pBGMtrack->pFile = M4OSA_32bitAlignedMalloc(
5130            (strlen(xVSS_context->pSettings->xVSS.pBGMtrack->pFile)
5131            + 1),
5132            M4VS, (M4OSA_Char *)"Saving struct xVSS BGM file path");
5133
5134        if( pEditSavingSettings->xVSS.pBGMtrack->pFile == M4OSA_NULL )
5135        {
5136            M4xVSS_freeCommand(xVSS_context);
5137            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
5138
5139            if( xVSS_context->pOutputFile != M4OSA_NULL )
5140            {
5141                free(xVSS_context->pOutputFile);
5142                xVSS_context->pOutputFile = M4OSA_NULL;
5143            }
5144            return M4ERR_ALLOC;
5145        }
5146        memcpy((void *)pEditSavingSettings->xVSS.pBGMtrack->pFile,
5147            (void *)xVSS_context->pSettings->xVSS.pBGMtrack->pFile,
5148            strlen(xVSS_context->pSettings->xVSS.pBGMtrack->pFile)
5149            + 1);
5150
5151        /*Copy BGM track file path*/
5152
5153        /**
5154        * UTF conversion*/
5155        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
5156            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
5157            != M4OSA_NULL )
5158        {
5159            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
5160                (M4OSA_Void *)pEditSavingSettings->xVSS.pBGMtrack->pFile,
5161                (M4OSA_Void *)xVSS_context->
5162                UTFConversionContext.pTempOutConversionBuffer, &length);
5163
5164            if( err != M4NO_ERROR )
5165            {
5166                M4OSA_TRACE1_1(
5167                    "M4xVSS_SaveStart: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
5168                    err);
5169
5170                if( xVSS_context->pOutputFile != M4OSA_NULL )
5171                {
5172                    free(xVSS_context->pOutputFile);
5173                    xVSS_context->pOutputFile = M4OSA_NULL;
5174                }
5175                return err;
5176            }
5177            pDecodedPath =
5178                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
5179
5180            free(pEditSavingSettings->xVSS.pBGMtrack->pFile);
5181            pEditSavingSettings->xVSS.pBGMtrack->pFile =
5182                (M4OSA_Void *)M4OSA_32bitAlignedMalloc(length + 1, M4VS, (M4OSA_Char
5183                *)"M4xVSS_SaveStart: Temp filename in case of BGM");
5184
5185            if( pEditSavingSettings->xVSS.pBGMtrack->pFile == M4OSA_NULL )
5186            {
5187                M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
5188
5189                if( xVSS_context->pOutputFile != M4OSA_NULL )
5190                {
5191                    free(xVSS_context->pOutputFile);
5192                    xVSS_context->pOutputFile = M4OSA_NULL;
5193                }
5194                return M4ERR_ALLOC;
5195            }
5196            memcpy((void *)pEditSavingSettings->xVSS.pBGMtrack->pFile,
5197                (void *)pDecodedPath, length + 1);
5198        }
5199
5200        /**/
5201
5202        M4OSA_chrNCopy(out_3gp, xVSS_context->pTempPath, M4XVSS_MAX_PATH_LEN - 1);
5203        M4OSA_chrNCopy(out_3gp_tmp, xVSS_context->pTempPath, M4XVSS_MAX_PATH_LEN - 1);
5204
5205        /* Construct output temporary 3GP filename */
5206        strncat((char *)out_3gp, (const char *)"savetemp.3gp\0", 13);
5207        strncat((char *)out_3gp_tmp, (const char *)"savetemp.tmp\0", 13);
5208
5209        /**
5210        * UTF conversion: convert into the customer format, before being used*/
5211        pDecodedPath = out_3gp;
5212        length = strlen(pDecodedPath);
5213
5214        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
5215            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
5216            != M4OSA_NULL )
5217        {
5218            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
5219                (M4OSA_Void *)out_3gp, (M4OSA_Void *)xVSS_context->
5220                UTFConversionContext.pTempOutConversionBuffer, &length);
5221
5222            if( err != M4NO_ERROR )
5223            {
5224                M4OSA_TRACE1_1(
5225                    "M4xVSS_SaveStart: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
5226                    err);
5227
5228                if( xVSS_context->pOutputFile != M4OSA_NULL )
5229                {
5230                    free(xVSS_context->pOutputFile);
5231                    xVSS_context->pOutputFile = M4OSA_NULL;
5232                }
5233                return err;
5234            }
5235            pDecodedPath =
5236                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
5237        }
5238
5239        /**
5240        * End of the UTF conversion, use the converted file path*/
5241        xVSS_context->pCurrentEditSettings->pOutputFile =
5242            (M4OSA_Void *)M4OSA_32bitAlignedMalloc(length + 1, M4VS,
5243            (M4OSA_Char *)"M4xVSS_SaveStart: Temp filename in case of BGM");
5244
5245        if( xVSS_context->pCurrentEditSettings->pOutputFile == M4OSA_NULL )
5246        {
5247            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
5248
5249            if( xVSS_context->pOutputFile != M4OSA_NULL )
5250            {
5251                free(xVSS_context->pOutputFile);
5252                xVSS_context->pOutputFile = M4OSA_NULL;
5253            }
5254            return M4ERR_ALLOC;
5255        }
5256        memcpy((void *)xVSS_context->pCurrentEditSettings->pOutputFile,
5257            (void *)pDecodedPath, length + 1);
5258        xVSS_context->pCurrentEditSettings->uiOutputPathSize = length + 1;
5259
5260        /**
5261        * UTF conversion: convert into the customer format, before being used*/
5262        pDecodedPath = out_3gp_tmp;
5263        length = strlen(pDecodedPath);
5264
5265        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
5266            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
5267            != M4OSA_NULL )
5268        {
5269            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
5270                (M4OSA_Void *)out_3gp_tmp, (M4OSA_Void *)xVSS_context->
5271                UTFConversionContext.pTempOutConversionBuffer, &length);
5272
5273            if( err != M4NO_ERROR )
5274            {
5275                M4OSA_TRACE1_1(
5276                    "M4xVSS_SaveStart: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
5277                    err);
5278
5279                if( xVSS_context->pOutputFile != M4OSA_NULL )
5280                {
5281                    free(xVSS_context->pOutputFile);
5282                    xVSS_context->pOutputFile = M4OSA_NULL;
5283                }
5284                return err;
5285            }
5286            pDecodedPath =
5287                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
5288        }
5289
5290        /**
5291        * End of the UTF conversion, use the converted file path*/
5292        xVSS_context->pCurrentEditSettings->pTemporaryFile =
5293            (M4OSA_Void *)M4OSA_32bitAlignedMalloc(length + 1, M4VS,
5294            (M4OSA_Char *)"M4xVSS_SaveStart: Temporary file");
5295
5296        if( xVSS_context->pCurrentEditSettings->pTemporaryFile == M4OSA_NULL )
5297        {
5298            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
5299
5300            if( xVSS_context->pOutputFile != M4OSA_NULL )
5301            {
5302                free(xVSS_context->pOutputFile);
5303                xVSS_context->pOutputFile = M4OSA_NULL;
5304            }
5305            return M4ERR_ALLOC;
5306        }
5307        memcpy((void *)xVSS_context->pCurrentEditSettings->pTemporaryFile,
5308            (void *)pDecodedPath, length + 1);
5309
5310        /* Put nb of step for progression monitoring to 2, because audio mixing is needed */
5311        xVSS_context->nbStepTotal = 2;
5312    }
5313    else
5314    {
5315        xVSS_context->pCurrentEditSettings->pOutputFile =
5316            xVSS_context->pOutputFile;
5317        xVSS_context->pCurrentEditSettings->pTemporaryFile = M4OSA_NULL;
5318
5319        /* Put nb of step for progression monitoring to 1, because no audio mixing is needed */
5320        xVSS_context->nbStepTotal = 1;
5321    }
5322
5323    /**
5324    ***/
5325
5326    err = M4xVSS_internalGenerateEditedFile(xVSS_context);
5327
5328    if( err != M4NO_ERROR )
5329    {
5330        M4OSA_TRACE1_1(
5331            "M4xVSS_SaveStart: M4xVSS_internalGenerateEditedFile returned an error: 0x%x",
5332            err);
5333
5334        /**/
5335        if( xVSS_context->pCurrentEditSettings->pOutputFile != M4OSA_NULL
5336            && xVSS_context->pSettings->xVSS.pBGMtrack == M4OSA_NULL )
5337        {
5338            free(xVSS_context->pCurrentEditSettings->
5339                pOutputFile);
5340            xVSS_context->pCurrentEditSettings->pOutputFile = M4OSA_NULL;
5341            xVSS_context->pOutputFile = M4OSA_NULL;
5342        }
5343
5344        if( xVSS_context->pCurrentEditSettings->pTemporaryFile != M4OSA_NULL
5345            && xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
5346        {
5347            free(xVSS_context->pCurrentEditSettings->
5348                pTemporaryFile);
5349            xVSS_context->pCurrentEditSettings->pTemporaryFile = M4OSA_NULL;
5350        }
5351
5352        if( xVSS_context->pOutputFile != M4OSA_NULL )
5353        {
5354            free(xVSS_context->pOutputFile);
5355            xVSS_context->pOutputFile = M4OSA_NULL;
5356        }
5357        /* TODO: Translate error code of VSS to an xVSS error code */
5358        return err;
5359    }
5360
5361    /* Reinitialize current step number for progression monitoring */
5362    xVSS_context->currentStep = 0;
5363
5364    /* Change xVSS state */
5365    xVSS_context->m_state = M4xVSS_kStateSaving;
5366
5367    return M4NO_ERROR;
5368}
5369
5370/**
5371 ******************************************************************************
5372 * prototype    M4OSA_ERR M4xVSS_SaveStop(M4OSA_Context pContext)
5373 * @brief        This function unallocate save ressources and change xVSS
5374 *                internal state.
5375 * @note        This function must be called once M4xVSS_Step has returned
5376 *                M4VSS3GPP_WAR_SAVING_DONE
5377 *
5378 * @param    pContext            (IN) Pointer on the xVSS edit context
5379 * @return    M4NO_ERROR:            No error
5380 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
5381 * @return    M4ERR_STATE:        This function cannot not be called at this time
5382 ******************************************************************************
5383 */
5384M4OSA_ERR M4xVSS_SaveStop( M4OSA_Context pContext )
5385{
5386    M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
5387    M4OSA_ERR err = M4NO_ERROR;
5388
5389    /* Check state */
5390    if( xVSS_context->m_state != M4xVSS_kStateSaving )
5391    {
5392        M4OSA_TRACE1_1(
5393            "Bad state when calling M4xVSS_SaveStop function! State is %d",
5394            xVSS_context->m_state);
5395        return M4ERR_STATE;
5396    }
5397
5398    /* Free saving structures */
5399    M4xVSS_internalFreeSaving(xVSS_context);
5400
5401    if( xVSS_context->pOutputFile != M4OSA_NULL )
5402    {
5403        free(xVSS_context->pOutputFile);
5404        xVSS_context->pOutputFile = M4OSA_NULL;
5405    }
5406
5407    /* Change xVSS state */
5408    xVSS_context->m_state = M4xVSS_kStateSaved;
5409
5410    return M4NO_ERROR;
5411}
5412
5413/**
5414 ******************************************************************************
5415 * prototype    M4OSA_ERR M4xVSS_Step(M4OSA_Context pContext, M4OSA_UInt8 *pProgress)
5416 * @brief        This function executes differents tasks, depending of xVSS
5417 *                internal state.
5418 * @note        This function:
5419 *                    - analyses editing structure if called after M4xVSS_SendCommand
5420 *                    - generates preview file if called after M4xVSS_PreviewStart
5421 *                    - generates final edited file if called after M4xVSS_SaveStart
5422 *
5423 * @param    pContext                        (IN) Pointer on the xVSS edit context
5424 * @param    pProgress                        (IN/OUT) Pointer on an integer giving a
5425 *                                            progress indication (between 0-100)
5426 * @return    M4NO_ERROR:                        No error, the user must call M4xVSS_Step again
5427 * @return    M4ERR_PARAMETER:                At least one parameter is M4OSA_NULL
5428 * @return    M4ERR_STATE:                    This function cannot not be called at this time
5429 * @return    M4VSS3GPP_WAR_PREVIEW_READY:    Preview file is generated
5430 * @return    M4VSS3GPP_WAR_SAVING_DONE:        Final edited file is generated
5431 * @return    M4VSS3GPP_WAR_ANALYZING_DONE:    Analyse is done
5432 ******************************************************************************
5433 */
5434M4OSA_ERR M4xVSS_Step( M4OSA_Context pContext, M4OSA_UInt8 *pProgress )
5435{
5436    M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
5437    M4VSS3GPP_EditContext pVssCtxt = xVSS_context->pCurrentEditContext;
5438    M4VSS3GPP_AudioMixingContext pAudioMixingCtxt =
5439        xVSS_context->pAudioMixContext;
5440    M4OSA_ERR err = M4NO_ERROR;
5441    M4OSA_UInt8 uiProgress = 0;
5442
5443    switch( xVSS_context->m_state )
5444    {
5445        case M4xVSS_kStateSaving:
5446        //case M4xVSS_kStateGeneratingPreview:
5447            {
5448                if( xVSS_context->editingStep
5449                    == M4xVSS_kMicroStateEditing ) /* VSS -> creating effects, transitions ... */
5450                {
5451                    /* RC: to delete unecessary temp files on the fly */
5452                    M4VSS3GPP_InternalEditContext *pVSSContext =
5453                        (M4VSS3GPP_InternalEditContext *)pVssCtxt;
5454
5455                    err = M4VSS3GPP_editStep(pVssCtxt, &uiProgress);
5456
5457                    if( ( err != M4NO_ERROR) && (err != M4VSS3GPP_WAR_EDITING_DONE)
5458                        && (err != M4VSS3GPP_WAR_SWITCH_CLIP) )
5459                    {
5460                        M4OSA_TRACE1_1(
5461                            "M4xVSS_Step: M4VSS3GPP_editStep returned 0x%x\n", err);
5462                        M4VSS3GPP_editCleanUp(pVssCtxt);
5463                        /* TODO ? : Translate error code of VSS to an xVSS error code ? */
5464                        xVSS_context->pCurrentEditContext = M4OSA_NULL;
5465                        return err;
5466                    }
5467
5468                    /* RC: to delete unecessary temp files on the fly */
5469                    if( err == M4VSS3GPP_WAR_SWITCH_CLIP )
5470                    {
5471#ifndef DO_NOT_REMOVE_TEMP_FILES
5472                        /* It means we can delete the temporary file */
5473                        /* First step, check the temp file is not use somewhere else after */
5474
5475                        M4OSA_UInt32 i;
5476                        M4OSA_Int32 cmpResult = -1;
5477
5478                        for ( i = pVSSContext->uiCurrentClip;
5479                            i < pVSSContext->uiClipNumber; i++ )
5480                        {
5481                            if( pVSSContext->pClipList[pVSSContext->uiCurrentClip
5482                                - 1].filePathSize
5483                                == pVSSContext->pClipList[i].filePathSize )
5484                            {
5485                                cmpResult = memcmp((void *)pVSSContext->
5486                                    pClipList[pVSSContext->uiCurrentClip
5487                                    - 1].pFile, (void *)pVSSContext->pClipList[i].pFile,
5488                                    pVSSContext->
5489                                    pClipList[pVSSContext->uiCurrentClip
5490                                    - 1].filePathSize);
5491
5492                                if( cmpResult == 0 )
5493                                {
5494                                    /* It means we found a corresponding file, we do not delete
5495                                    this temporary file */
5496                                    break;
5497                                }
5498                            }
5499                        }
5500
5501                        if( cmpResult != 0 )
5502                        {
5503                            M4OSA_UInt32 ConvertedSize = 0;
5504                            M4OSA_Char *toto;
5505                            M4OSA_Char *pTmpStr;
5506
5507                            /* Convert result in UTF8 to check if we can delete it or not */
5508                            if( xVSS_context->UTFConversionContext.pConvToUTF8Fct
5509                                != M4OSA_NULL && xVSS_context->
5510                                UTFConversionContext.
5511                                pTempOutConversionBuffer != M4OSA_NULL )
5512                            {
5513                                M4xVSS_internalConvertToUTF8(xVSS_context,
5514                                    (M4OSA_Void *)pVSSContext->
5515                                    pClipList[pVSSContext->uiCurrentClip
5516                                    - 1].pFile, (M4OSA_Void *)xVSS_context->
5517                                    UTFConversionContext.
5518                                    pTempOutConversionBuffer, &ConvertedSize);
5519                                toto = (M4OSA_Char *)strstr((const char *)xVSS_context->
5520                                    UTFConversionContext.
5521                                    pTempOutConversionBuffer,
5522                                    (const char *)xVSS_context->pTempPath);
5523                                pTmpStr =
5524                                    xVSS_context->UTFConversionContext.
5525                                    pTempOutConversionBuffer;
5526                            }
5527                            else
5528                            {
5529                                toto = (M4OSA_Char *)strstr((const char *)pVSSContext->
5530                                    pClipList[pVSSContext->uiCurrentClip
5531                                    - 1].pFile, (const char *)xVSS_context->pTempPath);
5532                                pTmpStr = pVSSContext->
5533                                    pClipList[pVSSContext->uiCurrentClip
5534                                    - 1].pFile;
5535                            }
5536
5537                            if( toto != M4OSA_NULL )
5538                            {
5539                                /* As temporary files can be imgXXX.3gp or vidXXX.3gp */
5540                                pTmpStr +=
5541                                    (strlen((const char *)pTmpStr)
5542                                    - 10); /* Because temporary files have a length at most of
5543                                    10 bytes */
5544                                toto = (M4OSA_Char *)strstr((const char *)pTmpStr,
5545                                    (const char *)"img");
5546
5547                                if( toto != M4OSA_NULL )
5548                                {
5549                                    toto = (M4OSA_Char *)strstr((const char *)pTmpStr,
5550                                        (const char *)"vid");
5551                                }
5552
5553                                if( err
5554                                    == M4NO_ERROR ) /* It means the file is a temporary file, we
5555                                    can delete it */
5556                                {
5557                                    remove((const char *)pVSSContext->
5558                                        pClipList[pVSSContext->uiCurrentClip
5559                                        - 1].pFile);
5560                                }
5561                            }
5562                        }
5563
5564#endif /* DO_NOT_REMOVE_TEMP_FILES*/
5565                        /* */
5566
5567                        err = M4NO_ERROR;
5568                    }
5569
5570                    if( err == M4VSS3GPP_WAR_EDITING_DONE )
5571                    {
5572                        xVSS_context->currentStep++;
5573                        /* P4ME00003276: When a step is complete, increment currentStep and reset
5574                        uiProgress unless progress would be wrong */
5575                        uiProgress = 0;
5576                        err = M4xVSS_internalCloseEditedFile(xVSS_context);
5577                        /* Fix for  blrnxpsw#234---> */
5578                        if( err != M4NO_ERROR )
5579                        {
5580                            if( err == ((M4OSA_UInt32)M4ERR_FILE_INVALID_POSITION) )
5581                            {
5582                                err = M4xVSSERR_NO_MORE_SPACE;
5583                            }
5584                            M4OSA_TRACE1_1(
5585                                "M4xVSS_internalCloseEditedFile returned an error: 0x%x",
5586                                err);
5587                            return err;
5588                        }
5589                        /*<---- Fix for  blrnxpsw#234 */
5590                        if( xVSS_context->pCurrentEditSettings->xVSS.pBGMtrack
5591                            != M4OSA_NULL )
5592                        {
5593                            xVSS_context->editingStep =
5594                                M4xVSS_kMicroStateAudioMixing;
5595                            /* Open Audio mixing component */
5596                            err = M4xVSS_internalGenerateAudioMixFile(xVSS_context);
5597
5598                            if( err != M4NO_ERROR )
5599                            {
5600                                M4OSA_TRACE1_1(
5601                                    "M4xVSS_internalGenerateAudioMixFile returned an error: 0x%x",
5602                                    err);
5603                                /* TODO ? : Translate error code of VSS to an xVSS error code */
5604                                return err;
5605                            }
5606                            err = M4NO_ERROR;
5607                            goto end_step;
5608                        }
5609                        else
5610                        {
5611
5612                            err = M4VSS3GPP_WAR_SAVING_DONE;
5613                            goto end_step;
5614
5615                        }
5616                    }
5617                }
5618                else if( xVSS_context->editingStep
5619                    == M4xVSS_kMicroStateAudioMixing ) /* Audio mixing: mix/replace audio track
5620                    with given BGM */
5621                {
5622                    err = M4VSS3GPP_audioMixingStep(pAudioMixingCtxt, &uiProgress);
5623
5624                    if( ( err != M4NO_ERROR)
5625                        && (err != M4VSS3GPP_WAR_END_OF_AUDIO_MIXING) )
5626                    {
5627                        M4OSA_TRACE1_1(
5628                            "M4VSS3GPP_audioMixingMain: M4VSS3GPP_audioMixingStep returned 0x%x\n",
5629                            err);
5630                        /* TODO ? : Translate error code of VSS to an xVSS error code */
5631                        return err;
5632                    }
5633
5634                    if( err == M4VSS3GPP_WAR_END_OF_AUDIO_MIXING )
5635                    {
5636                        xVSS_context->currentStep++;
5637                        /* P4ME00003276: When a step is complete, increment currentStep and reset
5638                        uiProgress unless progress would be wrong */
5639                        uiProgress = 0;
5640                        err = M4xVSS_internalCloseAudioMixedFile(xVSS_context);
5641
5642                        if( err != M4NO_ERROR )
5643                        {
5644                            M4OSA_TRACE1_1(
5645                                "M4xVSS_internalCloseAudioMixedFile returned an error: 0x%x",
5646                                err);
5647                            /* TODO ? : Translate error code of VSS to an xVSS error code */
5648                            return err;
5649                        }
5650
5651                            err = M4VSS3GPP_WAR_SAVING_DONE;
5652                            goto end_step;
5653
5654                    }
5655                }
5656                else
5657                {
5658                    M4OSA_TRACE1_0("Bad state in step function !");
5659                    return M4ERR_STATE;
5660                }
5661            }
5662            break;
5663
5664        case M4xVSS_kStateAnalyzing:
5665            {
5666                if( xVSS_context->analyseStep
5667                    == M4xVSS_kMicroStateAnalysePto3GPP ) /* Pto3GPP, analysing input parameters */
5668                {
5669                    if( xVSS_context->pPTo3GPPcurrentParams == M4OSA_NULL
5670                        && xVSS_context->pPTo3GPPparamsList != M4OSA_NULL )
5671                    {
5672                        xVSS_context->pPTo3GPPcurrentParams =
5673                            xVSS_context->
5674                            pPTo3GPPparamsList; /* Current Pto3GPP Parameter is the first element
5675                            of the list */
5676                    }
5677                    else if( xVSS_context->pPTo3GPPcurrentParams != M4OSA_NULL
5678                        && xVSS_context->pPTo3GPPparamsList != M4OSA_NULL )
5679                    {
5680                        xVSS_context->pPTo3GPPcurrentParams =
5681                            xVSS_context->pPTo3GPPcurrentParams->
5682                            pNext; /* Current Pto3GPP Parameter is the next element of the list */
5683
5684                        if( xVSS_context->pPTo3GPPcurrentParams
5685                            == M4OSA_NULL ) /* It means there is no next image to convert */
5686                        {
5687                            /* We step to MCS phase */
5688                            xVSS_context->analyseStep =
5689                                M4xVSS_kMicroStateAnalyzeMCS;
5690                            err = M4NO_ERROR;
5691                            goto end_step;
5692                        }
5693                    }
5694                    else if( xVSS_context->pPTo3GPPparamsList == M4OSA_NULL )
5695                    {
5696                        xVSS_context->analyseStep =
5697                            M4xVSS_kMicroStateAnalyzeMCS; /* Change Analyzing micro state to
5698                             MCS phase */
5699                        err = M4NO_ERROR;
5700                        goto end_step;
5701                    }
5702
5703                    /* Check if this file has to be converted or not */
5704                    /* If not, we just return M4NO_ERROR, and go to next file */
5705                    if( xVSS_context->pPTo3GPPcurrentParams->isCreated
5706                        == M4OSA_FALSE )
5707                    {
5708                        /* Opening Pto3GPP */
5709                        err = M4xVSS_internalStartConvertPictureTo3gp(xVSS_context);
5710
5711                        if( err != M4NO_ERROR )
5712                        {
5713                            M4OSA_TRACE1_1("M4xVSS_Step: M4xVSS_internalStartConvertPictureTo3gp \
5714                            returned error: 0x%x",
5715                                err)
5716                                /* TODO ? : Translate error code of VSS to an xVSS error code */
5717                                return err;
5718                        }
5719                        xVSS_context->analyseStep =
5720                            M4xVSS_kMicroStateConvertPto3GPP;
5721                    }
5722                }
5723                else if( xVSS_context->analyseStep
5724                    == M4xVSS_kMicroStateConvertPto3GPP ) /* Pto3GPP, converting */
5725                {
5726                    err = M4PTO3GPP_Step(xVSS_context->pM4PTO3GPP_Ctxt);
5727                    /* update progress bar */
5728                    if(xVSS_context->pCallBackCtxt->m_NbImage > 1)
5729                    {
5730                        uiProgress = (xVSS_context->pCallBackCtxt->m_ImageCounter * 100) / (xVSS_context->pCallBackCtxt->m_NbImage -1);
5731                    }
5732
5733                    if( ( err != M4NO_ERROR) && (err
5734                        != ((M4OSA_UInt32)M4PTO3GPP_WAR_END_OF_PROCESSING)) )
5735                    {
5736                        /* TO BE CHECKED NO LEAKS  !!!!! */
5737                        M4OSA_TRACE1_1(
5738                            "M4xVSS_Step: M4PTO3GPP_Step returned 0x%x\n", err);
5739                        /* TODO ? : Translate error code of VSS to an xVSS error code */
5740                        return err;
5741                    }
5742                    else if( err
5743                        == ((M4OSA_UInt32)M4PTO3GPP_WAR_END_OF_PROCESSING) )
5744                    {
5745                        xVSS_context->currentStep++;
5746                        /* P4ME00003276: When a step is complete, increment currentStep and reset
5747                         uiProgress unless progress would be wrong */
5748                        uiProgress = 0;
5749                        xVSS_context->analyseStep =
5750                            M4xVSS_kMicroStateAnalysePto3GPP; /* We go back to analyze parameters
5751                            to see if there is a next file to convert */
5752                        /* RC !!!!!!!! */
5753                        xVSS_context->pPTo3GPPcurrentParams->isCreated =
5754                            M4OSA_TRUE; /* To avoid reconverting it if another SendCommand is
5755                            called */
5756                        err = M4xVSS_internalStopConvertPictureTo3gp(xVSS_context);
5757                        /*SS:blrnxpsw#  234 */
5758                        if( err == ((M4OSA_UInt32)M4ERR_FILE_INVALID_POSITION) )
5759                        {
5760                            err = M4xVSSERR_NO_MORE_SPACE;
5761                        }
5762
5763                        if( err != M4NO_ERROR )
5764                        {
5765                            M4OSA_TRACE1_1("M4xVSS_Step:\
5766                                           M4xVSS_internalStopConvertPictureTo3gp returned 0x%x",
5767                                            err);
5768                            /* TODO ? : Translate error code of VSS to an xVSS error code */
5769                            return err;
5770                        }
5771                    }
5772                }
5773                else if( xVSS_context->analyseStep
5774                    ==
5775                    M4xVSS_kMicroStateAnalyzeMCS ) /* MCS: analyzing input parameters */
5776                {
5777                    if( xVSS_context->pMCScurrentParams == M4OSA_NULL \
5778                        && xVSS_context->pMCSparamsList != M4OSA_NULL )
5779                    {
5780                        xVSS_context->pMCScurrentParams = xVSS_context->
5781                            pMCSparamsList; /* Current MCS Parameter is the first
5782                                            element of the list */
5783                    }
5784                    else if( xVSS_context->pMCScurrentParams != M4OSA_NULL \
5785                        && xVSS_context->pMCSparamsList != M4OSA_NULL )
5786                    {
5787                        xVSS_context->pMCScurrentParams =
5788                            xVSS_context->pMCScurrentParams->
5789                            pNext; /* Current MCS Parameter
5790                                   is the next element of the list */
5791
5792                        if( xVSS_context->pMCScurrentParams == M4OSA_NULL )
5793                            /* It means there is no next image to convert */
5794                        {
5795                            xVSS_context->analyseStep =
5796                                M4xVSS_kMicroStateAnalysePto3GPP; /* Reinit Analyzing micro state */
5797                            xVSS_context->m_state =
5798                                M4xVSS_kStateOpened; /* Change xVSS state */
5799                            err = M4VSS3GPP_WAR_ANALYZING_DONE;
5800                            goto end_step; /* End of Analysis */
5801                        }
5802                    }
5803                    else if( xVSS_context->pMCSparamsList == M4OSA_NULL )
5804                    {
5805                        xVSS_context->analyseStep =
5806                            M4xVSS_kMicroStateAnalysePto3GPP; /* Reinit Analyzing micro state */
5807                        xVSS_context->m_state =
5808                            M4xVSS_kStateOpened; /* Change xVSS state */
5809                        err = M4VSS3GPP_WAR_ANALYZING_DONE;
5810                        goto end_step;                        /* End of Analysis */
5811                    }
5812
5813                    /* Check if this file has to be transcoded or not */
5814                    /* If not, we just return M4NO_ERROR, and go to next file */
5815                    if( xVSS_context->pMCScurrentParams->isCreated == M4OSA_FALSE )
5816                    {
5817                        /* Opening MCS */
5818                        M4OSA_UInt32 rotationDegree = 0;
5819                        err = M4xVSS_internalStartTranscoding(xVSS_context, &rotationDegree);
5820
5821                        if( err != M4NO_ERROR )
5822                        {
5823                            M4OSA_TRACE1_1("M4xVSS_Step: M4xVSS_internalStartTranscoding returned\
5824                                 error: 0x%x", err);
5825                            return err;
5826                        }
5827                        int32_t index = xVSS_context->pMCScurrentParams->videoclipnumber;
5828
5829                        /* The cuts are done in the MCS, so we need to replace
5830                           the beginCutTime and endCutTime to keep the entire video*/
5831                        xVSS_context->pSettings->pClipList[index]->uiBeginCutTime = 0;
5832                        xVSS_context->pSettings->pClipList[index]->uiEndCutTime = 0;
5833
5834
5835                        M4OSA_TRACE1_1("M4xVSS_Step: \
5836                            M4xVSS_internalStartTranscoding returned \
5837                                success; MCS context: 0x%x",
5838                                 xVSS_context->pMCS_Ctxt);
5839                        xVSS_context->analyseStep =
5840                            M4xVSS_kMicroStateTranscodeMCS;
5841
5842                        // Retain rotation info of trimmed / transcoded file
5843                        xVSS_context->pSettings->pClipList[index]->\
5844                            ClipProperties.videoRotationDegrees = rotationDegree;
5845                    }
5846                }
5847                else if( xVSS_context->analyseStep
5848                    == M4xVSS_kMicroStateTranscodeMCS )
5849                    /* MCS: transcoding file */
5850                {
5851                    err = M4MCS_step(xVSS_context->pMCS_Ctxt, &uiProgress);
5852                    /*SS:blrnxpsw#  234 */
5853                    if( err == ((M4OSA_UInt32)M4MCS_ERR_NOMORE_SPACE) )
5854                    {
5855                        err = M4xVSSERR_NO_MORE_SPACE;
5856                    }
5857
5858                    if( ( err != M4NO_ERROR)
5859                        && (err != M4MCS_WAR_TRANSCODING_DONE) )
5860                    {
5861                        /* TO BE CHECKED NO LEAKS  !!!!! */
5862                        M4OSA_TRACE1_1("M4xVSS_Step: M4MCS_step returned 0x%x\n",
5863                            err);
5864                        /* TODO ? : Translate error code of MCS to an xVSS error code ? */
5865                        return err;
5866                    }
5867                    else if( err == M4MCS_WAR_TRANSCODING_DONE )
5868                    {
5869                        xVSS_context->currentStep++;
5870                        /* P4ME00003276: When a step is complete, increment currentStep and reset
5871                        uiProgress unless progress would be wrong */
5872                        uiProgress = 0;
5873                        xVSS_context->analyseStep =
5874                            M4xVSS_kMicroStateAnalyzeMCS; /* We go back to
5875                                                          analyze parameters to see if there is
5876                                                           a next file to transcode */
5877                        /* RC !!!!!!!!!*/
5878                        xVSS_context->pMCScurrentParams->isCreated =
5879                            M4OSA_TRUE; /* To avoid
5880                                        reconverting it if another SendCommand is called */
5881                        err = M4xVSS_internalStopTranscoding(xVSS_context);
5882
5883                        if( err != M4NO_ERROR )
5884                        {
5885                            M4OSA_TRACE1_1("M4xVSS_Step:\
5886                                           M4xVSS_internalStopTranscoding returned 0x%x", err);
5887                            /* TODO ? : Translate error code of MCS to an xVSS error code ? */
5888                            return err;
5889                        }
5890                    }
5891                }
5892                else
5893                {
5894                    M4OSA_TRACE1_0("Bad micro state in analyzing state")
5895                        return M4ERR_STATE;
5896                }
5897            }
5898            break;
5899
5900        default:
5901            M4OSA_TRACE1_1(
5902                "Bad state when calling M4xVSS_Step function! State is %d",
5903                xVSS_context->m_state);
5904            return M4ERR_STATE;
5905    }
5906
5907end_step:
5908    /* Compute progression */
5909    if( xVSS_context->nbStepTotal != 0 )
5910    {
5911        *pProgress = (M4OSA_UInt8)(( ( xVSS_context->currentStep * 100) \
5912            / (xVSS_context->nbStepTotal))
5913            + (uiProgress / (xVSS_context->nbStepTotal)));
5914
5915        if( *pProgress > 100 )
5916        {
5917            *pProgress = 100;
5918        }
5919    }
5920    else
5921    {
5922        *pProgress = 100;
5923    }
5924
5925    return err;
5926}
5927
5928/**
5929 ******************************************************************************
5930 * prototype    M4OSA_ERR M4xVSS_CloseCommand(M4OSA_Context pContext)
5931 * @brief        This function deletes current editing profile, unallocate
5932 *                ressources and change xVSS internal state.
5933 * @note        After this function, the user can call a new M4xVSS_SendCommand
5934 *
5935 * @param    pContext            (IN) Pointer on the xVSS edit context
5936 * @return    M4NO_ERROR:            No error
5937 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
5938 * @return    M4ERR_STATE:        This function cannot not be called at this time
5939 ******************************************************************************
5940 */
5941M4OSA_ERR M4xVSS_CloseCommand( M4OSA_Context pContext )
5942{
5943    M4xVSS_Context *xVSS_context = (