M4xVSS_API.c revision eaf349aaffc89c3ff754ddef856c80097b5a79a2
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
2072    replaceARGB_3GP:
2073                        /* Update total duration */
2074                        totalDuration += pParams->duration;
2075
2076                        /* Replacing in VSS structure the JPG file by the 3gp file */
2077                        xVSS_context->pSettings->pClipList[i]->FileType =
2078                            M4VIDEOEDITING_kFileType_3GPP;
2079
2080                        if( xVSS_context->pSettings->pClipList[i]->pFile != M4OSA_NULL )
2081                        {
2082                            free(xVSS_context->pSettings->pClipList[i]->pFile);
2083                            xVSS_context->pSettings->pClipList[i]->pFile = M4OSA_NULL;
2084                        }
2085
2086                        /**
2087                        * UTF conversion: convert into UTF8, before being used*/
2088                        pDecodedPath = pParams->pFileOut;
2089
2090                        if( xVSS_context->UTFConversionContext.pConvToUTF8Fct != M4OSA_NULL
2091                            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
2092                            != M4OSA_NULL )
2093                        {
2094                            err = M4xVSS_internalConvertToUTF8(xVSS_context,
2095                                (M4OSA_Void *)pParams->pFileOut,
2096                                (M4OSA_Void *)xVSS_context->
2097                                UTFConversionContext.pTempOutConversionBuffer,
2098                                &length);
2099
2100                            if( err != M4NO_ERROR )
2101                            {
2102                                M4OSA_TRACE1_1(
2103                                    "M4xVSS_SendCommand: M4xVSS_internalConvertToUTF8 returns err: \
2104                                    0x%x",err);
2105                                /* Free Send command */
2106                                M4xVSS_freeCommand(xVSS_context);
2107                                return err;
2108                            }
2109                            pDecodedPath =
2110                                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
2111                        }
2112                        else
2113                        {
2114                            length = strlen(pDecodedPath);
2115                        }
2116                        /**
2117                        * End of the UTF conversion, use the converted file path*/
2118                        xVSS_context->pSettings->pClipList[i]->pFile = M4OSA_32bitAlignedMalloc((length
2119                            + 1), M4VS, (M4OSA_Char *)"xVSS file path of ARGB to 3gp");
2120
2121                        if( xVSS_context->pSettings->pClipList[i]->pFile == M4OSA_NULL )
2122                        {
2123                            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
2124                            /*FB: to avoid leaks when there is an error in the send command*/
2125                            /* Free Send command */
2126                            M4xVSS_freeCommand(xVSS_context);
2127                            /**/
2128                            return M4ERR_ALLOC;
2129                        }
2130                        memcpy((void *)xVSS_context->pSettings->pClipList[i]->pFile,
2131                            (void *)pDecodedPath, (length + 1));
2132                        /*FB: add file path size because of UTF16 conversion*/
2133                        xVSS_context->pSettings->pClipList[i]->filePathSize = length+1;
2134            }
2135        }
2136        /************************
2137        3GP input file type case
2138        *************************/
2139        else if( xVSS_context->pSettings->pClipList[i]->FileType
2140            == M4VIDEOEDITING_kFileType_3GPP
2141            || xVSS_context->pSettings->pClipList[i]->FileType
2142            == M4VIDEOEDITING_kFileType_MP4
2143            || xVSS_context->pSettings->pClipList[i]->FileType
2144            == M4VIDEOEDITING_kFileType_M4V )
2145        {
2146            /*UTF conversion support*/
2147            M4OSA_Void *pDecodedPath = M4OSA_NULL;
2148
2149            /* Need to call MCS in case 3GP video/audio types are not compatible
2150            (H263/MPEG4 or AMRNB/AAC) */
2151            /* => Need to fill MCS_Params structure with the right parameters ! */
2152            /* Need also to parse MCS params struct to check if file has already been transcoded */
2153
2154            M4VIDEOEDITING_ClipProperties fileProperties;
2155            M4xVSS_MCS_params *pParams;
2156            M4OSA_Bool audioIsDifferent = M4OSA_FALSE;
2157            M4OSA_Bool videoIsDifferent = M4OSA_FALSE;
2158            M4OSA_Bool bAudioMono;
2159            /* Initialize file properties structure */
2160
2161            memset((void *) &fileProperties,0,
2162                sizeof(M4VIDEOEDITING_ClipProperties));
2163
2164            //fileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio;
2165
2166            /* Prevent from bad initializing of percentage cut time */
2167            if( xVSS_context->pSettings->pClipList[i]->xVSS.uiEndCutPercent
2168                            > 100 || xVSS_context->pSettings->pClipList[i]->xVSS.
2169                            uiBeginCutPercent > 100 )
2170            {
2171                /* These percentage cut time have probably not been initialized */
2172                /* Let's not use them by setting them to 0 */
2173                xVSS_context->pSettings->pClipList[i]->xVSS.uiEndCutPercent = 0;
2174                xVSS_context->pSettings->pClipList[i]->xVSS.uiBeginCutPercent =
2175                    0;
2176            }
2177
2178            /**
2179            * UTF conversion: convert into the customer format, before being used*/
2180            pDecodedPath = xVSS_context->pSettings->pClipList[i]->pFile;
2181
2182            if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
2183                != M4OSA_NULL && xVSS_context->
2184                UTFConversionContext.pTempOutConversionBuffer
2185                != M4OSA_NULL )
2186            {
2187                err = M4xVSS_internalConvertFromUTF8(xVSS_context, (M4OSA_Void
2188                    *)xVSS_context->pSettings->pClipList[i]->pFile,
2189                    (M4OSA_Void *)xVSS_context->
2190                    UTFConversionContext.pTempOutConversionBuffer,
2191                    &length);
2192
2193                if( err != M4NO_ERROR )
2194                {
2195                    M4OSA_TRACE1_1(
2196                        "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
2197                        err);
2198                    /* Free Send command */
2199                    M4xVSS_freeCommand(xVSS_context);
2200                    return err;
2201                }
2202                pDecodedPath =
2203                    xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
2204            }
2205            /**
2206            * End of the UTF conversion, use the converted file path*/
2207            err = M4xVSS_internalGetProperties(xVSS_context, pDecodedPath,
2208                &fileProperties);
2209
2210            if( err != M4NO_ERROR )
2211            {
2212                M4xVSS_freeCommand(xVSS_context);
2213                M4OSA_TRACE1_1(
2214                    "M4xVSS_sendCommand: M4xVSS_internalGetProperties returned 0x%x",
2215                    err);
2216                /* TODO: Translate error code of MCS to an xVSS error code */
2217                return err;
2218            }
2219
2220            /* Parse MCS params chained list to know if input file has already been converted */
2221            if( xVSS_context->pMCSparamsList != M4OSA_NULL )
2222            {
2223                M4OSA_UInt32 pCmpResult = 0;
2224
2225                pParams = xVSS_context->pMCSparamsList;
2226                /* We parse all MCS Param chained list */
2227                while( pParams != M4OSA_NULL )
2228                {
2229
2230                    /**
2231                    * UTF conversion: convert into UTF8, before being used*/
2232                    pDecodedPath = pParams->pFileIn;
2233
2234                    if( xVSS_context->UTFConversionContext.pConvToUTF8Fct
2235                        != M4OSA_NULL && xVSS_context->
2236                        UTFConversionContext.pTempOutConversionBuffer
2237                        != M4OSA_NULL )
2238                    {
2239                        err = M4xVSS_internalConvertToUTF8(xVSS_context,
2240                            (M4OSA_Void *)pParams->pFileIn,
2241                            (M4OSA_Void *)xVSS_context->
2242                            UTFConversionContext.
2243                            pTempOutConversionBuffer, &length);
2244
2245                        if( err != M4NO_ERROR )
2246                        {
2247                            M4OSA_TRACE1_1(
2248                                "M4xVSS_SendCommand: M4xVSS_internalConvertToUTF8 returns err:\
2249                                 0x%x", err);
2250                            /* Free Send command */
2251                            M4xVSS_freeCommand(xVSS_context);
2252                            return err;
2253                        }
2254                        pDecodedPath = xVSS_context->
2255                            UTFConversionContext.pTempOutConversionBuffer;
2256                    }
2257
2258                    /**
2259                    * End of the UTF conversion, use the converted file path*/
2260                    pCmpResult = strcmp((const char *)pSettings->pClipList[i]->pFile,
2261                        (const char *)pDecodedPath);
2262
2263                    /* If input filenames are the same, and if this is not a BGM, we can reuse
2264                    the transcoded file */
2265                    if( pCmpResult == 0 && pParams->isBGM == M4OSA_FALSE
2266                        && pParams->BeginCutTime
2267                        == pSettings->pClipList[i]->uiBeginCutTime
2268                        && (pParams->EndCutTime
2269                        == pSettings->pClipList[i]->uiEndCutTime
2270                        || pParams->EndCutTime
2271                        == pSettings->pClipList[i]->uiBeginCutTime
2272                        + pSettings->pClipList[i]->xVSS.uiDuration)
2273                        && pSettings->pClipList[i]->xVSS.MediaRendering
2274                        == pParams->MediaRendering )
2275                    {
2276                        if( pSettings->xVSS.pBGMtrack != M4OSA_NULL )
2277                        {
2278                            if( pSettings->xVSS.pBGMtrack->uiAddVolume == 100
2279                                || (pParams->OutputAudioFormat
2280                                == M4VIDEOEDITING_kNullAudio
2281                                && fileProperties.AudioStreamType
2282                                == pSettings->xVSS.outputAudioFormat)
2283                                || pParams->OutputAudioFormat
2284                                == pSettings->xVSS.outputAudioFormat
2285                                || fileProperties.AudioStreamType
2286                                == M4VIDEOEDITING_kNoneAudio )
2287                            {
2288                                /* Replace 3GP filename with transcoded 3GP filename */
2289                                goto replace3GP_3GP;
2290                            }
2291                        }
2292                        else if( ( pParams->OutputAudioFormat
2293                            == M4VIDEOEDITING_kNullAudio
2294                            && fileProperties.AudioStreamType
2295                            == pSettings->xVSS.outputAudioFormat)
2296                            || pParams->OutputAudioFormat
2297                            == pSettings->xVSS.outputAudioFormat
2298                            || fileProperties.AudioStreamType
2299                            == M4VIDEOEDITING_kNoneAudio )
2300                        {
2301                            /* Replace 3GP filename with transcoded 3GP filename */
2302                            goto replace3GP_3GP;
2303                        }
2304                    }
2305
2306                    /* We need to update this variable, in case some 3GP files have been added
2307                    between two */
2308                    /* calls to M4xVSS_sendCommand */
2309                    pMCS_last = pParams;
2310                    pParams = pParams->pNext;
2311                }
2312            }
2313
2314            /* If we have percentage information let's use it... */
2315            if( xVSS_context->pSettings->pClipList[i]->xVSS.uiEndCutPercent != 0
2316                || xVSS_context->pSettings->pClipList[i]->xVSS.uiBeginCutPercent
2317                != 0 )
2318            {
2319                /* If percentage information are not correct and if duration field is not filled */
2320                if( ( xVSS_context->pSettings->pClipList[i]->xVSS.
2321                    uiEndCutPercent
2322                    <= xVSS_context->pSettings->pClipList[i]->xVSS.
2323                    uiBeginCutPercent)
2324                    && xVSS_context->pSettings->pClipList[i]->xVSS.uiDuration
2325                    == 0 )
2326                {
2327                    M4OSA_TRACE1_0(
2328                        "M4xVSS_sendCommand: Bad percentage for begin and end cut time !");
2329                    M4xVSS_freeCommand(xVSS_context);
2330                    return M4ERR_PARAMETER;
2331                }
2332
2333                /* We transform the percentage into absolute time */
2334                xVSS_context->pSettings->pClipList[i]->uiBeginCutTime
2335                    = (M4OSA_UInt32)(
2336                    xVSS_context->pSettings->pClipList[i]->xVSS.
2337                    uiBeginCutPercent
2338                    * fileProperties.uiClipDuration / 100);
2339                xVSS_context->pSettings->pClipList[i]->uiEndCutTime
2340                    = (M4OSA_UInt32)(
2341                    xVSS_context->pSettings->pClipList[i]->xVSS.
2342                    uiEndCutPercent
2343                    * fileProperties.uiClipDuration / 100);
2344            }
2345            /* ...Otherwise, we use absolute time. */
2346            else
2347            {
2348                /* If endCutTime == 0, it means all the file is taken. Let's change to the file
2349                duration, to accurate preview. */
2350                if( xVSS_context->pSettings->pClipList[i]->uiEndCutTime == 0
2351                    || xVSS_context->pSettings->pClipList[i]->uiEndCutTime
2352                    > fileProperties.uiClipDuration )
2353                {
2354                    xVSS_context->pSettings->pClipList[i]->uiEndCutTime =
2355                        fileProperties.uiClipDuration;
2356                }
2357            }
2358
2359            /* If duration field is filled, it has priority on other fields on EndCutTime,
2360             so let's use it */
2361            if( xVSS_context->pSettings->pClipList[i]->xVSS.uiDuration != 0 )
2362            {
2363                xVSS_context->pSettings->pClipList[i]->uiEndCutTime =
2364                    xVSS_context->pSettings->pClipList[i]->uiBeginCutTime
2365                    +xVSS_context->pSettings->pClipList[i]->xVSS.uiDuration;
2366
2367                if( xVSS_context->pSettings->pClipList[i]->uiEndCutTime
2368                    > fileProperties.uiClipDuration )
2369                {
2370                    xVSS_context->pSettings->pClipList[i]->uiEndCutTime =
2371                        fileProperties.uiClipDuration;
2372                }
2373            }
2374
2375            /* If output video format is not set, we take video format of the first 3GP video */
2376            if( xVSS_context->pSettings->xVSS.outputVideoFormat
2377                == M4VIDEOEDITING_kNoneVideo )
2378            {
2379                //xVSS_context->pSettings->xVSS.outputVideoFormat = fileProperties.VideoStreamType;
2380                //M4OSA_TRACE2_1("Output video format is not set, set it to current clip: %d",
2381                // xVSS_context->pSettings->xVSS.outputVideoFormat);
2382                M4OSA_TRACE1_0(
2383                    "Output video format is not set, an error parameter is returned.");
2384                M4xVSS_freeCommand(xVSS_context);
2385                return M4ERR_PARAMETER;
2386            }
2387
2388            if( xVSS_context->pSettings->xVSS.outputAudioFormat
2389                == M4VIDEOEDITING_kNoneAudio )
2390            {
2391                //xVSS_context->pSettings->xVSS.outputAudioFormat = fileProperties.AudioStreamType;
2392                M4OSA_TRACE2_1(
2393                    "Output audio format is not set -> remove audio track of clip: %d",
2394                    i);
2395            }
2396
2397            if( fileProperties.uiNbChannels == 1 )
2398            {
2399                bAudioMono = M4OSA_TRUE;
2400            }
2401            else
2402            {
2403                bAudioMono = M4OSA_FALSE;
2404            }
2405
2406            if( fileProperties.AudioStreamType
2407                != xVSS_context->pSettings->xVSS.outputAudioFormat
2408                || (fileProperties.AudioStreamType == M4VIDEOEDITING_kAAC
2409                && (fileProperties.uiSamplingFrequency != samplingFreq
2410                || bAudioMono
2411                != xVSS_context->pSettings->xVSS.bAudioMono)) )
2412            {
2413                audioIsDifferent = M4OSA_TRUE;
2414                /* If we want to replace audio, there is no need to transcode audio */
2415                if( pSettings->xVSS.pBGMtrack != M4OSA_NULL )
2416                {
2417                    /* temp fix :PT volume not herad in the second clip */
2418                    if( /*(pSettings->xVSS.pBGMtrack->uiAddVolume == 100
2419                        && xVSS_context->pSettings->xVSS.outputFileSize == 0)
2420                        ||*/
2421                        fileProperties.AudioStreamType
2422                        == M4VIDEOEDITING_kNoneAudio ) /*11/12/2008 CR 3283 VAL for the MMS
2423                        use case, we need to transcode except the media without audio*/
2424                    {
2425                        audioIsDifferent = M4OSA_FALSE;
2426                    }
2427                }
2428                else if( fileProperties.AudioStreamType
2429                    == M4VIDEOEDITING_kNoneAudio )
2430                {
2431                    audioIsDifferent = M4OSA_FALSE;
2432                }
2433            }
2434            /* Here check the clip video profile and level, if it exceeds
2435             * the profile and level of export file, then the file need
2436             * to be transcoded(do not do compress domain trim) */
2437           if ((fileProperties.uiVideoProfile >
2438                     xVSS_context->pSettings->xVSS.outputVideoProfile) ||
2439                (fileProperties.uiVideoLevel >
2440                     xVSS_context->pSettings->xVSS.outputVideoLevel)) {
2441               /* Set bTranscodingRequired to TRUE to indicate the video will be
2442                * transcoded in MCS. */
2443               xVSS_context->pSettings->pClipList[i]->bTranscodingRequired =
2444                   M4OSA_TRUE;
2445               videoIsDifferent = M4OSA_TRUE;
2446           }
2447
2448            if( videoIsDifferent == M4OSA_TRUE || audioIsDifferent == M4OSA_TRUE)
2449            {
2450                M4OSA_Char out_3gp[M4XVSS_MAX_PATH_LEN];
2451                M4OSA_Char out_3gp_tmp[M4XVSS_MAX_PATH_LEN];
2452
2453                /* Construct output temporary 3GP filename */
2454                err = M4OSA_chrSPrintf(out_3gp, M4XVSS_MAX_PATH_LEN - 1, (M4OSA_Char *)"%svid%d.3gp",
2455                    xVSS_context->pTempPath, xVSS_context->tempFileIndex);
2456
2457                if( err != M4NO_ERROR )
2458                {
2459                    M4OSA_TRACE1_1("Error in M4OSA_chrSPrintf: 0x%x", err);
2460                    return err;
2461                }
2462
2463#ifdef M4xVSS_RESERVED_MOOV_DISK_SPACE
2464
2465                err = M4OSA_chrSPrintf(out_3gp_tmp, M4XVSS_MAX_PATH_LEN - 1, "%svid%d.tmp",
2466                    xVSS_context->pTempPath, xVSS_context->tempFileIndex);
2467
2468                if( err != M4NO_ERROR )
2469                {
2470                    M4OSA_TRACE1_1("Error in M4OSA_chrSPrintf: 0x%x", err);
2471                    return err;
2472                }
2473
2474#endif /*M4xVSS_RESERVED_MOOV_DISK_SPACE*/
2475
2476                xVSS_context->tempFileIndex++;
2477
2478                pParams =
2479                    (M4xVSS_MCS_params *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_MCS_params),
2480                    M4VS, (M4OSA_Char *)"Element of MCS Params (for 3GP)");
2481
2482                if( pParams == M4OSA_NULL )
2483                {
2484                    M4OSA_TRACE1_0(
2485                        "M4xVSS_sendCommand: Problem when allocating one element MCS Params");
2486                    /*FB: to avoid leaks when there is an error in the send command*/
2487                    /* Free Send command */
2488                    M4xVSS_freeCommand(xVSS_context);
2489                    /**/
2490                    return M4ERR_ALLOC;
2491                }
2492                pParams->MediaRendering = M4xVSS_kResizing;
2493                pParams->videoclipnumber = i; // Indicates video clip index
2494
2495                if( xVSS_context->pMCSparamsList
2496                    == M4OSA_NULL ) /* Means it is the first element of the list */
2497                {
2498                    /* Initialize the xVSS context with the first element of the list */
2499                    xVSS_context->pMCSparamsList = pParams;
2500                }
2501                else
2502                {
2503                    /* Update next pointer of the previous last element of the chain */
2504                    pMCS_last->pNext = pParams;
2505                }
2506
2507                /* Save this element in case of other file to convert */
2508                pMCS_last = pParams;
2509
2510                /* Fill the last M4xVSS_MCS_params element */
2511                pParams->InputFileType = M4VIDEOEDITING_kFileType_3GPP;
2512                pParams->OutputFileType = M4VIDEOEDITING_kFileType_3GPP;
2513
2514                pParams->OutputVideoTimescale = xVSS_context->targetedTimescale;
2515
2516                /* We do not need to reencode video if its parameters do not differ */
2517                /* from output settings parameters */
2518                if( videoIsDifferent == M4OSA_TRUE )
2519                {
2520                    pParams->OutputVideoFormat =
2521                        xVSS_context->pSettings->xVSS.outputVideoFormat;
2522                    pParams->outputVideoProfile =
2523                        xVSS_context->pSettings->xVSS.outputVideoProfile;
2524                    pParams->outputVideoLevel =
2525                        xVSS_context->pSettings->xVSS.outputVideoLevel;
2526                    pParams->OutputVideoFrameRate =
2527                        xVSS_context->pSettings->videoFrameRate;
2528                    pParams->OutputVideoFrameSize =
2529                        xVSS_context->pSettings->xVSS.outputVideoSize;
2530
2531                    /*FB: VAL CR P4ME00003076
2532                    The output video bitrate is now directly given by the user in the edition
2533                    settings structure If the bitrate given by the user is irrelevant
2534                    (the MCS minimum and maximum video bitrate are used),
2535                    the output video bitrate is hardcoded according to the output video size*/
2536                    if( xVSS_context->pSettings->xVSS.outputVideoBitrate
2537                        >= M4VIDEOEDITING_k16_KBPS
2538                        && xVSS_context->pSettings->xVSS.outputVideoBitrate
2539                        <= M4VIDEOEDITING_k8_MBPS ) /*+ New Encoder bitrates */
2540                    {
2541                        pParams->OutputVideoBitrate =
2542                            xVSS_context->pSettings->xVSS.outputVideoBitrate;
2543                    }
2544                    else
2545                    {
2546                        switch( xVSS_context->pSettings->xVSS.outputVideoSize )
2547                        {
2548                            case M4VIDEOEDITING_kSQCIF:
2549                                pParams->OutputVideoBitrate =
2550                                    M4VIDEOEDITING_k48_KBPS;
2551                                break;
2552
2553                            case M4VIDEOEDITING_kQQVGA:
2554                                pParams->OutputVideoBitrate =
2555                                    M4VIDEOEDITING_k64_KBPS;
2556                                break;
2557
2558                            case M4VIDEOEDITING_kQCIF:
2559                                pParams->OutputVideoBitrate =
2560                                    M4VIDEOEDITING_k128_KBPS;
2561                                break;
2562
2563                            case M4VIDEOEDITING_kQVGA:
2564                                pParams->OutputVideoBitrate =
2565                                    M4VIDEOEDITING_k384_KBPS;
2566                                break;
2567
2568                            case M4VIDEOEDITING_kCIF:
2569                                pParams->OutputVideoBitrate =
2570                                    M4VIDEOEDITING_k384_KBPS;
2571                                break;
2572
2573                            case M4VIDEOEDITING_kVGA:
2574                                pParams->OutputVideoBitrate =
2575                                    M4VIDEOEDITING_k512_KBPS;
2576                                break;
2577
2578                            default: /* Should not happen !! */
2579                                pParams->OutputVideoBitrate =
2580                                    M4VIDEOEDITING_k64_KBPS;
2581                                break;
2582                        }
2583                    }
2584                }
2585                else
2586                {
2587                    pParams->OutputVideoFormat = M4VIDEOEDITING_kNullVideo;
2588                    pParams->OutputVideoFrameRate =
2589                        M4VIDEOEDITING_k15_FPS; /* Must be set, otherwise, MCS returns an error */
2590                }
2591
2592                if( audioIsDifferent == M4OSA_TRUE )
2593                {
2594                    pParams->OutputAudioFormat =
2595                        xVSS_context->pSettings->xVSS.outputAudioFormat;
2596
2597                    switch( xVSS_context->pSettings->xVSS.outputAudioFormat )
2598                    {
2599                        case M4VIDEOEDITING_kNoneAudio:
2600                            break;
2601
2602                        case M4VIDEOEDITING_kAMR_NB:
2603                            pParams->OutputAudioBitrate =
2604                                M4VIDEOEDITING_k12_2_KBPS;
2605                            pParams->bAudioMono = M4OSA_TRUE;
2606                            pParams->OutputAudioSamplingFrequency =
2607                                M4VIDEOEDITING_kDefault_ASF;
2608                            break;
2609
2610                        case M4VIDEOEDITING_kAAC:
2611                            {
2612                                /*FB: VAL CR P4ME00003076
2613                                The output audio bitrate in the AAC case is now directly given by
2614                                the user in the edition settings structure
2615                                If the bitrate given by the user is irrelevant or undefined
2616                                (the MCS minimum and maximum audio bitrate are used),
2617                                the output audio bitrate is hard coded according to the output
2618                                audio sampling frequency*/
2619
2620                                /*Check if the audio bitrate is correctly defined*/
2621
2622                                /*Mono
2623                                MCS values for AAC Mono are min: 16kbps and max: 192 kbps*/
2624                                if( xVSS_context->pSettings->xVSS.outputAudioBitrate
2625                                    >= M4VIDEOEDITING_k16_KBPS
2626                                    && xVSS_context->pSettings->
2627                                    xVSS.outputAudioBitrate
2628                                    <= M4VIDEOEDITING_k192_KBPS
2629                                    && xVSS_context->pSettings->xVSS.bAudioMono
2630                                    == M4OSA_TRUE )
2631                                {
2632                                    pParams->OutputAudioBitrate =
2633                                        xVSS_context->pSettings->
2634                                        xVSS.outputAudioBitrate;
2635                                }
2636                                /*Stereo
2637                                MCS values for AAC Mono are min: 32kbps and max: 192 kbps*/
2638                                else if( xVSS_context->pSettings->
2639                                    xVSS.outputAudioBitrate
2640                                    >= M4VIDEOEDITING_k32_KBPS
2641                                    && xVSS_context->pSettings->
2642                                    xVSS.outputAudioBitrate
2643                                    <= M4VIDEOEDITING_k192_KBPS
2644                                    && xVSS_context->pSettings->xVSS.bAudioMono
2645                                    == M4OSA_FALSE )
2646                                {
2647                                    pParams->OutputAudioBitrate =
2648                                        xVSS_context->pSettings->
2649                                        xVSS.outputAudioBitrate;
2650                                }
2651
2652                                /*The audio bitrate is hard coded according to the output audio
2653                                 sampling frequency*/
2654                                else
2655                                {
2656                                    switch( xVSS_context->pSettings->
2657                                        xVSS.outputAudioSamplFreq )
2658                                    {
2659                                        case M4VIDEOEDITING_k16000_ASF:
2660                                            pParams->OutputAudioBitrate =
2661                                                M4VIDEOEDITING_k24_KBPS;
2662                                            break;
2663
2664                                        case M4VIDEOEDITING_k22050_ASF:
2665                                        case M4VIDEOEDITING_k24000_ASF:
2666                                            pParams->OutputAudioBitrate =
2667                                                M4VIDEOEDITING_k32_KBPS;
2668                                            break;
2669
2670                                        case M4VIDEOEDITING_k32000_ASF:
2671                                            pParams->OutputAudioBitrate =
2672                                                M4VIDEOEDITING_k48_KBPS;
2673                                            break;
2674
2675                                        case M4VIDEOEDITING_k44100_ASF:
2676                                        case M4VIDEOEDITING_k48000_ASF:
2677                                            pParams->OutputAudioBitrate =
2678                                                M4VIDEOEDITING_k64_KBPS;
2679                                            break;
2680
2681                                        default:
2682                                            pParams->OutputAudioBitrate =
2683                                                M4VIDEOEDITING_k64_KBPS;
2684                                            break;
2685                                    }
2686
2687                                    if( xVSS_context->pSettings->xVSS.bAudioMono
2688                                        == M4OSA_FALSE )
2689                                    {
2690                                        /* Output bitrate have to be doubled */
2691                                        pParams->OutputAudioBitrate +=
2692                                            pParams->OutputAudioBitrate;
2693                                    }
2694                                }
2695
2696                                pParams->bAudioMono =
2697                                    xVSS_context->pSettings->xVSS.bAudioMono;
2698
2699                                if( xVSS_context->pSettings->
2700                                    xVSS.outputAudioSamplFreq
2701                                    == M4VIDEOEDITING_k8000_ASF )
2702                                {
2703                                    /* Prevent from unallowed sampling frequencies */
2704                                    pParams->OutputAudioSamplingFrequency =
2705                                        M4VIDEOEDITING_kDefault_ASF;
2706                                }
2707                                else
2708                                {
2709                                    pParams->OutputAudioSamplingFrequency =
2710                                        xVSS_context->pSettings->
2711                                        xVSS.outputAudioSamplFreq;
2712                                }
2713                                break;
2714                            }
2715
2716                        default: /* Should not happen !! */
2717                            pParams->OutputAudioFormat = M4VIDEOEDITING_kAMR_NB;
2718                            pParams->OutputAudioBitrate =
2719                                M4VIDEOEDITING_k12_2_KBPS;
2720                            pParams->bAudioMono = M4OSA_TRUE;
2721                            pParams->OutputAudioSamplingFrequency =
2722                                M4VIDEOEDITING_kDefault_ASF;
2723                            break;
2724                        }
2725                }
2726                else
2727                {
2728                    pParams->OutputAudioFormat = M4VIDEOEDITING_kNullAudio;
2729                }
2730
2731                /**
2732                * UTF conversion: convert into the customer format, before being used*/
2733                pDecodedPath = xVSS_context->pSettings->pClipList[i]->pFile;
2734                length = strlen(pDecodedPath);
2735
2736                if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
2737                    != M4OSA_NULL && xVSS_context->
2738                    UTFConversionContext.pTempOutConversionBuffer
2739                    != M4OSA_NULL )
2740                {
2741                    err = M4xVSS_internalConvertFromUTF8(xVSS_context,
2742                        (M4OSA_Void *)xVSS_context->pSettings->
2743                        pClipList[i]->pFile,
2744                        (M4OSA_Void *)xVSS_context->
2745                        UTFConversionContext.pTempOutConversionBuffer,
2746                        &length);
2747
2748                    if( err != M4NO_ERROR )
2749                    {
2750                        M4OSA_TRACE1_1(
2751                            "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
2752                            err);
2753                        /* Free Send command */
2754                        M4xVSS_freeCommand(xVSS_context);
2755                        return err;
2756                    }
2757                    pDecodedPath = xVSS_context->
2758                        UTFConversionContext.pTempOutConversionBuffer;
2759                }
2760
2761                /**
2762                * End of the UTF conversion, use the converted file path*/
2763                pParams->pFileIn =
2764                    (M4OSA_Void *)M4OSA_32bitAlignedMalloc((length + 1), M4VS,
2765                    (M4OSA_Char *)"MCS 3GP Params: file in");
2766
2767                if( pParams->pFileIn == M4OSA_NULL )
2768                {
2769                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
2770                    /*FB: to avoid leaks when there is an error in the send command*/
2771                    /* Free Send command */
2772                    M4xVSS_freeCommand(xVSS_context);
2773                    /**/
2774                    return M4ERR_ALLOC;
2775                }
2776                memcpy((void *)pParams->pFileIn, (void *)pDecodedPath,
2777                    (length + 1)); /* Copy input file path */
2778
2779                /**
2780                * UTF conversion: convert into the customer format, before being used*/
2781                pDecodedPath = out_3gp;
2782                length = strlen(pDecodedPath);
2783
2784                if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
2785                    != M4OSA_NULL && xVSS_context->
2786                    UTFConversionContext.pTempOutConversionBuffer
2787                    != M4OSA_NULL )
2788                {
2789                    err = M4xVSS_internalConvertFromUTF8(xVSS_context,
2790                        (M4OSA_Void *)out_3gp, (M4OSA_Void *)xVSS_context->
2791                        UTFConversionContext.pTempOutConversionBuffer,
2792                        &length);
2793
2794                    if( err != M4NO_ERROR )
2795                    {
2796                        M4OSA_TRACE1_1(
2797                            "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
2798                            err);
2799                        /* Free Send command */
2800                        M4xVSS_freeCommand(xVSS_context);
2801                        return err;
2802                    }
2803                    pDecodedPath = xVSS_context->
2804                        UTFConversionContext.pTempOutConversionBuffer;
2805                }
2806
2807                /**
2808                * End of the UTF conversion, use the converted file path*/
2809                pParams->pFileOut =
2810                    (M4OSA_Void *)M4OSA_32bitAlignedMalloc((length + 1), M4VS,
2811                    (M4OSA_Char *)"MCS 3GP Params: file out");
2812
2813                if( pParams->pFileOut == M4OSA_NULL )
2814                {
2815                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
2816                    /*FB: to avoid leaks when there is an error in the send command*/
2817                    /* Free Send command */
2818                    M4xVSS_freeCommand(xVSS_context);
2819                    /**/
2820                    return M4ERR_ALLOC;
2821                }
2822                memcpy((void *)pParams->pFileOut, (void *)pDecodedPath,
2823                    (length + 1)); /* Copy output file path */
2824
2825#ifdef M4xVSS_RESERVED_MOOV_DISK_SPACE
2826                /**
2827                * UTF conversion: convert into the customer format, before being used*/
2828
2829                pDecodedPath = out_3gp_tmp;
2830                length = strlen(pDecodedPath);
2831
2832                if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
2833                    != M4OSA_NULL && xVSS_context->
2834                    UTFConversionContext.pTempOutConversionBuffer
2835                    != M4OSA_NULL )
2836                {
2837                    err = M4xVSS_internalConvertFromUTF8(xVSS_context,
2838                        (M4OSA_Void *)out_3gp_tmp,
2839                        (M4OSA_Void *)xVSS_context->
2840                        UTFConversionContext.pTempOutConversionBuffer,
2841                        &length);
2842
2843                    if( err != M4NO_ERROR )
2844                    {
2845                        M4OSA_TRACE1_1(
2846                            "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
2847                            err);
2848                        /* Free Send command */
2849                        M4xVSS_freeCommand(xVSS_context);
2850                        return err;
2851                    }
2852                    pDecodedPath = xVSS_context->
2853                        UTFConversionContext.pTempOutConversionBuffer;
2854                }
2855
2856                /**
2857                * End of the UTF conversion, use the converted file path*/
2858                pParams->pFileTemp =
2859                    (M4OSA_Void *)M4OSA_32bitAlignedMalloc((length + 1), M4VS,
2860                    (M4OSA_Char *)"MCS 3GP Params: file temp");
2861
2862                if( pParams->pFileTemp == M4OSA_NULL )
2863                {
2864                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
2865                    /*FB: to avoid leaks when there is an error in the send command*/
2866                    /* Free Send command */
2867                    M4xVSS_freeCommand(xVSS_context);
2868                    /**/
2869                    return M4ERR_ALLOC;
2870                }
2871                memcpy((void *)pParams->pFileTemp, (void *)pDecodedPath,
2872                    (length + 1)); /* Copy temporary file path */
2873
2874#else
2875
2876                pParams->pFileTemp = M4OSA_NULL;
2877
2878#endif /*M4xVSS_RESERVED_MOOV_DISK_SPACE*/
2879
2880                /*FB 2008/10/20 keep media aspect ratio, add media rendering parameter*/
2881
2882                if( xVSS_context->pSettings->pClipList[i]->xVSS.MediaRendering
2883                    == M4xVSS_kCropping
2884                    || xVSS_context->pSettings->pClipList[i]->xVSS.
2885                    MediaRendering == M4xVSS_kBlackBorders
2886                    || xVSS_context->pSettings->pClipList[i]->xVSS.
2887                    MediaRendering == M4xVSS_kResizing )
2888                {
2889                    pParams->MediaRendering =
2890                        xVSS_context->pSettings->pClipList[i]->xVSS.
2891                        MediaRendering;
2892                }
2893
2894                /*FB: transcoding per parts*/
2895                pParams->BeginCutTime =
2896                    xVSS_context->pSettings->pClipList[i]->uiBeginCutTime;
2897                pParams->EndCutTime =
2898                    xVSS_context->pSettings->pClipList[i]->uiEndCutTime;
2899
2900                pParams->pNext = M4OSA_NULL;
2901                pParams->isBGM = M4OSA_FALSE;
2902                pParams->isCreated = M4OSA_FALSE;
2903                xVSS_context->nbStepTotal++;
2904                bIsTranscoding = M4OSA_TRUE;
2905
2906replace3GP_3GP:
2907                /* Update total duration */
2908                totalDuration +=
2909                    xVSS_context->pSettings->pClipList[i]->uiEndCutTime
2910                    - xVSS_context->pSettings->pClipList[i]->uiBeginCutTime;
2911
2912                /* Replacing in VSS structure the original 3GP file by the transcoded 3GP file */
2913                xVSS_context->pSettings->pClipList[i]->FileType =
2914                    M4VIDEOEDITING_kFileType_3GPP;
2915
2916                if( xVSS_context->pSettings->pClipList[i]->pFile != M4OSA_NULL )
2917                {
2918                    free(xVSS_context->pSettings->pClipList[i]->pFile);
2919                    xVSS_context->pSettings->pClipList[i]->pFile = M4OSA_NULL;
2920                }
2921
2922                /**
2923                * UTF conversion: convert into the customer format, before being used*/
2924                pDecodedPath = pParams->pFileOut;
2925
2926                if( xVSS_context->UTFConversionContext.pConvToUTF8Fct
2927                    != M4OSA_NULL && xVSS_context->
2928                    UTFConversionContext.pTempOutConversionBuffer
2929                    != M4OSA_NULL )
2930                {
2931                    err = M4xVSS_internalConvertToUTF8(xVSS_context,
2932                        (M4OSA_Void *)pParams->pFileOut,
2933                        (M4OSA_Void *)xVSS_context->
2934                        UTFConversionContext.pTempOutConversionBuffer,
2935                        &length);
2936
2937                    if( err != M4NO_ERROR )
2938                    {
2939                        M4OSA_TRACE1_1(
2940                            "M4xVSS_SendCommand: M4xVSS_internalConvertToUTF8 returns err: 0x%x",
2941                            err);
2942                        /* Free Send command */
2943                        M4xVSS_freeCommand(xVSS_context);
2944                        return err;
2945                    }
2946                    pDecodedPath = xVSS_context->
2947                        UTFConversionContext.pTempOutConversionBuffer;
2948                }
2949                else
2950                {
2951                    length = strlen(pDecodedPath);
2952                }
2953                /**
2954                * End of the UTF conversion, use the converted file path*/
2955                xVSS_context->pSettings->pClipList[i]->pFile = M4OSA_32bitAlignedMalloc(
2956                    (length + 1),
2957                    M4VS, (M4OSA_Char *)"xVSS file path of 3gp to 3gp");
2958
2959                if( xVSS_context->pSettings->pClipList[i]->pFile == M4OSA_NULL )
2960                {
2961                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
2962                    /*FB: to avoid leaks when there is an error in the send command*/
2963                    /* Free Send command */
2964                    M4xVSS_freeCommand(xVSS_context);
2965                    /**/
2966                    return M4ERR_ALLOC;
2967                }
2968                memcpy((void *)xVSS_context->pSettings->pClipList[i]->pFile,
2969                    (void *)pDecodedPath, (length + 1));
2970                /*FB: add file path size because of UTF 16 conversion*/
2971                xVSS_context->pSettings->pClipList[i]->filePathSize = length+1;
2972
2973                /* We define master clip as first 3GP input clip */
2974                /*if(xVSS_context->pSettings->uiMasterClip == 0 && fileProperties.
2975                AudioStreamType != M4VIDEOEDITING_kNoneAudio)
2976                {
2977                xVSS_context->pSettings->uiMasterClip = i;
2978                }*/
2979            }
2980            else
2981            {
2982                /* Update total duration */
2983                totalDuration +=
2984                    xVSS_context->pSettings->pClipList[i]->uiEndCutTime
2985                    - xVSS_context->pSettings->pClipList[i]->uiBeginCutTime;
2986            }
2987            /* We define master clip as first 3GP input clip */
2988            if( masterClip == -1
2989                && fileProperties.AudioStreamType != M4VIDEOEDITING_kNoneAudio )
2990            {
2991                masterClip = i;
2992                xVSS_context->pSettings->uiMasterClip = i;
2993            }
2994
2995        }
2996        /**************************
2997        Other input file type case
2998        ***************************/
2999        else
3000        {
3001            M4OSA_TRACE1_0("Bad file type as input clip");
3002            /*FB: to avoid leaks when there is an error in the send command*/
3003            /* Free Send command */
3004            M4xVSS_freeCommand(xVSS_context);
3005            /**/
3006            return M4ERR_PARAMETER;
3007        }
3008    }
3009
3010    /*********************************************************
3011    * Parse all effects to make some adjustment for framing, *
3012    * text and to transform relative time into absolute time *
3013    **********************************************************/
3014    for ( j = 0; j < xVSS_context->pSettings->nbEffects; j++ )
3015    {
3016        /* Copy effect to "local" structure */
3017        memcpy((void *) &(xVSS_context->pSettings->Effects[j]),
3018            (void *) &(pSettings->Effects[j]),
3019            sizeof(M4VSS3GPP_EffectSettings));
3020
3021        /* Prevent from bad initializing of effect percentage time */
3022        if( xVSS_context->pSettings->Effects[j].xVSS.uiDurationPercent > 100
3023            || xVSS_context->pSettings->Effects[j].xVSS.uiStartPercent > 100 )
3024        {
3025            /* These percentage time have probably not been initialized */
3026            /* Let's not use them by setting them to 0 */
3027            xVSS_context->pSettings->Effects[j].xVSS.uiDurationPercent = 0;
3028            xVSS_context->pSettings->Effects[j].xVSS.uiStartPercent = 0;
3029        }
3030
3031        /* If we have percentage information let's use it... Otherwise, we use absolute time. */
3032        if( xVSS_context->pSettings->Effects[j].xVSS.uiDurationPercent != 0 )
3033        {
3034            xVSS_context->pSettings->
3035                Effects[j].uiStartTime = (M4OSA_UInt32)(totalDuration
3036                * xVSS_context->pSettings->Effects[j].xVSS.uiStartPercent
3037                / 100);
3038            /* The percentage of effect duration is based on the duration of the clip -
3039            start time */
3040            xVSS_context->pSettings->
3041                Effects[j].uiDuration = (M4OSA_UInt32)(totalDuration
3042                * xVSS_context->pSettings->Effects[j].xVSS.uiDurationPercent
3043                / 100);
3044        }
3045
3046        /* If there is a framing effect, we need to allocate framing effect structure */
3047        if( xVSS_context->pSettings->Effects[j].VideoEffectType
3048            == M4xVSS_kVideoEffectType_Framing )
3049        {
3050#ifdef DECODE_GIF_ON_SAVING
3051
3052            M4xVSS_FramingContext *framingCtx;
3053            /*UTF conversion support*/
3054            M4OSA_Void *pDecodedPath = M4OSA_NULL;
3055
3056#else
3057
3058            M4xVSS_FramingStruct *framingCtx;
3059
3060#endif /*DECODE_GIF_ON_SAVING*/
3061
3062            M4OSA_Char *pExt2 = M4OSA_NULL;
3063            M4VIFI_ImagePlane *pPlane =
3064                xVSS_context->pSettings->Effects[j].xVSS.pFramingBuffer;
3065            M4OSA_Int32 result1, result2;
3066
3067            /* Copy framing file path */
3068            if( pSettings->Effects[j].xVSS.pFramingFilePath != M4OSA_NULL )
3069            {
3070                xVSS_context->pSettings->
3071                    Effects[j].xVSS.pFramingFilePath = M4OSA_32bitAlignedMalloc(
3072                    strlen(pSettings->Effects[j].xVSS.pFramingFilePath)
3073                    + 1, M4VS, (M4OSA_Char *)"Local Framing file path");
3074
3075                if( xVSS_context->pSettings->Effects[j].xVSS.pFramingFilePath
3076                    == M4OSA_NULL )
3077                {
3078                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3079                    /*FB: to avoid leaks when there is an error in the send command*/
3080                    /* Free Send command */
3081                    M4xVSS_freeCommand(xVSS_context);
3082                    /**/
3083                    return M4ERR_ALLOC;
3084                }
3085                memcpy((void *)xVSS_context->pSettings->
3086                    Effects[j].xVSS.pFramingFilePath,
3087                    (void *)pSettings->
3088                    Effects[j].xVSS.pFramingFilePath, strlen(
3089                    pSettings->Effects[j].xVSS.pFramingFilePath) + 1);
3090
3091                pExt2 =
3092                    xVSS_context->pSettings->Effects[j].xVSS.pFramingFilePath;
3093            }
3094
3095#ifdef DECODE_GIF_ON_SAVING
3096
3097            framingCtx = (M4xVSS_FramingContext
3098                *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingContext),
3099                M4VS, (M4OSA_Char *)"Context of the framing effect");
3100
3101            if( framingCtx == M4OSA_NULL )
3102            {
3103                M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3104                /*FB: to avoid leaks when there is an error in the send command*/
3105                /* Free Send command */
3106                M4xVSS_freeCommand(xVSS_context);
3107                /**/
3108                return M4ERR_ALLOC;
3109            }
3110            framingCtx->aFramingCtx = M4OSA_NULL;
3111            framingCtx->aFramingCtx_last = M4OSA_NULL;
3112            framingCtx->pSPSContext = M4OSA_NULL;
3113            framingCtx->outputVideoSize =
3114                xVSS_context->pSettings->xVSS.outputVideoSize;
3115            framingCtx->topleft_x =
3116                xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3117            framingCtx->topleft_y =
3118                xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3119            framingCtx->bEffectResize =
3120                xVSS_context->pSettings->Effects[j].xVSS.bResize;
3121            framingCtx->pEffectFilePath =
3122                xVSS_context->pSettings->Effects[j].xVSS.pFramingFilePath;
3123            framingCtx->pFileReadPtr = xVSS_context->pFileReadPtr;
3124            framingCtx->pFileWritePtr = xVSS_context->pFileWritePtr;
3125            framingCtx->effectDuration =
3126                xVSS_context->pSettings->Effects[j].uiDuration;
3127            framingCtx->b_IsFileGif = M4OSA_FALSE;
3128            framingCtx->alphaBlendingStruct = M4OSA_NULL;
3129            framingCtx->b_animated = M4OSA_FALSE;
3130
3131            /* Output ratio for the effect is stored in uiFiftiesOutFrameRate parameters of the
3132            extended xVSS effects structure */
3133            if( xVSS_context->pSettings->Effects[j].xVSS.uiFiftiesOutFrameRate
3134                != 0 )
3135            {
3136                framingCtx->frameDurationRatio =
3137                    (M4OSA_Float)(( xVSS_context->pSettings->
3138                    Effects[j].xVSS.uiFiftiesOutFrameRate) / 1000.0);
3139            }
3140            else
3141            {
3142                framingCtx->frameDurationRatio = 1.0;
3143            }
3144
3145            /*Alpha blending*/
3146            /*Check if the alpha blending parameters are corrects*/
3147            if( pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime > 100 )
3148            {
3149                pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime = 0;
3150            }
3151
3152            if( pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime > 100 )
3153            {
3154                pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime = 0;
3155            }
3156
3157            if( pSettings->Effects[j].xVSS.uialphaBlendingEnd > 100 )
3158            {
3159                pSettings->Effects[j].xVSS.uialphaBlendingEnd = 100;
3160            }
3161
3162            if( pSettings->Effects[j].xVSS.uialphaBlendingMiddle > 100 )
3163            {
3164                pSettings->Effects[j].xVSS.uialphaBlendingMiddle = 100;
3165            }
3166
3167            if( pSettings->Effects[j].xVSS.uialphaBlendingStart > 100 )
3168            {
3169                pSettings->Effects[j].xVSS.uialphaBlendingStart = 100;
3170            }
3171
3172            if( pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime > 0
3173                || pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime > 0 )
3174            {
3175                /*Allocate the alpha blending structure*/
3176                framingCtx->alphaBlendingStruct =
3177                    (M4xVSS_internalEffectsAlphaBlending *)M4OSA_32bitAlignedMalloc(
3178                    sizeof(M4xVSS_internalEffectsAlphaBlending),
3179                    M4VS, (M4OSA_Char *)"alpha blending structure");
3180
3181                if( framingCtx->alphaBlendingStruct == M4OSA_NULL )
3182                {
3183                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3184                    M4xVSS_freeCommand(xVSS_context);
3185                    return M4ERR_ALLOC;
3186                }
3187                /*Fill the alpha blending structure*/
3188                framingCtx->alphaBlendingStruct->m_fadeInTime =
3189                    pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime;
3190                framingCtx->alphaBlendingStruct->m_fadeOutTime =
3191                    pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime;
3192                framingCtx->alphaBlendingStruct->m_end =
3193                    pSettings->Effects[j].xVSS.uialphaBlendingEnd;
3194                framingCtx->alphaBlendingStruct->m_middle =
3195                    pSettings->Effects[j].xVSS.uialphaBlendingMiddle;
3196                framingCtx->alphaBlendingStruct->m_start =
3197                    pSettings->Effects[j].xVSS.uialphaBlendingStart;
3198
3199                if( pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime
3200                    + pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime
3201                        > 100 )
3202                {
3203                    framingCtx->alphaBlendingStruct->m_fadeOutTime =
3204                        100 - framingCtx->alphaBlendingStruct->m_fadeInTime;
3205                }
3206            }
3207
3208            /**
3209            * UTF conversion: convert into the customer format, before being used*/
3210            pDecodedPath =
3211                xVSS_context->pSettings->Effects[j].xVSS.pFramingFilePath;
3212            length = strlen(pDecodedPath);
3213
3214            if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
3215                != M4OSA_NULL && xVSS_context->
3216                UTFConversionContext.pTempOutConversionBuffer
3217                != M4OSA_NULL )
3218            {
3219                err = M4xVSS_internalConvertFromUTF8(xVSS_context,
3220                    (M4OSA_Void *)xVSS_context->pSettings->
3221                    Effects[j].xVSS.pFramingFilePath,
3222                    (M4OSA_Void *)xVSS_context->
3223                    UTFConversionContext.pTempOutConversionBuffer,
3224                    &length);
3225
3226                if( err != M4NO_ERROR )
3227                {
3228                    M4OSA_TRACE1_1(
3229                        "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
3230                        err);
3231                    /* Free Send command */
3232                    M4xVSS_freeCommand(xVSS_context);
3233                    return err;
3234                }
3235                pDecodedPath =
3236                    xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
3237            }
3238
3239            /**
3240            * End of the UTF conversion, use the converted file path*/
3241            framingCtx->pEffectFilePath = M4OSA_32bitAlignedMalloc(length + 1, M4VS,
3242                (M4OSA_Char *)"Local Framing file path");
3243
3244            if( framingCtx->pEffectFilePath == M4OSA_NULL )
3245            {
3246                M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3247                /*FB: to avoid leaks when there is an error in the send command*/
3248                /* Free Send command */
3249                M4xVSS_freeCommand(xVSS_context);
3250                /**/
3251                return M4ERR_ALLOC;
3252            }
3253            memcpy((void *)framingCtx->pEffectFilePath,
3254                (void *)pDecodedPath, length + 1);
3255
3256            /* Save framing structure associated with corresponding effect */
3257            xVSS_context->pSettings->Effects[j].pExtVideoEffectFctCtxt =
3258                framingCtx;
3259
3260#else
3261
3262            framingCtx = (M4xVSS_FramingStruct
3263                *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingStruct),
3264                M4VS, (M4OSA_Char *)"Context of the framing effect");
3265
3266            if( framingCtx == M4OSA_NULL )
3267            {
3268                M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3269                /*FB: to avoid leaks when there is an error in the send command*/
3270                /* Free Send command */
3271                M4xVSS_freeCommand(xVSS_context);
3272                /**/
3273                return M4ERR_ALLOC;
3274            }
3275
3276            framingCtx->topleft_x =
3277                xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3278            framingCtx->topleft_y =
3279                xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3280
3281            /* BugFix 1.2.0: Leak when decoding error */
3282            framingCtx->FramingRgb = M4OSA_NULL;
3283            framingCtx->FramingYuv = M4OSA_NULL;
3284            framingCtx->pNext = framingCtx;
3285            /* Save framing structure associated with corresponding effect */
3286            xVSS_context->pSettings->Effects[j].pExtVideoEffectFctCtxt =
3287                framingCtx;
3288
3289#endif /*DECODE_GIF_ON_SAVING*/
3290
3291            if( pExt2 != M4OSA_NULL )
3292            {
3293                /* Decode the image associated to the effect, and fill framing structure */
3294                pExt2 += (strlen((const char *)pExt2) - 4);
3295
3296                result1 = strcmp((const char *)pExt2,(const char *)".rgb");
3297                result2 = strcmp((const char *)pExt2,(const char *)".RGB");
3298
3299                if( 0 == result1 || 0 == result2 )
3300                {
3301#ifdef DECODE_GIF_ON_SAVING
3302
3303                    framingCtx->aFramingCtx =
3304                        (M4xVSS_FramingStruct
3305                        *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingStruct),
3306                        M4VS,
3307                        (M4OSA_Char
3308                        *)
3309                        "M4xVSS_internalDecodeGIF: Context of the framing effect");
3310
3311                    if( framingCtx->aFramingCtx == M4OSA_NULL )
3312                    {
3313                        M4OSA_TRACE1_0(
3314                            "Allocation error in M4xVSS_SendCommand");
3315                        /* TODO: Translate error code of SPS to an xVSS error code */
3316                        M4xVSS_freeCommand(xVSS_context);
3317                        return M4ERR_ALLOC;
3318                    }
3319                    framingCtx->aFramingCtx->pCurrent =
3320                        M4OSA_NULL; /* Only used by the first element of the chain */
3321                    framingCtx->aFramingCtx->previousClipTime = -1;
3322                    framingCtx->aFramingCtx->FramingYuv = M4OSA_NULL;
3323                    framingCtx->aFramingCtx->FramingRgb = M4OSA_NULL;
3324                    framingCtx->aFramingCtx->topleft_x =
3325                        xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3326                    framingCtx->aFramingCtx->topleft_y =
3327                        xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3328                    /*To support ARGB8888 : get the width and height */
3329
3330                    framingCtx->aFramingCtx->width =
3331                        xVSS_context->pSettings->Effects[j].xVSS.width;
3332                    framingCtx->aFramingCtx->height =
3333                        xVSS_context->pSettings->Effects[j].xVSS.height;
3334                    M4OSA_TRACE1_1("FRAMMING BEFORE M4xVSS_SendCommand  %d",
3335                        framingCtx->aFramingCtx->width);
3336                    M4OSA_TRACE1_1("FRAMMING BEFORE M4xVSS_SendCommand  %d",
3337                        framingCtx->aFramingCtx->height);
3338
3339#endif
3340
3341                    err = M4xVSS_internalConvertARGB888toYUV420_FrammingEffect(
3342                        xVSS_context,
3343                        &(xVSS_context->pSettings->Effects[j]),
3344                        framingCtx->aFramingCtx,xVSS_context->pSettings->xVSS.outputVideoSize);
3345                    M4OSA_TRACE3_1("FRAMING WIDTH BEFORE M4xVSS_SendCommand  %d",
3346                        framingCtx->aFramingCtx->width);
3347                    M4OSA_TRACE3_1("FRAMING HEIGHT BEFORE M4xVSS_SendCommand  %d",
3348                        framingCtx->aFramingCtx->height);
3349
3350                    if( err != M4NO_ERROR )
3351                    {
3352                        M4OSA_TRACE1_1(
3353                            "M4xVSS_SendCommand: M4xVSS_internalDecodePNG returned 0x%x",
3354                            err);
3355                        /* TODO: Translate error code of SPS to an xVSS error code */
3356                        M4xVSS_freeCommand(xVSS_context);
3357                        return err;
3358                    }
3359                }
3360                else
3361                {
3362                    M4OSA_TRACE1_1(
3363                        "M4xVSS_SendCommand: Not supported still picture format 0x%x",
3364                        err);
3365                    /*FB: to avoid leaks when there is an error in the send command*/
3366                    /* Free Send command */
3367                    M4xVSS_freeCommand(xVSS_context);
3368                    /**/
3369                    return M4ERR_PARAMETER;
3370                }
3371            }
3372            else if( pPlane != M4OSA_NULL )
3373            {
3374#ifdef DECODE_GIF_ON_SAVING
3375
3376                framingCtx->aFramingCtx = (M4xVSS_FramingStruct
3377                    *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingStruct),
3378                    M4VS, (M4OSA_Char *)"Context of the framing effect");
3379
3380                if( framingCtx->aFramingCtx == M4OSA_NULL )
3381                {
3382                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3383                    /*FB: to avoid leaks when there is an error in the send command*/
3384                    /* Free Send command */
3385                    M4xVSS_freeCommand(xVSS_context);
3386                    /**/
3387                    return M4ERR_ALLOC;
3388                }
3389
3390                framingCtx->aFramingCtx->topleft_x =
3391                    xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3392                framingCtx->aFramingCtx->topleft_y =
3393                    xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3394
3395                /* BugFix 1.2.0: Leak when decoding error */
3396                framingCtx->aFramingCtx->FramingRgb = M4OSA_NULL;
3397                framingCtx->aFramingCtx->FramingYuv = M4OSA_NULL;
3398                framingCtx->aFramingCtx->pNext = framingCtx->aFramingCtx;
3399                framingCtx->aFramingCtx->pCurrent = framingCtx->aFramingCtx;
3400                framingCtx->aFramingCtx->duration = 0;
3401                framingCtx->aFramingCtx->previousClipTime = -1;
3402                framingCtx->aFramingCtx->FramingRgb =
3403                    xVSS_context->pSettings->Effects[j].xVSS.pFramingBuffer;
3404                /* Force input RGB buffer to even size to avoid errors in YUV conversion */
3405                framingCtx->aFramingCtx->FramingRgb->u_width =
3406                    framingCtx->aFramingCtx->FramingRgb->u_width & ~1;
3407                framingCtx->aFramingCtx->FramingRgb->u_height =
3408                    framingCtx->aFramingCtx->FramingRgb->u_height & ~1;
3409                /* Input RGB plane is provided, let's convert it to YUV420, and update framing
3410                structure  */
3411                err = M4xVSS_internalConvertRGBtoYUV(framingCtx->aFramingCtx);
3412
3413#else
3414
3415                framingCtx->FramingRgb =
3416                    xVSS_context->pSettings->Effects[j].xVSS.pFramingBuffer;
3417                /* Force input RGB buffer to even size to avoid errors in YUV conversion */
3418                framingCtx->FramingRgb.u_width =
3419                    framingCtx->FramingRgb.u_width & ~1;
3420                framingCtx->FramingRgb.u_height =
3421                    framingCtx->FramingRgb.u_height & ~1;
3422                /* Input RGB plane is provided, let's convert it to YUV420, and update framing
3423                 structure  */
3424                err = M4xVSS_internalConvertRGBtoYUV(framingCtx);
3425
3426#endif
3427
3428                if( err != M4NO_ERROR )
3429                {
3430                    M4OSA_TRACE1_1(
3431                        "M4xVSS_sendCommand: error when converting RGB to YUV: 0w%x",
3432                        err);
3433                    /*FB: to avoid leaks when there is an error in the send command*/
3434                    /* Free Send command */
3435                    M4xVSS_freeCommand(xVSS_context);
3436                    /**/
3437                    return err;
3438                }
3439            }
3440            else
3441            {
3442                M4OSA_TRACE1_0(
3443                    "M4xVSS_sendCommand: No input image/plane provided for framing effect.");
3444                /*FB: to avoid leaks when there is an error in the send command*/
3445                /* Free Send command */
3446                M4xVSS_freeCommand(xVSS_context);
3447                /**/
3448                return M4ERR_PARAMETER;
3449            }
3450        }
3451        /* CR: Add text handling with external text interface */
3452        /* If effect type is text, we call external text function to get RGB 565 buffer */
3453        if( xVSS_context->pSettings->Effects[j].VideoEffectType
3454            == M4xVSS_kVideoEffectType_Text )
3455        {
3456            /* Call the font engine function pointer to get RGB565 buffer */
3457            /* We transform text effect into framing effect from buffer */
3458            if( xVSS_context->pSettings->xVSS.pTextRenderingFct != M4OSA_NULL )
3459            {
3460                /*FB: add UTF convertion for text buffer*/
3461                M4OSA_Void *pDecodedPath = M4OSA_NULL;
3462#ifdef DECODE_GIF_ON_SAVING
3463
3464                M4xVSS_FramingContext *framingCtx;
3465
3466#else
3467
3468                M4xVSS_FramingStruct *framingCtx;
3469
3470#endif /*DECODE_GIF_ON_SAVING*/
3471
3472#ifdef DECODE_GIF_ON_SAVING
3473
3474                framingCtx = (M4xVSS_FramingContext
3475                    *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingContext),
3476                    M4VS, (M4OSA_Char *)"Context of the framing effect");
3477
3478                if( framingCtx == M4OSA_NULL )
3479                {
3480                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3481                    /*FB: to avoid leaks when there is an error in the send command*/
3482                    /* Free Send command */
3483                    M4xVSS_freeCommand(xVSS_context);
3484                    /**/
3485                    return M4ERR_ALLOC;
3486                }
3487                framingCtx->aFramingCtx = M4OSA_NULL;
3488                framingCtx->aFramingCtx_last = M4OSA_NULL;
3489                framingCtx->pSPSContext = M4OSA_NULL;
3490                framingCtx->outputVideoSize =
3491                    xVSS_context->pSettings->xVSS.outputVideoSize;
3492                framingCtx->topleft_x =
3493                    xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3494                framingCtx->topleft_y =
3495                    xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3496                framingCtx->bEffectResize =
3497                    xVSS_context->pSettings->Effects[j].xVSS.bResize;
3498                framingCtx->pEffectFilePath =
3499                    xVSS_context->pSettings->Effects[j].xVSS.pFramingFilePath;
3500                framingCtx->pFileReadPtr = xVSS_context->pFileReadPtr;
3501                framingCtx->pFileWritePtr = xVSS_context->pFileWritePtr;
3502                framingCtx->effectDuration =
3503                    xVSS_context->pSettings->Effects[j].uiDuration;
3504                framingCtx->b_IsFileGif = M4OSA_FALSE;
3505                framingCtx->b_animated = M4OSA_FALSE;
3506                framingCtx->alphaBlendingStruct = M4OSA_NULL;
3507
3508                /* Save framing structure associated with corresponding effect */
3509                xVSS_context->pSettings->Effects[j].pExtVideoEffectFctCtxt =
3510                    framingCtx;
3511
3512                framingCtx->aFramingCtx = (M4xVSS_FramingStruct
3513                    *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingStruct),
3514                    M4VS, (M4OSA_Char *)"Context of the framing effect");
3515
3516                if( framingCtx->aFramingCtx == M4OSA_NULL )
3517                {
3518                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3519                    /*FB: to avoid leaks when there is an error in the send command*/
3520                    /* Free Send command */
3521                    M4xVSS_freeCommand(xVSS_context);
3522                    /**/
3523                    return M4ERR_ALLOC;
3524                }
3525
3526                framingCtx->aFramingCtx->topleft_x =
3527                    xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3528                framingCtx->aFramingCtx->topleft_y =
3529                    xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3530
3531                /* BugFix 1.2.0: Leak when decoding error */
3532                framingCtx->aFramingCtx->FramingRgb = M4OSA_NULL;
3533                framingCtx->aFramingCtx->FramingYuv = M4OSA_NULL;
3534                framingCtx->aFramingCtx->pNext = framingCtx->aFramingCtx;
3535                framingCtx->aFramingCtx->pCurrent = framingCtx->aFramingCtx;
3536                framingCtx->aFramingCtx->duration = 0;
3537                framingCtx->aFramingCtx->previousClipTime = -1;
3538
3539                /*Alpha blending*/
3540                /*Check if the alpha blending parameters are corrects*/
3541                if( pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime > 100 )
3542                {
3543                    pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime = 0;
3544                }
3545
3546                if( pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime > 100 )
3547                {
3548                    pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime = 0;
3549                }
3550
3551                if( pSettings->Effects[j].xVSS.uialphaBlendingEnd > 100 )
3552                {
3553                    pSettings->Effects[j].xVSS.uialphaBlendingEnd = 100;
3554                }
3555
3556                if( pSettings->Effects[j].xVSS.uialphaBlendingMiddle > 100 )
3557                {
3558                    pSettings->Effects[j].xVSS.uialphaBlendingMiddle = 100;
3559                }
3560
3561                if( pSettings->Effects[j].xVSS.uialphaBlendingStart > 100 )
3562                {
3563                    pSettings->Effects[j].xVSS.uialphaBlendingStart = 100;
3564                }
3565
3566                if( pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime > 0
3567                    || pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime
3568                    > 0 )
3569                {
3570                    /*Allocate the alpha blending structure*/
3571                    framingCtx->alphaBlendingStruct =
3572                        (M4xVSS_internalEffectsAlphaBlending *)M4OSA_32bitAlignedMalloc(
3573                        sizeof(M4xVSS_internalEffectsAlphaBlending),
3574                        M4VS, (M4OSA_Char *)"alpha blending structure");
3575
3576                    if( framingCtx->alphaBlendingStruct == M4OSA_NULL )
3577                    {
3578                        M4OSA_TRACE1_0(
3579                            "Allocation error in M4xVSS_SendCommand");
3580                        M4xVSS_freeCommand(xVSS_context);
3581                        return M4ERR_ALLOC;
3582                    }
3583                    /*Fill the alpha blending structure*/
3584                    framingCtx->alphaBlendingStruct->m_fadeInTime =
3585                        pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime;
3586                    framingCtx->alphaBlendingStruct->m_fadeOutTime =
3587                        pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime;
3588                    framingCtx->alphaBlendingStruct->m_end =
3589                        pSettings->Effects[j].xVSS.uialphaBlendingEnd;
3590                    framingCtx->alphaBlendingStruct->m_middle =
3591                        pSettings->Effects[j].xVSS.uialphaBlendingMiddle;
3592                    framingCtx->alphaBlendingStruct->m_start =
3593                        pSettings->Effects[j].xVSS.uialphaBlendingStart;
3594
3595                    if( pSettings->Effects[j].xVSS.uialphaBlendingFadeInTime
3596                        + pSettings->Effects[j].xVSS.uialphaBlendingFadeOutTime
3597                            > 100 )
3598                    {
3599                        framingCtx->alphaBlendingStruct->m_fadeOutTime =
3600                            100 - framingCtx->alphaBlendingStruct->m_fadeInTime;
3601                    }
3602                }
3603#else
3604
3605                framingCtx = (M4xVSS_FramingStruct
3606                    *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingStruct),
3607                    M4VS, (M4OSA_Char
3608                    *)"Context of the framing effect (for text)");
3609
3610                if( framingCtx == M4OSA_NULL )
3611                {
3612                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3613                    /*FB: to avoid leaks when there is an error in the send command*/
3614                    /* Free Send command */
3615                    M4xVSS_freeCommand(xVSS_context);
3616                    /**/
3617                    return M4ERR_ALLOC;
3618                }
3619
3620                framingCtx->topleft_x =
3621                    xVSS_context->pSettings->Effects[j].xVSS.topleft_x;
3622                framingCtx->topleft_y =
3623                    xVSS_context->pSettings->Effects[j].xVSS.topleft_y;
3624                framingCtx->FramingRgb = M4OSA_NULL;
3625
3626                /* BugFix 1.2.0: Leak when decoding error */
3627                framingCtx->FramingYuv = M4OSA_NULL;
3628                framingCtx->pNext = framingCtx;
3629
3630#endif
3631                /* Save framing structure associated with corresponding effect */
3632
3633                xVSS_context->pSettings->Effects[j].pExtVideoEffectFctCtxt =
3634                    framingCtx;
3635
3636                /* FB: changes for Video Artist: memcopy pTextBuffer so that it can be changed
3637                after a complete analysis*/
3638                if( pSettings->Effects[j].xVSS.pTextBuffer == M4OSA_NULL )
3639                {
3640                    M4OSA_TRACE1_0("M4xVSS_SendCommand: pTextBuffer is null");
3641                    M4xVSS_freeCommand(xVSS_context);
3642                    return M4ERR_PARAMETER;
3643                }
3644
3645                /*Convert text buffer into customer format before being used*/
3646                /**
3647                * UTF conversion: convert into the customer format, before being used*/
3648                pDecodedPath = pSettings->Effects[j].xVSS.pTextBuffer;
3649                xVSS_context->pSettings->Effects[j].xVSS.textBufferSize =
3650                    pSettings->Effects[j].xVSS.textBufferSize;
3651
3652                if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
3653                    != M4OSA_NULL && xVSS_context->
3654                    UTFConversionContext.pTempOutConversionBuffer
3655                    != M4OSA_NULL )
3656                {
3657                    err = M4xVSS_internalConvertFromUTF8(xVSS_context,
3658                        (M4OSA_Void *)pSettings->
3659                        Effects[j].xVSS.pTextBuffer,
3660                        (M4OSA_Void *)xVSS_context->
3661                        UTFConversionContext.pTempOutConversionBuffer,
3662                        &length);
3663
3664                    if( err != M4NO_ERROR )
3665                    {
3666                        M4OSA_TRACE1_1(
3667                            "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
3668                            err);
3669                        /* Free Send command */
3670                        M4xVSS_freeCommand(xVSS_context);
3671                        return err;
3672                    }
3673                    pDecodedPath = xVSS_context->
3674                        UTFConversionContext.pTempOutConversionBuffer;
3675                    xVSS_context->pSettings->Effects[j].xVSS.textBufferSize =
3676                        length;
3677                }
3678                /**
3679                * End of the UTF conversion, use the converted file path*/
3680
3681                xVSS_context->pSettings->
3682                    Effects[j].xVSS.pTextBuffer = M4OSA_32bitAlignedMalloc(
3683                    xVSS_context->pSettings->Effects[j].xVSS.textBufferSize + 1,
3684                    M4VS, (M4OSA_Char *)"Local text buffer effect");
3685
3686                //xVSS_context->pSettings->Effects[j].xVSS.pTextBuffer =
3687                // M4OSA_32bitAlignedMalloc(strlen(pSettings->Effects[j].xVSS.pTextBuffer)+1,
3688                // M4VS, "Local text buffer effect");
3689                if( xVSS_context->pSettings->Effects[j].xVSS.pTextBuffer
3690                    == M4OSA_NULL )
3691                {
3692                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3693                    /*FB: to avoid leaks when there is an error in the send command*/
3694                    /* Free Send command */
3695                    M4xVSS_freeCommand(xVSS_context);
3696                    /**/
3697                    return M4ERR_ALLOC;
3698                }
3699
3700                if( pSettings->Effects[j].xVSS.pTextBuffer != M4OSA_NULL )
3701                {
3702                    //memcpy((M4OSA_MemAddr8)xVSS_context->pSettings->Effects[j]
3703                    //.xVSS.pTextBuffer, (M4OSA_MemAddr8)pSettings->Effects[j].xVSS.pTextBuffer,
3704                    // strlen(pSettings->Effects[j].xVSS.pTextBuffer)+1);
3705                    memcpy((void *)xVSS_context->pSettings->
3706                        Effects[j].xVSS.pTextBuffer,
3707                        (void *)pDecodedPath, xVSS_context->pSettings->
3708                        Effects[j].xVSS.textBufferSize + 1);
3709                }
3710
3711                /*Allocate the text RGB buffer*/
3712                framingCtx->aFramingCtx->FramingRgb =
3713                    (M4VIFI_ImagePlane *)M4OSA_32bitAlignedMalloc(sizeof(M4VIFI_ImagePlane),
3714                    M4VS,
3715                    (M4OSA_Char *)"RGB structure for the text effect");
3716
3717                if( framingCtx->aFramingCtx->FramingRgb == M4OSA_NULL )
3718                {
3719                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3720                    /*FB: to avoid leaks when there is an error in the send command*/
3721                    /* Free Send command */
3722                    M4xVSS_freeCommand(xVSS_context);
3723                    /**/
3724                    return M4ERR_ALLOC;
3725                }
3726
3727                if( xVSS_context->pSettings->Effects[j].xVSS.uiTextBufferWidth
3728                    == 0 || xVSS_context->pSettings->
3729                    Effects[j].xVSS.uiTextBufferHeight == 0 )
3730                {
3731                    M4OSA_TRACE1_0(
3732                        "M4xVSS_SendCommand: text plane width and height are not defined");
3733                    /*FB: to avoid leaks when there is an error in the send command*/
3734                    /* Free Send command */
3735                    M4xVSS_freeCommand(xVSS_context);
3736                    /**/
3737                    return M4ERR_PARAMETER;
3738                }
3739                /* Allocate input RGB text buffer and force it to even size to avoid errors in
3740                 YUV conversion */
3741                framingCtx->aFramingCtx->FramingRgb->u_width =
3742                    xVSS_context->pSettings->
3743                    Effects[j].xVSS.uiTextBufferWidth & ~1;
3744                framingCtx->aFramingCtx->FramingRgb->u_height =
3745                    xVSS_context->pSettings->
3746                    Effects[j].xVSS.uiTextBufferHeight & ~1;
3747                framingCtx->aFramingCtx->FramingRgb->u_stride =
3748                    2 * framingCtx->aFramingCtx->FramingRgb->u_width;
3749                framingCtx->aFramingCtx->FramingRgb->u_topleft = 0;
3750                framingCtx->aFramingCtx->FramingRgb->pac_data =
3751                    (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(
3752                    framingCtx->aFramingCtx->FramingRgb->u_height
3753                    * framingCtx->aFramingCtx->FramingRgb->u_stride,
3754                    M4VS, (M4OSA_Char *)"Text RGB plane->pac_data");
3755
3756                if( framingCtx->aFramingCtx->FramingRgb->pac_data
3757                    == M4OSA_NULL )
3758                {
3759                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3760                    /*FB: to avoid leaks when there is an error in the send command*/
3761                    /* Free Send command */
3762                    M4xVSS_freeCommand(xVSS_context);
3763                    /**/
3764                    return M4ERR_ALLOC;
3765                }
3766
3767#ifdef DECODE_GIF_ON_SAVING
3768                /**/
3769                /* Call text rendering function */
3770
3771                err = xVSS_context->pSettings->xVSS.pTextRenderingFct(
3772                    xVSS_context->pSettings->Effects[j].xVSS.pRenderingData,
3773                    xVSS_context->pSettings->
3774                    Effects[j].xVSS.pTextBuffer,
3775                    xVSS_context->pSettings->
3776                    Effects[j].xVSS.textBufferSize,
3777                    &(framingCtx->aFramingCtx->FramingRgb));
3778
3779                if( err != M4NO_ERROR )
3780                {
3781                    M4OSA_TRACE1_0("Text rendering external function failed\n");
3782                    M4xVSS_freeCommand(xVSS_context);
3783                    return err;
3784                }
3785
3786                /* Check that RGB buffer is set */
3787                if( framingCtx->aFramingCtx->FramingRgb == M4OSA_NULL )
3788                {
3789                    M4OSA_TRACE1_0(
3790                        "Text rendering function did not set RGB buffer correctly !");
3791                    M4xVSS_freeCommand(xVSS_context);
3792                    return M4ERR_PARAMETER;
3793                }
3794
3795                /* Convert RGB plane to YUV420 and update framing structure */
3796                err = M4xVSS_internalConvertRGBtoYUV(framingCtx->aFramingCtx);
3797
3798                if( err != M4NO_ERROR )
3799                {
3800                    M4OSA_TRACE1_1(
3801                        "M4xVSS_sendCommand: error when converting RGB to YUV: 0w%x",
3802                        err);
3803                    M4xVSS_freeCommand(xVSS_context);
3804                    return err;
3805                }
3806
3807#else
3808                /**/
3809                /* Call text rendering function */
3810
3811                err = xVSS_context->pSettings->xVSS.pTextRenderingFct(
3812                    xVSS_context->pSettings->Effects[j].xVSS.pRenderingData,
3813                    xVSS_context->pSettings->
3814                    Effects[j].xVSS.pTextBuffer,
3815                    xVSS_context->pSettings->
3816                    Effects[j].xVSS.textBufferSize,
3817                    &(framingCtx->FramingRgb));
3818
3819                if( err != M4NO_ERROR )
3820                {
3821                    M4OSA_TRACE1_0("Text rendering external function failed\n");
3822                    M4xVSS_freeCommand(xVSS_context);
3823                    return err;
3824                }
3825
3826                /* Check that RGB buffer is set */
3827                if( framingCtx->FramingRgb == M4OSA_NULL )
3828                {
3829                    M4OSA_TRACE1_0(
3830                        "Text rendering function did not set RGB buffer correctly !");
3831                    M4xVSS_freeCommand(xVSS_context);
3832                    return M4ERR_PARAMETER;
3833                }
3834
3835                /* Convert RGB plane to YUV420 and update framing structure */
3836                err = M4xVSS_internalConvertRGBtoYUV(framingCtx);
3837
3838                if( err != M4NO_ERROR )
3839                {
3840                    M4OSA_TRACE1_1(
3841                        "M4xVSS_sendCommand: error when converting RGB to YUV: 0w%x",
3842                        err);
3843                    M4xVSS_freeCommand(xVSS_context);
3844                    return err;
3845                }
3846
3847#endif /*DECODE_GIF_ON_SAVING*/
3848
3849                /* Change internally effect type from "text" to framing */
3850
3851                xVSS_context->pSettings->Effects[j].VideoEffectType =
3852                    M4xVSS_kVideoEffectType_Framing;
3853                xVSS_context->pSettings->Effects[j].xVSS.bResize = M4OSA_FALSE;
3854            }
3855            else
3856            {
3857                M4OSA_TRACE1_0(
3858                    "M4xVSS_sendCommand: No text rendering function set !!");
3859                M4xVSS_freeCommand(xVSS_context);
3860                return M4ERR_PARAMETER;
3861            }
3862        }
3863
3864        /* Allocate the structure to store the data needed by the Fifties effect */
3865        else if( xVSS_context->pSettings->Effects[j].VideoEffectType
3866            == M4xVSS_kVideoEffectType_Fifties )
3867        {
3868            M4xVSS_FiftiesStruct *fiftiesCtx;
3869
3870            /* Check the expected frame rate for the fifties effect (must be above 0) */
3871            if( 0 == xVSS_context->pSettings->
3872                Effects[j].xVSS.uiFiftiesOutFrameRate )
3873            {
3874                M4OSA_TRACE1_0(
3875                    "The frame rate for the fifties effect must be greater than 0 !");
3876                M4xVSS_freeCommand(xVSS_context);
3877                return M4ERR_PARAMETER;
3878            }
3879
3880            fiftiesCtx = (M4xVSS_FiftiesStruct
3881                *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FiftiesStruct),
3882                M4VS, (M4OSA_Char *)"Context of the fifties effect");
3883
3884            if( fiftiesCtx == M4OSA_NULL )
3885            {
3886                M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3887                /* Free Send command */
3888                M4xVSS_freeCommand(xVSS_context);
3889                return M4ERR_ALLOC;
3890            }
3891
3892            fiftiesCtx->previousClipTime = -1;
3893            fiftiesCtx->fiftiesEffectDuration = 1000 / xVSS_context->pSettings->
3894                Effects[j].xVSS.uiFiftiesOutFrameRate;
3895            fiftiesCtx->shiftRandomValue = 0;
3896            fiftiesCtx->stripeRandomValue = 0;
3897
3898            /* Save the structure associated with corresponding effect */
3899            xVSS_context->pSettings->Effects[j].pExtVideoEffectFctCtxt =
3900                fiftiesCtx;
3901        }
3902
3903        /* Allocate the structure to store the data needed by the Color effect */
3904        else if( xVSS_context->pSettings->Effects[j].VideoEffectType
3905            == M4xVSS_kVideoEffectType_ColorRGB16
3906            || xVSS_context->pSettings->Effects[j].VideoEffectType
3907            == M4xVSS_kVideoEffectType_BlackAndWhite
3908            || xVSS_context->pSettings->Effects[j].VideoEffectType
3909            == M4xVSS_kVideoEffectType_Pink
3910            || xVSS_context->pSettings->Effects[j].VideoEffectType
3911            == M4xVSS_kVideoEffectType_Green
3912            || xVSS_context->pSettings->Effects[j].VideoEffectType
3913            == M4xVSS_kVideoEffectType_Sepia
3914            || xVSS_context->pSettings->Effects[j].VideoEffectType
3915            == M4xVSS_kVideoEffectType_Negative
3916            || xVSS_context->pSettings->Effects[j].VideoEffectType
3917            == M4xVSS_kVideoEffectType_Gradient )
3918        {
3919            M4xVSS_ColorStruct *ColorCtx;
3920
3921            ColorCtx =
3922                (M4xVSS_ColorStruct *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_ColorStruct),
3923                M4VS, (M4OSA_Char *)"Context of the color effect");
3924
3925            if( ColorCtx == M4OSA_NULL )
3926            {
3927                M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3928                /* Free Send command */
3929                M4xVSS_freeCommand(xVSS_context);
3930                return M4ERR_ALLOC;
3931            }
3932
3933            ColorCtx->colorEffectType =
3934                xVSS_context->pSettings->Effects[j].VideoEffectType;
3935
3936            if( xVSS_context->pSettings->Effects[j].VideoEffectType
3937                == M4xVSS_kVideoEffectType_ColorRGB16
3938                || xVSS_context->pSettings->Effects[j].VideoEffectType
3939                == M4xVSS_kVideoEffectType_Gradient )
3940            {
3941                ColorCtx->rgb16ColorData =
3942                    xVSS_context->pSettings->Effects[j].xVSS.uiRgb16InputColor;
3943            }
3944            else
3945            {
3946                ColorCtx->rgb16ColorData = 0;
3947            }
3948
3949            /* Save the structure associated with corresponding effect */
3950            xVSS_context->pSettings->Effects[j].pExtVideoEffectFctCtxt =
3951                ColorCtx;
3952        }
3953    }
3954
3955    /**********************************
3956    Background music registering
3957    **********************************/
3958    if( pSettings->xVSS.pBGMtrack != M4OSA_NULL && isNewBGM == M4OSA_TRUE )
3959    {
3960#ifdef PREVIEW_ENABLED
3961
3962        M4xVSS_MCS_params *pParams;
3963        M4OSA_Char *out_pcm;
3964        /*UTF conversion support*/
3965        M4OSA_Void *pDecodedPath = M4OSA_NULL;
3966
3967#endif
3968
3969        /* We save output file pointer, because we will need to use it when saving audio mixed
3970         file (last save step) */
3971
3972        xVSS_context->pOutputFile = xVSS_context->pSettings->pOutputFile;
3973        xVSS_context->pTemporaryFile = xVSS_context->pSettings->pTemporaryFile;
3974
3975        /* If a previous BGM has already been registered, delete it */
3976        /* Here can be implemented test to know if the same BGM is registered */
3977        if( xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
3978        {
3979            if( xVSS_context->pSettings->xVSS.pBGMtrack->pFile != M4OSA_NULL )
3980            {
3981                free(xVSS_context->pSettings->xVSS.pBGMtrack->
3982                    pFile);
3983                xVSS_context->pSettings->xVSS.pBGMtrack->pFile = M4OSA_NULL;
3984            }
3985            free(xVSS_context->pSettings->xVSS.pBGMtrack);
3986            xVSS_context->pSettings->xVSS.pBGMtrack = M4OSA_NULL;
3987        }
3988
3989        /* Allocate BGM */
3990        xVSS_context->pSettings->xVSS.pBGMtrack =
3991            (M4xVSS_BGMSettings *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_BGMSettings), M4VS,
3992            (M4OSA_Char *)"xVSS_context->pSettings->xVSS.pBGMtrack");
3993
3994        if( xVSS_context->pSettings->xVSS.pBGMtrack == M4OSA_NULL )
3995        {
3996            M4xVSS_freeCommand(xVSS_context);
3997            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
3998            return M4ERR_ALLOC;
3999        }
4000
4001        /* Copy input structure to our structure */
4002        memcpy((void *)xVSS_context->pSettings->xVSS.pBGMtrack,
4003            (void *)pSettings->xVSS.pBGMtrack,
4004            sizeof(M4xVSS_BGMSettings));
4005        /* Allocate file name, and copy file name buffer to our structure */
4006        xVSS_context->pSettings->xVSS.pBGMtrack->pFile =
4007            M4OSA_32bitAlignedMalloc((strlen(pSettings->xVSS.pBGMtrack->pFile)
4008            + 1), M4VS, (M4OSA_Char *)"xVSS BGM file path");
4009
4010        if( xVSS_context->pSettings->xVSS.pBGMtrack->pFile == M4OSA_NULL )
4011        {
4012            M4xVSS_freeCommand(xVSS_context);
4013            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
4014            return M4ERR_ALLOC;
4015        }
4016        memcpy((void *)xVSS_context->pSettings->xVSS.pBGMtrack->pFile,
4017            (void *)pSettings->xVSS.pBGMtrack->pFile,
4018            strlen(pSettings->xVSS.pBGMtrack->pFile) + 1);
4019
4020#ifdef PREVIEW_ENABLED
4021        /* Decode BGM track to pcm output file */
4022
4023        pParams =
4024            (M4xVSS_MCS_params *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_MCS_params), M4VS,
4025            (M4OSA_Char *)"Element of MCS Params (for BGM)");
4026
4027        if( pParams == M4OSA_NULL )
4028        {
4029            M4xVSS_freeCommand(xVSS_context);
4030            M4OSA_TRACE1_0(
4031                "M4xVSS_sendCommand: Problem when allocating one element MCS Params");
4032            return M4ERR_ALLOC;
4033        }
4034
4035        /* Initialize the pointers in case of problem (PR 2273) */
4036        pParams->pFileIn = M4OSA_NULL;
4037        pParams->pFileOut = M4OSA_NULL;
4038        pParams->pFileTemp = M4OSA_NULL;
4039        pParams->pNext = M4OSA_NULL;
4040        pParams->BeginCutTime = 0;
4041        pParams->EndCutTime = 0;
4042
4043        if( xVSS_context->pMCSparamsList
4044            == M4OSA_NULL ) /* Means it is the first element of the list */
4045        {
4046            /* Initialize the xVSS context with the first element of the list */
4047            xVSS_context->pMCSparamsList = pParams;
4048
4049        }
4050        else
4051        {
4052            M4xVSS_MCS_params *pParams_temp = xVSS_context->pMCSparamsList;
4053            M4xVSS_MCS_params *pParams_prev = M4OSA_NULL;
4054
4055            /* Parse MCS params chained list to find and delete BGM element */
4056            while( pParams_temp != M4OSA_NULL )
4057            {
4058                if( pParams_temp->isBGM == M4OSA_TRUE )
4059                {
4060                    /* Remove this element */
4061                    if( pParams_temp->pFileIn != M4OSA_NULL )
4062                    {
4063                        free(pParams_temp->pFileIn);
4064                        pParams_temp->pFileIn = M4OSA_NULL;
4065                    }
4066
4067                    if( pParams_temp->pFileOut != M4OSA_NULL )
4068                    {
4069                        /* Remove PCM temporary file */
4070                        remove((const char *)pParams_temp->pFileOut);
4071                        free(pParams_temp->pFileOut);
4072                        pParams_temp->pFileOut = M4OSA_NULL;
4073                    }
4074                    /* Chain previous element with next element = remove BGM chained
4075                         list element */
4076                    if( pParams_prev != M4OSA_NULL )
4077                    {
4078                        pParams_prev->pNext = pParams_temp->pNext;
4079                    }
4080                    /* If current pointer is the first of the chained list and next pointer of
4081                    the chained list is NULL */
4082                    /* it means that there was only one element in the list */
4083                    /* => we put the context variable to NULL to reaffect the first chained list
4084                     element */
4085                    if( pParams_temp == xVSS_context->pMCSparamsList
4086                        && pParams_temp->pNext == M4OSA_NULL )
4087                    {
4088                        xVSS_context->pMCSparamsList = M4OSA_NULL;
4089                    }
4090                    /* In that case, BGM pointer is the first one, but there are others elements
4091                     after it */
4092                    /* So, we need to change first chained list element */
4093                    else if( pParams_temp->pNext != M4OSA_NULL
4094                        && pParams_prev == M4OSA_NULL )
4095                    {
4096                        xVSS_context->pMCSparamsList = pParams_temp->pNext;
4097                    }
4098
4099                    if( pParams_temp->pNext != M4OSA_NULL )
4100                    {
4101                        pParams_prev = pParams_temp->pNext;
4102                        free(pParams_temp);
4103                        pParams_temp = M4OSA_NULL;
4104                        pParams_temp = pParams_prev;
4105                    }
4106                    else
4107                    {
4108                        free(pParams_temp);
4109                        pParams_temp = M4OSA_NULL;
4110                    }
4111                }
4112                else
4113                {
4114                    pParams_prev = pParams_temp;
4115                    pParams_temp = pParams_temp->pNext;
4116                }
4117            }
4118            /* We need to initialize the last element of the chained list to be able to add new
4119             BGM element */
4120            pMCS_last = pParams_prev;
4121
4122            if( xVSS_context->pMCSparamsList == M4OSA_NULL )
4123            {
4124                /* In that case, it means that there was only one element in the chained list */
4125                /* So, we need to save the new params*/
4126                xVSS_context->pMCSparamsList = pParams;
4127            }
4128            else
4129            {
4130                /* Update next pointer of the previous last element of the chain */
4131                pMCS_last->pNext = pParams;
4132            }
4133
4134        }
4135
4136        /* Fill the last M4xVSS_MCS_params element */
4137        pParams->InputFileType =
4138            xVSS_context->pSettings->xVSS.pBGMtrack->FileType;
4139        pParams->OutputFileType = M4VIDEOEDITING_kFileType_PCM;
4140        pParams->OutputVideoFormat = M4VIDEOEDITING_kNoneVideo;
4141        pParams->OutputVideoFrameSize = M4VIDEOEDITING_kQCIF;
4142        pParams->OutputVideoFrameRate = M4VIDEOEDITING_k15_FPS;
4143
4144        if( xVSS_context->pSettings->xVSS.outputAudioFormat
4145            == M4VIDEOEDITING_kAAC )
4146        {
4147            pParams->OutputAudioFormat = M4VIDEOEDITING_kAAC;
4148            pParams->OutputAudioSamplingFrequency = M4VIDEOEDITING_kDefault_ASF;
4149
4150            /*FB: VAL CR P4ME00003076
4151            The output audio bitrate in the AAC case is now directly given by the user*/
4152            /*Check if the audio bitrate is correctly defined*/
4153            /*Mono
4154            MCS values for AAC Mono are min: 16kbps and max: 192 kbps*/
4155            if( xVSS_context->pSettings->xVSS.outputAudioBitrate
4156                >= M4VIDEOEDITING_k16_KBPS
4157                && xVSS_context->pSettings->xVSS.outputAudioBitrate
4158                <= M4VIDEOEDITING_k192_KBPS
4159                && xVSS_context->pSettings->xVSS.bAudioMono == M4OSA_TRUE )
4160            {
4161                pParams->OutputAudioBitrate =
4162                    xVSS_context->pSettings->xVSS.outputAudioBitrate;
4163            }
4164            /*Stereo
4165            MCS values for AAC Mono are min: 32kbps and max: 192 kbps*/
4166            else if( xVSS_context->pSettings->xVSS.outputAudioBitrate
4167                >= M4VIDEOEDITING_k32_KBPS
4168                && xVSS_context->pSettings->xVSS.outputAudioBitrate
4169                <= M4VIDEOEDITING_k192_KBPS
4170                && xVSS_context->pSettings->xVSS.bAudioMono == M4OSA_FALSE )
4171            {
4172                pParams->OutputAudioBitrate =
4173                    xVSS_context->pSettings->xVSS.outputAudioBitrate;
4174            }
4175            else
4176            {
4177                pParams->OutputAudioBitrate = M4VIDEOEDITING_k32_KBPS;
4178            }
4179            pParams->bAudioMono = xVSS_context->pSettings->xVSS.bAudioMono;
4180        }
4181        else
4182        {
4183            pParams->OutputAudioFormat = M4VIDEOEDITING_kAMR_NB;
4184            pParams->OutputAudioSamplingFrequency = M4VIDEOEDITING_kDefault_ASF;
4185            pParams->OutputAudioBitrate = M4VIDEOEDITING_k12_2_KBPS;
4186            pParams->bAudioMono = M4OSA_TRUE;
4187        }
4188        pParams->OutputVideoBitrate = M4VIDEOEDITING_kUndefinedBitrate;
4189
4190        /* Prepare output filename */
4191        /* 21 is the size of "preview_16000_2.pcm" + \0 */
4192        out_pcm =
4193            (M4OSA_Char *)M4OSA_32bitAlignedMalloc(strlen(xVSS_context->pTempPath)
4194            + 21, M4VS, (M4OSA_Char *)"Temp char* for pcmPreviewFile");
4195
4196        if( out_pcm == M4OSA_NULL )
4197        {
4198            M4xVSS_freeCommand(xVSS_context);
4199            M4OSA_TRACE1_0("Allocation error in M4xVSS_Init");
4200            return M4ERR_ALLOC;
4201        }
4202
4203        /* Copy temporary path to final preview path string */
4204        M4OSA_chrNCopy(out_pcm, xVSS_context->pTempPath,
4205            strlen(xVSS_context->pTempPath) + 1);
4206
4207        /* Depending of the output sample frequency and nb of channels, we construct preview
4208        output filename */
4209        if( xVSS_context->pSettings->xVSS.outputAudioFormat
4210            == M4VIDEOEDITING_kAAC )
4211        {
4212            /* Construct output temporary PCM filename */
4213            if( xVSS_context->pSettings->xVSS.bAudioMono == M4OSA_TRUE )
4214            {
4215                strncat((char *)out_pcm, (const char *)"preview_16000_1.pcm\0",
4216                    20);
4217            }
4218            else
4219            {
4220                strncat((char *)out_pcm, (const char *)"preview_16000_2.pcm\0",
4221                    20);
4222            }
4223        }
4224        else if( xVSS_context->pSettings->xVSS.outputAudioFormat
4225            == M4VIDEOEDITING_kAMR_NB )
4226        {
4227            /* Construct output temporary PCM filename */
4228            strncat((char *)out_pcm, (const char *)"preview_08000_1.pcm\0", 20);
4229        }
4230        else
4231        {
4232            if( out_pcm != M4OSA_NULL )
4233            {
4234                free(out_pcm);
4235                out_pcm = M4OSA_NULL;
4236            }
4237            M4xVSS_freeCommand(xVSS_context);
4238            M4OSA_TRACE1_0("Bad audio output format \n");
4239            return M4ERR_PARAMETER;
4240        }
4241
4242        xVSS_context->pcmPreviewFile = out_pcm;
4243
4244        /**
4245        * UTF conversion: convert into the customer format, before being used*/
4246        pDecodedPath = out_pcm;
4247        length = strlen(pDecodedPath);
4248
4249        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
4250            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
4251            != M4OSA_NULL )
4252        {
4253            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
4254                (M4OSA_Void *)out_pcm, (M4OSA_Void *)xVSS_context->
4255                UTFConversionContext.pTempOutConversionBuffer, &length);
4256
4257            if( err != M4NO_ERROR )
4258            {
4259                M4OSA_TRACE1_1(
4260                    "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
4261                    err);
4262                /* Free Send command */
4263                M4xVSS_freeCommand(xVSS_context);
4264                return err;
4265            }
4266            pDecodedPath =
4267                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
4268        }
4269
4270        /**
4271        * End of the UTF conversion, use the converted file path*/
4272        xVSS_context->pcmPreviewFile =
4273            (M4OSA_Void *)M4OSA_32bitAlignedMalloc(length + 1, M4VS,
4274            (M4OSA_Char *)"pcmPreviewFile");
4275
4276        if( xVSS_context->pcmPreviewFile == M4OSA_NULL )
4277        {
4278            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
4279            free(out_pcm);
4280            out_pcm = M4OSA_NULL;
4281            /*FB: to avoid leaks when there is an error in the send command*/
4282            /* Free Send command */
4283            M4xVSS_freeCommand(xVSS_context);
4284            /**/
4285            return M4ERR_ALLOC;
4286        }
4287        memcpy((void *)xVSS_context->pcmPreviewFile, (void *)pDecodedPath, length + 1);
4288
4289        /* Free temporary output filename */
4290        if( out_pcm != M4OSA_NULL )
4291        {
4292            free(out_pcm);
4293            out_pcm = M4OSA_NULL;
4294        }
4295
4296        pParams->pFileOut = M4OSA_32bitAlignedMalloc((length + 1), M4VS,
4297            (M4OSA_Char *)"MCS BGM Params: file out");
4298
4299        if( pParams->pFileOut == M4OSA_NULL )
4300        {
4301            M4xVSS_freeCommand(xVSS_context);
4302            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
4303            return M4ERR_ALLOC;
4304        }
4305        pParams->pFileTemp = M4OSA_NULL;
4306
4307        memcpy((void *)pParams->pFileOut,(void *) xVSS_context->pcmPreviewFile,
4308            (length + 1)); /* Copy output file path */
4309
4310        /**
4311        * UTF conversion: convert into the customer format, before being used*/
4312
4313        pDecodedPath = xVSS_context->pSettings->xVSS.pBGMtrack->pFile;
4314        length = strlen(pDecodedPath);
4315
4316        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
4317            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
4318            != M4OSA_NULL )
4319        {
4320            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
4321                (M4OSA_Void *)xVSS_context->pSettings->xVSS.pBGMtrack->
4322                pFile, (M4OSA_Void *)xVSS_context->
4323                UTFConversionContext.pTempOutConversionBuffer, &length);
4324
4325            if( err != M4NO_ERROR )
4326            {
4327                M4OSA_TRACE1_1(
4328                    "M4xVSS_SendCommand: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
4329                    err);
4330                /* Free Send command */
4331                M4xVSS_freeCommand(xVSS_context);
4332                return err;
4333            }
4334            pDecodedPath =
4335                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
4336        }
4337
4338        /**
4339        * End of the UTF conversion, use the converted file path*/
4340        pParams->pFileIn = (M4OSA_Void *)M4OSA_32bitAlignedMalloc((length + 1), M4VS,
4341            (M4OSA_Char *)"MCS BGM Params: file in");
4342
4343        if( pParams->pFileIn == M4OSA_NULL )
4344        {
4345            M4xVSS_freeCommand(xVSS_context);
4346            M4OSA_TRACE1_0("Allocation error in M4xVSS_SendCommand");
4347            return M4ERR_ALLOC;
4348        }
4349        memcpy((void *)pParams->pFileIn, (void *)pDecodedPath,
4350            (length + 1)); /* Copy input file path */
4351
4352        pParams->isBGM = M4OSA_TRUE;
4353        pParams->isCreated = M4OSA_FALSE;
4354        xVSS_context->nbStepTotal++;
4355        bIsTranscoding = M4OSA_TRUE;
4356#endif /* PREVIEW_ENABLED */
4357
4358    }
4359    else if( pSettings->xVSS.pBGMtrack != M4OSA_NULL
4360        && isNewBGM == M4OSA_FALSE )
4361    {
4362#ifdef PREVIEW_ENABLED
4363        /* BGM is the same as previously, no need to redecode audio */
4364        /* Need to update MCS params chained list, to signal M4xVSS_step function to skip
4365        BGM decoding */
4366
4367        M4xVSS_MCS_params *pParams_temp = xVSS_context->pMCSparamsList;
4368        M4xVSS_MCS_params *pParams_prev = M4OSA_NULL;
4369
4370#endif /* PREVIEW_ENABLED */
4371        /* We save output file pointer, because we will need to use it when saving audio
4372         mixed file (last save step) */
4373
4374        xVSS_context->pOutputFile = xVSS_context->pSettings->pOutputFile;
4375        xVSS_context->pTemporaryFile = xVSS_context->pSettings->pTemporaryFile;
4376
4377        /* Re-write BGM settings in case they have changed between two sendCommand */
4378        xVSS_context->pSettings->xVSS.pBGMtrack->uiAddCts =
4379            pSettings->xVSS.pBGMtrack->uiAddCts;
4380        xVSS_context->pSettings->xVSS.pBGMtrack->uiAddVolume =
4381            pSettings->xVSS.pBGMtrack->uiAddVolume;
4382        xVSS_context->pSettings->xVSS.pBGMtrack->uiBeginLoop =
4383            pSettings->xVSS.pBGMtrack->uiBeginLoop;
4384        xVSS_context->pSettings->xVSS.pBGMtrack->uiEndLoop =
4385            pSettings->xVSS.pBGMtrack->uiEndLoop;
4386
4387#ifdef PREVIEW_ENABLED
4388        /* Parse MCS params chained list to find and delete BGM element */
4389
4390        while( pParams_temp != M4OSA_NULL )
4391        {
4392            if( pParams_temp->isBGM == M4OSA_TRUE )
4393            {
4394                pParams_temp->isCreated = M4OSA_TRUE;
4395                break;
4396            }
4397            pParams_prev = pParams_temp;
4398            pParams_temp = pParams_temp->pNext;
4399        }
4400
4401#endif /* PREVIEW_ENABLED */
4402
4403        M4OSA_TRACE2_0("M4xVSS_SendCommand has been recalled, BGM is the same");
4404    }
4405    else
4406    {
4407        M4OSA_TRACE1_0("No BGM in this xVSS command");
4408
4409        if( xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
4410        {
4411#ifdef PREVIEW_ENABLED
4412            /* Need to remove MCS previous params chained list */
4413
4414            M4xVSS_MCS_params *pParams_temp = xVSS_context->pMCSparamsList;
4415            M4xVSS_MCS_params *pParams_prev = M4OSA_NULL;
4416
4417            /* Parse MCS params chained list to find and delete BGM element */
4418            while( pParams_temp != M4OSA_NULL )
4419            {
4420                if( pParams_temp->isBGM == M4OSA_TRUE )
4421                {
4422                    /* Remove this element */
4423                    if( pParams_temp->pFileIn != M4OSA_NULL )
4424                    {
4425                        free(pParams_temp->pFileIn);
4426                        pParams_temp->pFileIn = M4OSA_NULL;
4427                    }
4428
4429                    if( pParams_temp->pFileOut != M4OSA_NULL )
4430                    {
4431                        free(pParams_temp->pFileOut);
4432                        pParams_temp->pFileOut = M4OSA_NULL;
4433                    }
4434                    /* Chain previous element with next element */
4435                    if( pParams_prev != M4OSA_NULL )
4436                    {
4437                        pParams_prev->pNext = pParams_temp->pNext;
4438                    }
4439                    /* If current pointer is the first of the chained list and next pointer
4440                     of the chained list is NULL */
4441                    /* it means that there was only one element in the list */
4442                    /* => we put the context variable to NULL */
4443                    if( pParams_temp == xVSS_context->pMCSparamsList
4444                        && pParams_temp->pNext == M4OSA_NULL )
4445                    {
4446                        free(pParams_temp);
4447                        xVSS_context->pMCSparamsList = M4OSA_NULL;
4448                    }
4449                    /* In that case, BGM pointer is the first one, but there are others
4450                     elements after it */
4451                    /* So, we need to change first chained list element */
4452                    else if( pParams_temp->pNext != M4OSA_NULL )
4453                    {
4454                        xVSS_context->pMCSparamsList = pParams_temp->pNext;
4455                        free(pParams_temp);
4456                        pParams_temp = M4OSA_NULL;
4457                    }
4458                    /* In all other cases, nothing else to do except freeing the chained
4459                    list element */
4460                    else
4461                    {
4462                        free(pParams_temp);
4463                        pParams_temp = M4OSA_NULL;
4464                    }
4465                    break;
4466                }
4467                pParams_prev = pParams_temp;
4468                pParams_temp = pParams_temp->pNext;
4469            }
4470
4471#endif /* PREVIEW_ENABLED */
4472            /* Here, we unallocate all BGM components and put xVSS_context->pSettings->
4473            xVSS.pBGMtrack to NULL */
4474
4475            if( xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
4476            {
4477                if( xVSS_context->pSettings->xVSS.pBGMtrack->pFile
4478                    != M4OSA_NULL )
4479                {
4480                    free(xVSS_context->pSettings->xVSS.pBGMtrack->pFile);
4481                    xVSS_context->pSettings->xVSS.pBGMtrack->pFile = M4OSA_NULL;
4482                }
4483                free(xVSS_context->pSettings->xVSS.pBGMtrack);
4484                xVSS_context->pSettings->xVSS.pBGMtrack = M4OSA_NULL;
4485            }
4486        }
4487    }
4488
4489    /* Changed to be able to mix with video only files -> in case no master clip is found
4490    (i.e only JPG input or video only input) */
4491    /* and if there is a BGM, we force the added volume to 100 (i.e replace audio) */
4492
4493    if( masterClip == -1
4494        && xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
4495    {
4496        /* In that case, it means that no input 3GP file has a video track.
4497        Therefore, if a mixing is asked, it will fail. Thus, we force replace audio. */
4498        xVSS_context->pSettings->xVSS.pBGMtrack->uiAddVolume = 100;
4499    }
4500
4501    /* Save clip number to know if a M4xVSS_sendCommand has already been called */
4502    xVSS_context->previousClipNumber = xVSS_context->pSettings->uiClipNumber;
4503
4504    /* Change state */
4505    xVSS_context->m_state = M4xVSS_kStateAnalyzing;
4506
4507    /* In case of MMS use case, we compute here the max video bitrate */
4508    /* In case of too low bitrate, a specific warning is returned */
4509    if( xVSS_context->pSettings->xVSS.outputFileSize != 0 && totalDuration > 0 )
4510    {
4511        M4OSA_UInt32 targetedBitrate = 0;
4512        M4VIDEOEDITING_ClipProperties fileProperties;
4513        M4OSA_Double ratio;
4514
4515        if( xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
4516        {
4517            if( xVSS_context->pSettings->xVSS.pBGMtrack->uiAddVolume
4518                == 100 ) /* We are in "replace audio mode, need to check the filetype */
4519            {
4520                if( xVSS_context->pSettings->xVSS.pBGMtrack->FileType
4521                    == M4VIDEOEDITING_kFileType_3GPP )
4522                {
4523                    M4OSA_Void *pDecodedPath;
4524                    /**
4525                    * UTF conversion: convert into the customer format, before being used*/
4526                    pDecodedPath =
4527                        xVSS_context->pSettings->xVSS.pBGMtrack->pFile;
4528                    length = strlen(pDecodedPath);
4529
4530                    if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
4531                        != M4OSA_NULL && xVSS_context->
4532                        UTFConversionContext.pTempOutConversionBuffer
4533                        != M4OSA_NULL )
4534                    {
4535                        err = M4xVSS_internalConvertFromUTF8(xVSS_context,
4536                            (M4OSA_Void *)xVSS_context->pSettings->
4537                            xVSS.pBGMtrack->pFile,
4538                            (M4OSA_Void *)xVSS_context->
4539                            UTFConversionContext.
4540                            pTempOutConversionBuffer, &length);
4541
4542                        if( err != M4NO_ERROR )
4543                        {
4544                            M4OSA_TRACE1_1("M4xVSS_SendCommand: \
4545                                M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
4546                                err);
4547                            /* Free Send command */
4548                            M4xVSS_freeCommand(xVSS_context);
4549                            return err;
4550                        }
4551                        pDecodedPath = xVSS_context->
4552                            UTFConversionContext.pTempOutConversionBuffer;
4553                    }
4554
4555                    /**
4556                    * End of the UTF conversion, use the converted file path*/
4557                    err =
4558                        M4xVSS_internalGetProperties(xVSS_context, pDecodedPath,
4559                        &fileProperties);
4560
4561                    /* Get the properties of the BGM track */
4562                    /*err = M4xVSS_internalGetProperties(xVSS_context, xVSS_context->pSettings->
4563                    xVSS.pBGMtrack->pFile, &fileProperties);*/
4564                    if( err != M4NO_ERROR )
4565                    {
4566                        M4OSA_TRACE1_1(
4567                            "M4xVSS_sendCommand: M4xVSS_internalGetProperties returned an error:\
4568                             0x%x", err);
4569                        return err;
4570                    }
4571
4572                    if( fileProperties.AudioStreamType
4573                        != M4VIDEOEDITING_kAMR_NB )
4574                    {
4575                        M4OSA_TRACE1_0(
4576                            "M4xVSS_sendCommand: Impossible to use MMS mode with BGM != AMR-NB");
4577                        return M4ERR_PARAMETER;
4578                    }
4579                }
4580                else if( xVSS_context->pSettings->xVSS.pBGMtrack->FileType
4581                    != M4VIDEOEDITING_kFileType_AMR
4582                    && xVSS_context->pSettings->xVSS.pBGMtrack->FileType
4583                    != M4VIDEOEDITING_kFileType_MP3 )
4584                {
4585                    M4OSA_TRACE1_0("M4xVSS_sendCommand: Bad input BGM file");
4586                    return M4ERR_PARAMETER;
4587                }
4588            }
4589        }
4590
4591        /* Compute targeted bitrate, with 8% margin (moov) */
4592        if( totalDuration > 1000 )
4593        {
4594            targetedBitrate =
4595                (M4OSA_UInt32)(( xVSS_context->pSettings->xVSS.outputFileSize
4596                * 8 * 0.84) / (totalDuration / 1000));
4597        }
4598        else
4599        {
4600            targetedBitrate = 0;
4601        }
4602
4603        /* Remove audio bitrate */
4604        if( targetedBitrate >= 12200 )
4605        {
4606            targetedBitrate -= 12200; /* Only AMR is supported in MMS case */
4607        }
4608        else
4609        {
4610            targetedBitrate = 0;
4611        }
4612
4613        /* Compute an indicator of "complexity" depending on nb of sequences and total duration */
4614        /* The highest is the number of sequences, the more there are some I frames */
4615        /* In that case, it is necessary to reduce the target bitrate */
4616        ratio =
4617            (M4OSA_Double)((M4OSA_Double)(xVSS_context->pSettings->uiClipNumber
4618            * 100000) / (M4OSA_Double)(totalDuration));
4619        M4OSA_TRACE2_3(
4620            "Ratio clip_nb/duration = %f\nTargeted bitrate = %d\nTotal duration: %d",
4621            (M4OSA_Double)((M4OSA_Double)(xVSS_context->pSettings->uiClipNumber
4622            * 100000) / (M4OSA_Double)(totalDuration)),
4623            targetedBitrate, totalDuration);
4624
4625        if( ratio > 50 && ratio <= 75 )
4626        {
4627            /* It means that there is a potential risk of having a higher file size
4628            than specified */
4629            targetedBitrate -= (M4OSA_UInt32)(targetedBitrate * 0.1);
4630            M4OSA_TRACE2_2(
4631                "New bitrate1 !!\nRatio clip_nb/duration = %f\nTargeted bitrate = %d",
4632                ratio, targetedBitrate);
4633        }
4634        else if( ratio > 75 )
4635        {
4636            targetedBitrate -= (M4OSA_UInt32)(targetedBitrate * 0.15);
4637            M4OSA_TRACE2_2(
4638                "New bitrate2 !!\nRatio clip_nb/duration = %f\nTargeted bitrate = %d",
4639                ratio, targetedBitrate);
4640        }
4641
4642        /*CR 3283 MMS use case for VAL:
4643        Decrease the output file size to keep a margin of 5%
4644        The writer will stop when the targeted output file size will be reached*/
4645        xVSS_context->pSettings->xVSS.outputFileSize -=
4646            (M4OSA_UInt32)(xVSS_context->pSettings->xVSS.outputFileSize * 0.05);
4647
4648        switch( xVSS_context->pSettings->xVSS.outputVideoSize )
4649        {
4650            case M4VIDEOEDITING_kSQCIF:
4651                if( targetedBitrate < 32000 )
4652                {
4653                    xVSS_context->targetedBitrate = 32000;
4654                    return M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED;
4655                }
4656                break;
4657
4658            case M4VIDEOEDITING_kQQVGA:
4659                if( targetedBitrate < 32000 )              /*48000)*/
4660                {
4661                    xVSS_context->targetedBitrate = 32000; /*48000;*/
4662                    return M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED;
4663                }
4664                break;
4665
4666            case M4VIDEOEDITING_kQCIF:
4667                if( targetedBitrate < 48000 )              /*64000)*/
4668                {
4669                    xVSS_context->targetedBitrate = 48000; /*64000;*/
4670                    return M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED;
4671                }
4672                break;
4673
4674            case M4VIDEOEDITING_kQVGA:
4675                if( targetedBitrate < 64000 )              /*128000)*/
4676                {
4677                    xVSS_context->targetedBitrate = 64000; /*128000;*/
4678                    return M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED;
4679                }
4680                break;
4681
4682            case M4VIDEOEDITING_kCIF:
4683                if( targetedBitrate < 128000 )
4684                {
4685                    xVSS_context->targetedBitrate = 128000;
4686                    return M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED;
4687                }
4688                break;
4689
4690            case M4VIDEOEDITING_kVGA:
4691                if( targetedBitrate < 192000 )
4692                {
4693                    xVSS_context->targetedBitrate = 192000;
4694                    return M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED;
4695                }
4696                break;
4697
4698            default:
4699                /* Cannot happen */
4700                M4OSA_TRACE1_0(
4701                    "M4xVSS_sendCommand: Error in output fileSize !");
4702                return M4ERR_PARAMETER;
4703                break;
4704        }
4705        xVSS_context->targetedBitrate = (M4OSA_UInt32)targetedBitrate;
4706    }
4707
4708    if( bIsTranscoding )
4709    {
4710        return M4VSS3GPP_WAR_TRANSCODING_NECESSARY;
4711    }
4712    else
4713    {
4714        return M4NO_ERROR;
4715    }
4716}
4717
4718/**
4719 ******************************************************************************
4720 * prototype    M4OSA_ERR M4xVSS_SaveStart(M4OSA_Context pContext, M4OSA_Char* pFilePath)
4721 * @brief        This function prepare the save
4722 * @note        The xVSS create 3GP edited final file
4723 *                This function must be called once M4xVSS_Step has returned
4724 *                M4VSS3GPP_WAR_ANALYZING_DONE
4725 *                After this function, the user must call M4xVSS_Step until
4726 *                it returns another error than M4NO_ERROR.
4727 *
4728 * @param    pContext            (IN) Pointer on the xVSS edit context
4729 * @param    pFilePath            (IN) If the user wants to provide a different
4730 *                                output filename, else can be NULL (allocated by the user)
4731 * @return    M4NO_ERROR:            No error
4732 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
4733 * @return    M4ERR_ALLOC:        Memory allocation has failed
4734 * @return    M4ERR_STATE:        This function cannot not be called at this time
4735 ******************************************************************************
4736 */
4737M4OSA_ERR M4xVSS_SaveStart( M4OSA_Context pContext, M4OSA_Void *pFilePath,
4738                           M4OSA_UInt32 filePathSize )
4739{
4740    M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
4741    M4OSA_ERR err;
4742
4743    /*Add for UTF conversion: copy the pSettings structure into a new pCurrentEditSettings*/
4744    M4VSS3GPP_EditSettings *pEditSavingSettings = M4OSA_NULL;
4745    M4OSA_UInt8 i, j;
4746    M4OSA_UInt32 offset = 0;
4747    M4OSA_UInt8 nbEffects = 0;
4748    /*only for UTF conversion support*/
4749    M4OSA_Void *pDecodedPath = M4OSA_NULL;
4750    M4OSA_UInt32 length = 0;
4751    /**/
4752
4753    /* Check state */
4754    if( xVSS_context->m_state != M4xVSS_kStateOpened )
4755    {
4756        M4OSA_TRACE1_1(
4757            "Bad state when calling M4xVSS_SaveStart function! State is %d",
4758            xVSS_context->m_state);
4759        return M4ERR_STATE;
4760    }
4761
4762    /* RC: to temporary handle changing of output filepath */
4763    /* TO BE CHANGED CLEANLY WITH A MALLOC/MEMCPY !!!! */
4764    if( pFilePath != M4OSA_NULL )
4765    {
4766        if( xVSS_context->pSettings->pOutputFile != M4OSA_NULL )
4767        {
4768            /*it means that pOutputFile has been allocated in M4xVSS_sendCommand()*/
4769            free(xVSS_context->pSettings->pOutputFile);
4770            xVSS_context->pSettings->pOutputFile = M4OSA_NULL;
4771            xVSS_context->pSettings->uiOutputPathSize = 0;
4772        }
4773
4774        pDecodedPath = pFilePath;
4775        /*As all inputs of the xVSS are in UTF8, convert the output file path into the customer
4776         format*/
4777        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
4778            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
4779            != M4OSA_NULL )
4780        {
4781            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
4782                (M4OSA_Void *)pFilePath, (M4OSA_Void *)xVSS_context->
4783                UTFConversionContext.pTempOutConversionBuffer, &length);
4784
4785            if( err != M4NO_ERROR )
4786            {
4787                M4OSA_TRACE1_1(
4788                    "M4xVSS_SaveStart: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
4789                    err);
4790                return err;
4791            }
4792            pDecodedPath =
4793                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
4794            filePathSize = length;
4795        }
4796
4797        xVSS_context->pOutputFile =
4798            (M4OSA_Void *)M4OSA_32bitAlignedMalloc(filePathSize + 1, M4VS,
4799            (M4OSA_Char *)"M4xVSS_SaveStart: output file");
4800
4801        if( xVSS_context->pOutputFile == M4OSA_NULL )
4802        {
4803            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
4804            return M4ERR_ALLOC;
4805        }
4806        memcpy((void *)xVSS_context->pOutputFile, (void *)pDecodedPath, filePathSize + 1);
4807        xVSS_context->pOutputFile[filePathSize] = '\0';
4808        xVSS_context->pSettings->pOutputFile = xVSS_context->pOutputFile;
4809        xVSS_context->pSettings->uiOutputPathSize = filePathSize;
4810    }
4811
4812    /**
4813    ***/
4814
4815    /*FB: Add for UTF conversion: copy the pSettings structure into a new pCurrentEditSettings*/
4816    /*It is the same principle as in the PreviewStart()*/
4817    pEditSavingSettings =
4818        (M4VSS3GPP_EditSettings *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_EditSettings),
4819        M4VS, (M4OSA_Char *)"Saving, copy of VSS structure");
4820
4821    if( pEditSavingSettings == M4OSA_NULL )
4822    {
4823        M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
4824
4825        if( xVSS_context->pOutputFile != M4OSA_NULL )
4826        {
4827            free(xVSS_context->pOutputFile);
4828            xVSS_context->pOutputFile = M4OSA_NULL;
4829        }
4830        return M4ERR_ALLOC;
4831    }
4832
4833    /* Copy settings from input structure */
4834    memcpy((void *) &(pEditSavingSettings->xVSS),
4835        (void *) &(xVSS_context->pSettings->xVSS),
4836        sizeof(M4xVSS_EditSettings));
4837
4838    /* Initialize pEditSavingSettings structure */
4839    pEditSavingSettings->xVSS.pBGMtrack = M4OSA_NULL;
4840
4841    pEditSavingSettings->videoFrameRate =
4842        xVSS_context->pSettings->videoFrameRate;
4843    pEditSavingSettings->uiClipNumber = xVSS_context->pSettings->uiClipNumber;
4844    pEditSavingSettings->uiMasterClip =
4845        xVSS_context->pSettings->uiMasterClip; /* VSS2.0 mandatory parameter */
4846
4847    /* Allocate savingSettings.pClipList/pTransitions structure */
4848    pEditSavingSettings->pClipList = (M4VSS3GPP_ClipSettings *
4849        * )M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_ClipSettings *)
4850        *pEditSavingSettings->uiClipNumber,
4851        M4VS, (M4OSA_Char *)"xVSS, saving , copy of pClipList");
4852
4853    if( pEditSavingSettings->pClipList == M4OSA_NULL )
4854    {
4855        M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
4856
4857        if( xVSS_context->pOutputFile != M4OSA_NULL )
4858        {
4859            free(xVSS_context->pOutputFile);
4860            xVSS_context->pOutputFile = M4OSA_NULL;
4861        }
4862        return M4ERR_ALLOC;
4863    }
4864
4865    if( pEditSavingSettings->uiClipNumber > 1 )
4866    {
4867        pEditSavingSettings->pTransitionList = (M4VSS3GPP_TransitionSettings *
4868            * )M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_TransitionSettings *)
4869            *(pEditSavingSettings->uiClipNumber - 1),
4870            M4VS, (M4OSA_Char *)"xVSS, saving, copy of pTransitionList");
4871
4872        if( pEditSavingSettings->pTransitionList == M4OSA_NULL )
4873        {
4874            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
4875
4876            if( xVSS_context->pOutputFile != M4OSA_NULL )
4877            {
4878                free(xVSS_context->pOutputFile);
4879                xVSS_context->pOutputFile = M4OSA_NULL;
4880            }
4881            return M4ERR_ALLOC;
4882        }
4883    }
4884    else
4885    {
4886        pEditSavingSettings->pTransitionList = M4OSA_NULL;
4887    }
4888
4889    for ( i = 0; i < pEditSavingSettings->uiClipNumber; i++ )
4890    {
4891        pEditSavingSettings->pClipList[i] = (M4VSS3GPP_ClipSettings
4892            *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_ClipSettings),
4893            M4VS, (M4OSA_Char *)"saving clip settings");
4894
4895        if( pEditSavingSettings->pClipList[i] == M4OSA_NULL )
4896        {
4897            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
4898
4899            if( xVSS_context->pOutputFile != M4OSA_NULL )
4900            {
4901                free(xVSS_context->pOutputFile);
4902                xVSS_context->pOutputFile = M4OSA_NULL;
4903            }
4904            return M4ERR_ALLOC;
4905        }
4906
4907        if( i < pEditSavingSettings->uiClipNumber
4908            - 1 ) /* Because there is 1 less transition than clip number */
4909        {
4910            pEditSavingSettings->pTransitionList[i] =
4911                (M4VSS3GPP_TransitionSettings
4912                *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_TransitionSettings),
4913                M4VS, (M4OSA_Char *)"saving transition settings");
4914
4915            if( pEditSavingSettings->pTransitionList[i] == M4OSA_NULL )
4916            {
4917                M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
4918
4919                if( xVSS_context->pOutputFile != M4OSA_NULL )
4920                {
4921                    free(xVSS_context->pOutputFile);
4922                    xVSS_context->pOutputFile = M4OSA_NULL;
4923                }
4924                return M4ERR_ALLOC;
4925            }
4926        }
4927    }
4928
4929    for ( i = 0; i < xVSS_context->pSettings->uiClipNumber; i++ )
4930    {
4931        // Add MP4 file support
4932
4933        if( ( xVSS_context->pSettings->pClipList[i]->FileType
4934            == M4VIDEOEDITING_kFileType_3GPP)
4935            || (xVSS_context->pSettings->pClipList[i]->FileType
4936            == M4VIDEOEDITING_kFileType_MP4)
4937            || (xVSS_context->pSettings->pClipList[i]->FileType
4938            == M4VIDEOEDITING_kFileType_M4V)
4939            || (xVSS_context->pSettings->pClipList[i]->FileType
4940            == M4VIDEOEDITING_kFileType_ARGB8888))
4941
4942        {
4943            /* Copy data from given structure to our saving structure */
4944            M4xVSS_DuplicateClipSettings(pEditSavingSettings->pClipList[i],
4945                xVSS_context->pSettings->pClipList[i],
4946                M4OSA_FALSE /* remove effects */);
4947
4948            /**
4949            * UTF conversion: convert into the customer format, before being used*/
4950            pDecodedPath = pEditSavingSettings->pClipList[i]->pFile;
4951            length = strlen(pDecodedPath);
4952
4953            if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct
4954                != M4OSA_NULL && xVSS_context->
4955                UTFConversionContext.pTempOutConversionBuffer
4956                != M4OSA_NULL )
4957            {
4958                err =
4959                    M4xVSS_internalConvertFromUTF8(xVSS_context, (M4OSA_Void
4960                    *)pEditSavingSettings->pClipList[i]->pFile,
4961                    (M4OSA_Void *)xVSS_context->
4962                    UTFConversionContext.pTempOutConversionBuffer,
4963                    &length);
4964
4965                if( err != M4NO_ERROR )
4966                {
4967                    M4OSA_TRACE1_1(
4968                        "M4xVSS_SaveStart: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
4969                        err);
4970
4971                    if( xVSS_context->pOutputFile != M4OSA_NULL )
4972                    {
4973                        free(xVSS_context->pOutputFile);
4974                        xVSS_context->pOutputFile = M4OSA_NULL;
4975                    }
4976                    return err;
4977                }
4978                pDecodedPath = xVSS_context->
4979                    UTFConversionContext.pTempOutConversionBuffer;
4980
4981                /**
4982                * End of the UTF conversion, use the converted file path*/
4983                free(
4984                    pEditSavingSettings->pClipList[i]->pFile);
4985                pEditSavingSettings->pClipList[i]->pFile = (M4OSA_Void
4986                    *)M4OSA_32bitAlignedMalloc((length + 1),
4987                    M4VS, (M4OSA_Char *)"saving transition settings");
4988
4989                if( pEditSavingSettings->pClipList[i]->pFile == M4OSA_NULL )
4990                {
4991                    M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
4992
4993                    if( xVSS_context->pOutputFile != M4OSA_NULL )
4994                    {
4995                        free(xVSS_context->pOutputFile);
4996                        xVSS_context->pOutputFile = M4OSA_NULL;
4997                    }
4998                    return M4ERR_ALLOC;
4999                }
5000                memcpy((void *)pEditSavingSettings->pClipList[i]->pFile,
5001                    (void *)pDecodedPath, length + 1);
5002            }
5003            /*FB: add file path size because of UTF 16 conversion*/
5004            pEditSavingSettings->pClipList[i]->filePathSize = length+1;
5005
5006            if( i
5007                < xVSS_context->pSettings->uiClipNumber
5008                - 1 ) /* Because there is 1 less transition than clip number */
5009            {
5010                memcpy(
5011                    (void *)pEditSavingSettings->pTransitionList[i],
5012                    (void *)xVSS_context->pSettings->
5013                    pTransitionList[i],
5014                    sizeof(M4VSS3GPP_TransitionSettings));
5015            }
5016        }
5017        else
5018        {
5019            M4OSA_TRACE1_0(
5020                "M4xVSS_SaveStart: Error when parsing xVSS_context->pSettings->pClipList[i]:\
5021                 Bad file type");
5022
5023            if( xVSS_context->pOutputFile != M4OSA_NULL )
5024            {
5025                free(xVSS_context->pOutputFile);
5026                xVSS_context->pOutputFile = M4OSA_NULL;
5027            }
5028            return M4ERR_PARAMETER;
5029        }
5030    }
5031
5032    /* Count the number of video effects, used to know how much memory is needed to allocate*/
5033    /* FB 2008/10/15: removed : not compatible with M4VSS3GPP_kVideoEffectType_None
5034    for(j=0;j<xVSS_context->pSettings->nbEffects;j++)
5035    {
5036    if(xVSS_context->pSettings->Effects[j].VideoEffectType != M4VSS3GPP_kVideoEffectType_None)
5037    {
5038    nbEffects++;
5039    }
5040    }*/
5041    nbEffects = xVSS_context->pSettings->nbEffects;
5042
5043    /* Allocate effects saving structure with correct number of effects */
5044    if( nbEffects != 0 )
5045    {
5046        pEditSavingSettings->Effects =
5047            (M4VSS3GPP_EffectSettings *)M4OSA_32bitAlignedMalloc(nbEffects
5048            * sizeof(M4VSS3GPP_EffectSettings), M4VS, (M4OSA_Char
5049            *)"Saving settings, effects table of structure settings");
5050
5051        if( pEditSavingSettings->Effects == M4OSA_NULL )
5052        {
5053            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
5054
5055            if( xVSS_context->pOutputFile != M4OSA_NULL )
5056            {
5057                free(xVSS_context->pOutputFile);
5058                xVSS_context->pOutputFile = M4OSA_NULL;
5059            }
5060            return M4ERR_ALLOC;
5061        }
5062
5063        /* Just copy effect structure to saving structure, as effects time are now */
5064        /* relative to output clip time*/
5065        memcpy((void *)pEditSavingSettings->Effects,
5066            (void *)xVSS_context->pSettings->Effects,
5067            nbEffects * sizeof(M4VSS3GPP_EffectSettings));
5068    }
5069    else
5070    {
5071        pEditSavingSettings->Effects = M4OSA_NULL;
5072        pEditSavingSettings->nbEffects = 0;
5073    }
5074    pEditSavingSettings->nbEffects = nbEffects;
5075
5076    if( pFilePath != M4OSA_NULL )
5077    {
5078        pEditSavingSettings->pOutputFile = pFilePath;
5079    }
5080
5081    /* Save pointer of saving video editor to use in step function */
5082    xVSS_context->pCurrentEditSettings = pEditSavingSettings;
5083
5084    /* Change output file name to temporary output file name, because final file will be
5085     generated by audio mixer */
5086    if( xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
5087    {
5088
5089        M4OSA_Char out_3gp[M4XVSS_MAX_PATH_LEN];
5090        M4OSA_Char out_3gp_tmp[M4XVSS_MAX_PATH_LEN];
5091
5092        /**/
5093        pEditSavingSettings->xVSS.pBGMtrack =
5094            (M4xVSS_BGMSettings *)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_BGMSettings), M4VS,
5095            (M4OSA_Char
5096            *)"Saving settings, effects table of structure settings");
5097
5098        if( pEditSavingSettings->xVSS.pBGMtrack == M4OSA_NULL )
5099        {
5100            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
5101
5102            if( xVSS_context->pOutputFile != M4OSA_NULL )
5103            {
5104                free(xVSS_context->pOutputFile);
5105                xVSS_context->pOutputFile = M4OSA_NULL;
5106            }
5107            return M4ERR_ALLOC;
5108        }
5109
5110        /* Just copy effect structure to saving structure, as effects time are now */
5111        /* relative to output clip time*/
5112        memcpy((void *)pEditSavingSettings->xVSS.pBGMtrack,
5113            (void *)xVSS_context->pSettings->xVSS.pBGMtrack,
5114            sizeof(M4xVSS_BGMSettings));
5115
5116        /* Allocate file name, and copy file name buffer to our structure */
5117        pEditSavingSettings->xVSS.pBGMtrack->pFile = M4OSA_32bitAlignedMalloc(
5118            (strlen(xVSS_context->pSettings->xVSS.pBGMtrack->pFile)
5119            + 1),
5120            M4VS, (M4OSA_Char *)"Saving struct xVSS BGM file path");
5121
5122        if( pEditSavingSettings->xVSS.pBGMtrack->pFile == M4OSA_NULL )
5123        {
5124            M4xVSS_freeCommand(xVSS_context);
5125            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
5126
5127            if( xVSS_context->pOutputFile != M4OSA_NULL )
5128            {
5129                free(xVSS_context->pOutputFile);
5130                xVSS_context->pOutputFile = M4OSA_NULL;
5131            }
5132            return M4ERR_ALLOC;
5133        }
5134        memcpy((void *)pEditSavingSettings->xVSS.pBGMtrack->pFile,
5135            (void *)xVSS_context->pSettings->xVSS.pBGMtrack->pFile,
5136            strlen(xVSS_context->pSettings->xVSS.pBGMtrack->pFile)
5137            + 1);
5138
5139        /*Copy BGM track file path*/
5140
5141        /**
5142        * UTF conversion*/
5143        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
5144            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
5145            != M4OSA_NULL )
5146        {
5147            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
5148                (M4OSA_Void *)pEditSavingSettings->xVSS.pBGMtrack->pFile,
5149                (M4OSA_Void *)xVSS_context->
5150                UTFConversionContext.pTempOutConversionBuffer, &length);
5151
5152            if( err != M4NO_ERROR )
5153            {
5154                M4OSA_TRACE1_1(
5155                    "M4xVSS_SaveStart: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
5156                    err);
5157
5158                if( xVSS_context->pOutputFile != M4OSA_NULL )
5159                {
5160                    free(xVSS_context->pOutputFile);
5161                    xVSS_context->pOutputFile = M4OSA_NULL;
5162                }
5163                return err;
5164            }
5165            pDecodedPath =
5166                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
5167
5168            free(pEditSavingSettings->xVSS.pBGMtrack->pFile);
5169            pEditSavingSettings->xVSS.pBGMtrack->pFile =
5170                (M4OSA_Void *)M4OSA_32bitAlignedMalloc(length + 1, M4VS, (M4OSA_Char
5171                *)"M4xVSS_SaveStart: Temp filename in case of BGM");
5172
5173            if( pEditSavingSettings->xVSS.pBGMtrack->pFile == M4OSA_NULL )
5174            {
5175                M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
5176
5177                if( xVSS_context->pOutputFile != M4OSA_NULL )
5178                {
5179                    free(xVSS_context->pOutputFile);
5180                    xVSS_context->pOutputFile = M4OSA_NULL;
5181                }
5182                return M4ERR_ALLOC;
5183            }
5184            memcpy((void *)pEditSavingSettings->xVSS.pBGMtrack->pFile,
5185                (void *)pDecodedPath, length + 1);
5186        }
5187
5188        /**/
5189
5190        M4OSA_chrNCopy(out_3gp, xVSS_context->pTempPath, M4XVSS_MAX_PATH_LEN - 1);
5191        M4OSA_chrNCopy(out_3gp_tmp, xVSS_context->pTempPath, M4XVSS_MAX_PATH_LEN - 1);
5192
5193        /* Construct output temporary 3GP filename */
5194        strncat((char *)out_3gp, (const char *)"savetemp.3gp\0", 13);
5195        strncat((char *)out_3gp_tmp, (const char *)"savetemp.tmp\0", 13);
5196
5197        /**
5198        * UTF conversion: convert into the customer format, before being used*/
5199        pDecodedPath = out_3gp;
5200        length = strlen(pDecodedPath);
5201
5202        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
5203            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
5204            != M4OSA_NULL )
5205        {
5206            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
5207                (M4OSA_Void *)out_3gp, (M4OSA_Void *)xVSS_context->
5208                UTFConversionContext.pTempOutConversionBuffer, &length);
5209
5210            if( err != M4NO_ERROR )
5211            {
5212                M4OSA_TRACE1_1(
5213                    "M4xVSS_SaveStart: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
5214                    err);
5215
5216                if( xVSS_context->pOutputFile != M4OSA_NULL )
5217                {
5218                    free(xVSS_context->pOutputFile);
5219                    xVSS_context->pOutputFile = M4OSA_NULL;
5220                }
5221                return err;
5222            }
5223            pDecodedPath =
5224                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
5225        }
5226
5227        /**
5228        * End of the UTF conversion, use the converted file path*/
5229        xVSS_context->pCurrentEditSettings->pOutputFile =
5230            (M4OSA_Void *)M4OSA_32bitAlignedMalloc(length + 1, M4VS,
5231            (M4OSA_Char *)"M4xVSS_SaveStart: Temp filename in case of BGM");
5232
5233        if( xVSS_context->pCurrentEditSettings->pOutputFile == M4OSA_NULL )
5234        {
5235            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
5236
5237            if( xVSS_context->pOutputFile != M4OSA_NULL )
5238            {
5239                free(xVSS_context->pOutputFile);
5240                xVSS_context->pOutputFile = M4OSA_NULL;
5241            }
5242            return M4ERR_ALLOC;
5243        }
5244        memcpy((void *)xVSS_context->pCurrentEditSettings->pOutputFile,
5245            (void *)pDecodedPath, length + 1);
5246        xVSS_context->pCurrentEditSettings->uiOutputPathSize = length + 1;
5247
5248        /**
5249        * UTF conversion: convert into the customer format, before being used*/
5250        pDecodedPath = out_3gp_tmp;
5251        length = strlen(pDecodedPath);
5252
5253        if( xVSS_context->UTFConversionContext.pConvFromUTF8Fct != M4OSA_NULL
5254            && xVSS_context->UTFConversionContext.pTempOutConversionBuffer
5255            != M4OSA_NULL )
5256        {
5257            err = M4xVSS_internalConvertFromUTF8(xVSS_context,
5258                (M4OSA_Void *)out_3gp_tmp, (M4OSA_Void *)xVSS_context->
5259                UTFConversionContext.pTempOutConversionBuffer, &length);
5260
5261            if( err != M4NO_ERROR )
5262            {
5263                M4OSA_TRACE1_1(
5264                    "M4xVSS_SaveStart: M4xVSS_internalConvertFromUTF8 returns err: 0x%x",
5265                    err);
5266
5267                if( xVSS_context->pOutputFile != M4OSA_NULL )
5268                {
5269                    free(xVSS_context->pOutputFile);
5270                    xVSS_context->pOutputFile = M4OSA_NULL;
5271                }
5272                return err;
5273            }
5274            pDecodedPath =
5275                xVSS_context->UTFConversionContext.pTempOutConversionBuffer;
5276        }
5277
5278        /**
5279        * End of the UTF conversion, use the converted file path*/
5280        xVSS_context->pCurrentEditSettings->pTemporaryFile =
5281            (M4OSA_Void *)M4OSA_32bitAlignedMalloc(length + 1, M4VS,
5282            (M4OSA_Char *)"M4xVSS_SaveStart: Temporary file");
5283
5284        if( xVSS_context->pCurrentEditSettings->pTemporaryFile == M4OSA_NULL )
5285        {
5286            M4OSA_TRACE1_0("Allocation error in M4xVSS_SaveStart");
5287
5288            if( xVSS_context->pOutputFile != M4OSA_NULL )
5289            {
5290                free(xVSS_context->pOutputFile);
5291                xVSS_context->pOutputFile = M4OSA_NULL;
5292            }
5293            return M4ERR_ALLOC;
5294        }
5295        memcpy((void *)xVSS_context->pCurrentEditSettings->pTemporaryFile,
5296            (void *)pDecodedPath, length + 1);
5297
5298        /* Put nb of step for progression monitoring to 2, because audio mixing is needed */
5299        xVSS_context->nbStepTotal = 2;
5300    }
5301    else
5302    {
5303        xVSS_context->pCurrentEditSettings->pOutputFile =
5304            xVSS_context->pOutputFile;
5305        xVSS_context->pCurrentEditSettings->pTemporaryFile = M4OSA_NULL;
5306
5307        /* Put nb of step for progression monitoring to 1, because no audio mixing is needed */
5308        xVSS_context->nbStepTotal = 1;
5309    }
5310
5311    /**
5312    ***/
5313
5314    err = M4xVSS_internalGenerateEditedFile(xVSS_context);
5315
5316    if( err != M4NO_ERROR )
5317    {
5318        M4OSA_TRACE1_1(
5319            "M4xVSS_SaveStart: M4xVSS_internalGenerateEditedFile returned an error: 0x%x",
5320            err);
5321
5322        /**/
5323        if( xVSS_context->pCurrentEditSettings->pOutputFile != M4OSA_NULL
5324            && xVSS_context->pSettings->xVSS.pBGMtrack == M4OSA_NULL )
5325        {
5326            free(xVSS_context->pCurrentEditSettings->
5327                pOutputFile);
5328            xVSS_context->pCurrentEditSettings->pOutputFile = M4OSA_NULL;
5329            xVSS_context->pOutputFile = M4OSA_NULL;
5330        }
5331
5332        if( xVSS_context->pCurrentEditSettings->pTemporaryFile != M4OSA_NULL
5333            && xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL )
5334        {
5335            free(xVSS_context->pCurrentEditSettings->
5336                pTemporaryFile);
5337            xVSS_context->pCurrentEditSettings->pTemporaryFile = M4OSA_NULL;
5338        }
5339
5340        if( xVSS_context->pOutputFile != M4OSA_NULL )
5341        {
5342            free(xVSS_context->pOutputFile);
5343            xVSS_context->pOutputFile = M4OSA_NULL;
5344        }
5345        /* TODO: Translate error code of VSS to an xVSS error code */
5346        return err;
5347    }
5348
5349    /* Reinitialize current step number for progression monitoring */
5350    xVSS_context->currentStep = 0;
5351
5352    /* Change xVSS state */
5353    xVSS_context->m_state = M4xVSS_kStateSaving;
5354
5355    return M4NO_ERROR;
5356}
5357
5358/**
5359 ******************************************************************************
5360 * prototype    M4OSA_ERR M4xVSS_SaveStop(M4OSA_Context pContext)
5361 * @brief        This function unallocate save ressources and change xVSS
5362 *                internal state.
5363 * @note        This function must be called once M4xVSS_Step has returned
5364 *                M4VSS3GPP_WAR_SAVING_DONE
5365 *
5366 * @param    pContext            (IN) Pointer on the xVSS edit context
5367 * @return    M4NO_ERROR:            No error
5368 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
5369 * @return    M4ERR_STATE:        This function cannot not be called at this time
5370 ******************************************************************************
5371 */
5372M4OSA_ERR M4xVSS_SaveStop( M4OSA_Context pContext )
5373{
5374    M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
5375    M4OSA_ERR err = M4NO_ERROR;
5376
5377    /* Check state */
5378    if( xVSS_context->m_state != M4xVSS_kStateSaving )
5379    {
5380        M4OSA_TRACE1_1(
5381            "Bad state when calling M4xVSS_SaveStop function! State is %d",
5382            xVSS_context->m_state);
5383        return M4ERR_STATE;
5384    }
5385
5386    /* Free saving structures */
5387    M4xVSS_internalFreeSaving(xVSS_context);
5388
5389    if( xVSS_context->pOutputFile != M4OSA_NULL )
5390    {
5391        free(xVSS_context->pOutputFile);
5392        xVSS_context->pOutputFile = M4OSA_NULL;
5393    }
5394
5395    /* Change xVSS state */
5396    xVSS_context->m_state = M4xVSS_kStateSaved;
5397
5398    return M4NO_ERROR;
5399}
5400
5401/**
5402 ******************************************************************************
5403 * prototype    M4OSA_ERR M4xVSS_Step(M4OSA_Context pContext, M4OSA_UInt8 *pProgress)
5404 * @brief        This function executes differents tasks, depending of xVSS
5405 *                internal state.
5406 * @note        This function:
5407 *                    - analyses editing structure if called after M4xVSS_SendCommand
5408 *                    - generates preview file if called after M4xVSS_PreviewStart
5409 *                    - generates final edited file if called after M4xVSS_SaveStart
5410 *
5411 * @param    pContext                        (IN) Pointer on the xVSS edit context
5412 * @param    pProgress                        (IN/OUT) Pointer on an integer giving a
5413 *                                            progress indication (between 0-100)
5414 * @return    M4NO_ERROR:                        No error, the user must call M4xVSS_Step again
5415 * @return    M4ERR_PARAMETER:                At least one parameter is M4OSA_NULL
5416 * @return    M4ERR_STATE:                    This function cannot not be called at this time
5417 * @return    M4VSS3GPP_WAR_PREVIEW_READY:    Preview file is generated
5418 * @return    M4VSS3GPP_WAR_SAVING_DONE:        Final edited file is generated
5419 * @return    M4VSS3GPP_WAR_ANALYZING_DONE:    Analyse is done
5420 ******************************************************************************
5421 */
5422M4OSA_ERR M4xVSS_Step( M4OSA_Context pContext, M4OSA_UInt8 *pProgress )
5423{
5424    M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
5425    M4VSS3GPP_EditContext pVssCtxt = xVSS_context->pCurrentEditContext;
5426    M4VSS3GPP_AudioMixingContext pAudioMixingCtxt =
5427        xVSS_context->pAudioMixContext;
5428    M4OSA_ERR err = M4NO_ERROR;
5429    M4OSA_UInt8 uiProgress = 0;
5430
5431    switch( xVSS_context->m_state )
5432    {
5433        case M4xVSS_kStateSaving:
5434        //case M4xVSS_kStateGeneratingPreview:
5435            {
5436                if( xVSS_context->editingStep
5437                    == M4xVSS_kMicroStateEditing ) /* VSS -> creating effects, transitions ... */
5438                {
5439                    /* RC: to delete unecessary temp files on the fly */
5440                    M4VSS3GPP_InternalEditContext *pVSSContext =
5441                        (M4VSS3GPP_InternalEditContext *)pVssCtxt;
5442
5443                    err = M4VSS3GPP_editStep(pVssCtxt, &uiProgress);
5444
5445                    if( ( err != M4NO_ERROR) && (err != M4VSS3GPP_WAR_EDITING_DONE)
5446                        && (err != M4VSS3GPP_WAR_SWITCH_CLIP) )
5447                    {
5448                        M4OSA_TRACE1_1(
5449                            "M4xVSS_Step: M4VSS3GPP_editStep returned 0x%x\n", err);
5450                        M4VSS3GPP_editCleanUp(pVssCtxt);
5451                        /* TODO ? : Translate error code of VSS to an xVSS error code ? */
5452                        xVSS_context->pCurrentEditContext = M4OSA_NULL;
5453                        return err;
5454                    }
5455
5456                    /* RC: to delete unecessary temp files on the fly */
5457                    if( err == M4VSS3GPP_WAR_SWITCH_CLIP )
5458                    {
5459#ifndef DO_NOT_REMOVE_TEMP_FILES
5460                        /* It means we can delete the temporary file */
5461                        /* First step, check the temp file is not use somewhere else after */
5462
5463                        M4OSA_UInt32 i;
5464                        M4OSA_Int32 cmpResult = -1;
5465
5466                        for ( i = pVSSContext->uiCurrentClip;
5467                            i < pVSSContext->uiClipNumber; i++ )
5468                        {
5469                            if( pVSSContext->pClipList[pVSSContext->uiCurrentClip
5470                                - 1].filePathSize
5471                                == pVSSContext->pClipList[i].filePathSize )
5472                            {
5473                                cmpResult = memcmp((void *)pVSSContext->
5474                                    pClipList[pVSSContext->uiCurrentClip
5475                                    - 1].pFile, (void *)pVSSContext->pClipList[i].pFile,
5476                                    pVSSContext->
5477                                    pClipList[pVSSContext->uiCurrentClip
5478                                    - 1].filePathSize);
5479
5480                                if( cmpResult == 0 )
5481                                {
5482                                    /* It means we found a corresponding file, we do not delete
5483                                    this temporary file */
5484                                    break;
5485                                }
5486                            }
5487                        }
5488
5489                        if( cmpResult != 0 )
5490                        {
5491                            M4OSA_UInt32 ConvertedSize = 0;
5492                            M4OSA_Char *toto;
5493                            M4OSA_Char *pTmpStr;
5494
5495                            /* Convert result in UTF8 to check if we can delete it or not */
5496                            if( xVSS_context->UTFConversionContext.pConvToUTF8Fct
5497                                != M4OSA_NULL && xVSS_context->
5498                                UTFConversionContext.
5499                                pTempOutConversionBuffer != M4OSA_NULL )
5500                            {
5501                                M4xVSS_internalConvertToUTF8(xVSS_context,
5502                                    (M4OSA_Void *)pVSSContext->
5503                                    pClipList[pVSSContext->uiCurrentClip
5504                                    - 1].pFile, (M4OSA_Void *)xVSS_context->
5505                                    UTFConversionContext.
5506                                    pTempOutConversionBuffer, &ConvertedSize);
5507                                toto = (M4OSA_Char *)strstr((const char *)xVSS_context->
5508                                    UTFConversionContext.
5509                                    pTempOutConversionBuffer,
5510                                    (const char *)xVSS_context->pTempPath);
5511                                pTmpStr =
5512                                    xVSS_context->UTFConversionContext.
5513                                    pTempOutConversionBuffer;
5514                            }
5515                            else
5516                            {
5517                                toto = (M4OSA_Char *)strstr((const char *)pVSSContext->
5518                                    pClipList[pVSSContext->uiCurrentClip
5519                                    - 1].pFile, (const char *)xVSS_context->pTempPath);
5520                                pTmpStr = pVSSContext->
5521                                    pClipList[pVSSContext->uiCurrentClip
5522                                    - 1].pFile;
5523                            }
5524
5525                            if( toto != M4OSA_NULL )
5526                            {
5527                                /* As temporary files can be imgXXX.3gp or vidXXX.3gp */
5528                                pTmpStr +=
5529                                    (strlen((const char *)pTmpStr)
5530                                    - 10); /* Because temporary files have a length at most of
5531                                    10 bytes */
5532                                toto = (M4OSA_Char *)strstr((const char *)pTmpStr,
5533                                    (const char *)"img");
5534
5535                                if( toto != M4OSA_NULL )
5536                                {
5537                                    toto = (M4OSA_Char *)strstr((const char *)pTmpStr,
5538                                        (const char *)"vid");
5539                                }
5540
5541                                if( err
5542                                    == M4NO_ERROR ) /* It means the file is a temporary file, we
5543                                    can delete it */
5544                                {
5545                                    remove((const char *)pVSSContext->
5546                                        pClipList[pVSSContext->uiCurrentClip
5547                                        - 1].pFile);
5548                                }
5549                            }
5550                        }
5551
5552#endif /* DO_NOT_REMOVE_TEMP_FILES*/
5553                        /* */
5554
5555                        err = M4NO_ERROR;
5556                    }
5557
5558                    if( err == M4VSS3GPP_WAR_EDITING_DONE )
5559                    {
5560                        xVSS_context->currentStep++;
5561                        /* P4ME00003276: When a step is complete, increment currentStep and reset
5562                        uiProgress unless progress would be wrong */
5563                        uiProgress = 0;
5564                        err = M4xVSS_internalCloseEditedFile(xVSS_context);
5565                        /* Fix for  blrnxpsw#234---> */
5566                        if( err != M4NO_ERROR )
5567                        {
5568                            if( err == ((M4OSA_UInt32)M4ERR_FILE_INVALID_POSITION) )
5569                            {
5570                                err = M4xVSSERR_NO_MORE_SPACE;
5571                            }
5572                            M4OSA_TRACE1_1(
5573                                "M4xVSS_internalCloseEditedFile returned an error: 0x%x",
5574                                err);
5575                            return err;
5576                        }
5577                        /*<---- Fix for  blrnxpsw#234 */
5578                        if( xVSS_context->pCurrentEditSettings->xVSS.pBGMtrack
5579                            != M4OSA_NULL )
5580                        {
5581                            xVSS_context->editingStep =
5582                                M4xVSS_kMicroStateAudioMixing;
5583                            /* Open Audio mixing component */
5584                            err = M4xVSS_internalGenerateAudioMixFile(xVSS_context);
5585
5586                            if( err != M4NO_ERROR )
5587                            {
5588                                M4OSA_TRACE1_1(
5589                                    "M4xVSS_internalGenerateAudioMixFile returned an error: 0x%x",
5590                                    err);
5591                                /* TODO ? : Translate error code of VSS to an xVSS error code */
5592                                return err;
5593                            }
5594                            err = M4NO_ERROR;
5595                            goto end_step;
5596                        }
5597                        else
5598                        {
5599
5600                            err = M4VSS3GPP_WAR_SAVING_DONE;
5601                            goto end_step;
5602
5603                        }
5604                    }
5605                }
5606                else if( xVSS_context->editingStep
5607                    == M4xVSS_kMicroStateAudioMixing ) /* Audio mixing: mix/replace audio track
5608                    with given BGM */
5609                {
5610                    err = M4VSS3GPP_audioMixingStep(pAudioMixingCtxt, &uiProgress);
5611
5612                    if( ( err != M4NO_ERROR)
5613                        && (err != M4VSS3GPP_WAR_END_OF_AUDIO_MIXING) )
5614                    {
5615                        M4OSA_TRACE1_1(
5616                            "M4VSS3GPP_audioMixingMain: M4VSS3GPP_audioMixingStep returned 0x%x\n",
5617                            err);
5618                        /* TODO ? : Translate error code of VSS to an xVSS error code */
5619                        return err;
5620                    }
5621
5622                    if( err == M4VSS3GPP_WAR_END_OF_AUDIO_MIXING )
5623                    {
5624                        xVSS_context->currentStep++;
5625                        /* P4ME00003276: When a step is complete, increment currentStep and reset
5626                        uiProgress unless progress would be wrong */
5627                        uiProgress = 0;
5628                        err = M4xVSS_internalCloseAudioMixedFile(xVSS_context);
5629
5630                        if( err != M4NO_ERROR )
5631                        {
5632                            M4OSA_TRACE1_1(
5633                                "M4xVSS_internalCloseAudioMixedFile returned an error: 0x%x",
5634                                err);
5635                            /* TODO ? : Translate error code of VSS to an xVSS error code */
5636                            return err;
5637                        }
5638
5639                            err = M4VSS3GPP_WAR_SAVING_DONE;
5640                            goto end_step;
5641
5642                    }
5643                }
5644                else
5645                {
5646                    M4OSA_TRACE1_0("Bad state in step function !");
5647                    return M4ERR_STATE;
5648                }
5649            }
5650            break;
5651
5652        case M4xVSS_kStateAnalyzing:
5653            {
5654                if( xVSS_context->analyseStep
5655                    == M4xVSS_kMicroStateAnalysePto3GPP ) /* Pto3GPP, analysing input parameters */
5656                {
5657                    if( xVSS_context->pPTo3GPPcurrentParams == M4OSA_NULL
5658                        && xVSS_context->pPTo3GPPparamsList != M4OSA_NULL )
5659                    {
5660                        xVSS_context->pPTo3GPPcurrentParams =
5661                            xVSS_context->
5662                            pPTo3GPPparamsList; /* Current Pto3GPP Parameter is the first element
5663                            of the list */
5664                    }
5665                    else if( xVSS_context->pPTo3GPPcurrentParams != M4OSA_NULL
5666                        && xVSS_context->pPTo3GPPparamsList != M4OSA_NULL )
5667                    {
5668                        xVSS_context->pPTo3GPPcurrentParams =
5669                            xVSS_context->pPTo3GPPcurrentParams->
5670                            pNext; /* Current Pto3GPP Parameter is the next element of the list */
5671
5672                        if( xVSS_context->pPTo3GPPcurrentParams
5673                            == M4OSA_NULL ) /* It means there is no next image to convert */
5674                        {
5675                            /* We step to MCS phase */
5676                            xVSS_context->analyseStep =
5677                                M4xVSS_kMicroStateAnalyzeMCS;
5678                            err = M4NO_ERROR;
5679                            goto end_step;
5680                        }
5681                    }
5682                    else if( xVSS_context->pPTo3GPPparamsList == M4OSA_NULL )
5683                    {
5684                        xVSS_context->analyseStep =
5685                            M4xVSS_kMicroStateAnalyzeMCS; /* Change Analyzing micro state to
5686                             MCS phase */
5687                        err = M4NO_ERROR;
5688                        goto end_step;
5689                    }
5690
5691                    /* Check if this file has to be converted or not */
5692                    /* If not, we just return M4NO_ERROR, and go to next file */
5693                    if( xVSS_context->pPTo3GPPcurrentParams->isCreated
5694                        == M4OSA_FALSE )
5695                    {
5696                        /* Opening Pto3GPP */
5697                        err = M4xVSS_internalStartConvertPictureTo3gp(xVSS_context);
5698
5699                        if( err != M4NO_ERROR )
5700                        {
5701                            M4OSA_TRACE1_1("M4xVSS_Step: M4xVSS_internalStartConvertPictureTo3gp \
5702                            returned error: 0x%x",
5703                                err)
5704                                /* TODO ? : Translate error code of VSS to an xVSS error code */
5705                                return err;
5706                        }
5707                        xVSS_context->analyseStep =
5708                            M4xVSS_kMicroStateConvertPto3GPP;
5709                    }
5710                }
5711                else if( xVSS_context->analyseStep
5712                    == M4xVSS_kMicroStateConvertPto3GPP ) /* Pto3GPP, converting */
5713                {
5714                    err = M4PTO3GPP_Step(xVSS_context->pM4PTO3GPP_Ctxt);
5715                    /* update progress bar */
5716                    if(xVSS_context->pCallBackCtxt->m_NbImage > 1)
5717                    {
5718                        uiProgress = (xVSS_context->pCallBackCtxt->m_ImageCounter * 100) / (xVSS_context->pCallBackCtxt->m_NbImage -1);
5719                    }
5720
5721                    if( ( err != M4NO_ERROR) && (err
5722                        != ((M4OSA_UInt32)M4PTO3GPP_WAR_END_OF_PROCESSING)) )
5723                    {
5724                        /* TO BE CHECKED NO LEAKS  !!!!! */
5725                        M4OSA_TRACE1_1(
5726                            "M4xVSS_Step: M4PTO3GPP_Step returned 0x%x\n", err);
5727                        /* TODO ? : Translate error code of VSS to an xVSS error code */
5728                        return err;
5729                    }
5730                    else if( err
5731                        == ((M4OSA_UInt32)M4PTO3GPP_WAR_END_OF_PROCESSING) )
5732                    {
5733                        xVSS_context->currentStep++;
5734                        /* P4ME00003276: When a step is complete, increment currentStep and reset
5735                         uiProgress unless progress would be wrong */
5736                        uiProgress = 0;
5737                        xVSS_context->analyseStep =
5738                            M4xVSS_kMicroStateAnalysePto3GPP; /* We go back to analyze parameters
5739                            to see if there is a next file to convert */
5740                        /* RC !!!!!!!! */
5741                        xVSS_context->pPTo3GPPcurrentParams->isCreated =
5742                            M4OSA_TRUE; /* To avoid reconverting it if another SendCommand is
5743                            called */
5744                        err = M4xVSS_internalStopConvertPictureTo3gp(xVSS_context);
5745                        /*SS:blrnxpsw#  234 */
5746                        if( err == ((M4OSA_UInt32)M4ERR_FILE_INVALID_POSITION) )
5747                        {
5748                            err = M4xVSSERR_NO_MORE_SPACE;
5749                        }
5750
5751                        if( err != M4NO_ERROR )
5752                        {
5753                            M4OSA_TRACE1_1("M4xVSS_Step:\
5754                                           M4xVSS_internalStopConvertPictureTo3gp returned 0x%x",
5755                                            err);
5756                            /* TODO ? : Translate error code of VSS to an xVSS error code */
5757                            return err;
5758                        }
5759                    }
5760                }
5761                else if( xVSS_context->analyseStep
5762                    ==
5763                    M4xVSS_kMicroStateAnalyzeMCS ) /* MCS: analyzing input parameters */
5764                {
5765                    if( xVSS_context->pMCScurrentParams == M4OSA_NULL \
5766                        && xVSS_context->pMCSparamsList != M4OSA_NULL )
5767                    {
5768                        xVSS_context->pMCScurrentParams = xVSS_context->
5769                            pMCSparamsList; /* Current MCS Parameter is the first
5770                                            element of the list */
5771                    }
5772                    else if( xVSS_context->pMCScurrentParams != M4OSA_NULL \
5773                        && xVSS_context->pMCSparamsList != M4OSA_NULL )
5774                    {
5775                        xVSS_context->pMCScurrentParams =
5776                            xVSS_context->pMCScurrentParams->
5777                            pNext; /* Current MCS Parameter
5778                                   is the next element of the list */
5779
5780                        if( xVSS_context->pMCScurrentParams == M4OSA_NULL )
5781                            /* It means there is no next image to convert */
5782                        {
5783                            xVSS_context->analyseStep =
5784                                M4xVSS_kMicroStateAnalysePto3GPP; /* Reinit Analyzing micro state */
5785                            xVSS_context->m_state =
5786                                M4xVSS_kStateOpened; /* Change xVSS state */
5787                            err = M4VSS3GPP_WAR_ANALYZING_DONE;
5788                            goto end_step; /* End of Analysis */
5789                        }
5790                    }
5791                    else if( xVSS_context->pMCSparamsList == M4OSA_NULL )
5792                    {
5793                        xVSS_context->analyseStep =
5794                            M4xVSS_kMicroStateAnalysePto3GPP; /* Reinit Analyzing micro state */
5795                        xVSS_context->m_state =
5796                            M4xVSS_kStateOpened; /* Change xVSS state */
5797                        err = M4VSS3GPP_WAR_ANALYZING_DONE;
5798                        goto end_step;                        /* End of Analysis */
5799                    }
5800
5801                    /* Check if this file has to be transcoded or not */
5802                    /* If not, we just return M4NO_ERROR, and go to next file */
5803                    if( xVSS_context->pMCScurrentParams->isCreated == M4OSA_FALSE )
5804                    {
5805                        /* Opening MCS */
5806                        M4OSA_UInt32 rotationDegree = 0;
5807                        err = M4xVSS_internalStartTranscoding(xVSS_context, &rotationDegree);
5808
5809                        if( err != M4NO_ERROR )
5810                        {
5811                            M4OSA_TRACE1_1("M4xVSS_Step: M4xVSS_internalStartTranscoding returned\
5812                                 error: 0x%x", err);
5813                            return err;
5814                        }
5815                        int32_t index = xVSS_context->pMCScurrentParams->videoclipnumber;
5816
5817                        /* The cuts are done in the MCS, so we need to replace
5818                           the beginCutTime and endCutTime to keep the entire video*/
5819                        xVSS_context->pSettings->pClipList[index]->uiBeginCutTime = 0;
5820                        xVSS_context->pSettings->pClipList[index]->uiEndCutTime = 0;
5821
5822
5823                        M4OSA_TRACE1_1("M4xVSS_Step: \
5824                            M4xVSS_internalStartTranscoding returned \
5825                                success; MCS context: 0x%x",
5826                                 xVSS_context->pMCS_Ctxt);
5827                        xVSS_context->analyseStep =
5828                            M4xVSS_kMicroStateTranscodeMCS;
5829
5830                        // Retain rotation info of trimmed / transcoded file
5831                        xVSS_context->pSettings->pClipList[index]->\
5832                            ClipProperties.videoRotationDegrees = rotationDegree;
5833                    }
5834                }
5835                else if( xVSS_context->analyseStep
5836                    == M4xVSS_kMicroStateTranscodeMCS )
5837                    /* MCS: transcoding file */
5838                {
5839                    err = M4MCS_step(xVSS_context->pMCS_Ctxt, &uiProgress);
5840                    /*SS:blrnxpsw#  234 */
5841                    if( err == ((M4OSA_UInt32)M4MCS_ERR_NOMORE_SPACE) )
5842                    {
5843                        err = M4xVSSERR_NO_MORE_SPACE;
5844                    }
5845
5846                    if( ( err != M4NO_ERROR)
5847                        && (err != M4MCS_WAR_TRANSCODING_DONE) )
5848                    {
5849                        /* TO BE CHECKED NO LEAKS  !!!!! */
5850                        M4OSA_TRACE1_1("M4xVSS_Step: M4MCS_step returned 0x%x\n",
5851                            err);
5852                        /* TODO ? : Translate error code of MCS to an xVSS error code ? */
5853                        return err;
5854                    }
5855                    else if( err == M4MCS_WAR_TRANSCODING_DONE )
5856                    {
5857                        xVSS_context->currentStep++;
5858                        /* P4ME00003276: When a step is complete, increment currentStep and reset
5859                        uiProgress unless progress would be wrong */
5860                        uiProgress = 0;
5861                        xVSS_context->analyseStep =
5862                            M4xVSS_kMicroStateAnalyzeMCS; /* We go back to
5863                                                          analyze parameters to see if there is
5864                                                           a next file to transcode */
5865                        /* RC !!!!!!!!!*/
5866                        xVSS_context->pMCScurrentParams->isCreated =
5867                            M4OSA_TRUE; /* To avoid
5868                                        reconverting it if another SendCommand is called */
5869                        err = M4xVSS_internalStopTranscoding(xVSS_context);
5870
5871                        if( err != M4NO_ERROR )
5872                        {
5873                            M4OSA_TRACE1_1("M4xVSS_Step:\
5874                                           M4xVSS_internalStopTranscoding returned 0x%x", err);
5875                            /* TODO ? : Translate error code of MCS to an xVSS error code ? */
5876                            return err;
5877                        }
5878                    }
5879                }
5880                else
5881                {
5882                    M4OSA_TRACE1_0("Bad micro state in analyzing state")
5883                        return M4ERR_STATE;
5884                }
5885            }
5886            break;
5887
5888        default:
5889            M4OSA_TRACE1_1(
5890                "Bad state when calling M4xVSS_Step function! State is %d",
5891                xVSS_context->m_state);
5892            return M4ERR_STATE;
5893    }
5894
5895end_step:
5896    /* Compute progression */
5897    if( xVSS_context->nbStepTotal != 0 )
5898    {
5899        *pProgress = (M4OSA_UInt8)(( ( xVSS_context->currentStep * 100) \
5900            / (xVSS_context->nbStepTotal))
5901            + (uiProgress / (xVSS_context->nbStepTotal)));
5902
5903        if( *pProgress > 100 )
5904        {
5905            *pProgress = 100;
5906        }
5907    }
5908    else
5909    {
5910        *pProgress = 100;
5911    }
5912
5913    return err;
5914}
5915
5916/**
5917 ******************************************************************************
5918 * prototype    M4OSA_ERR M4xVSS_CloseCommand(M4OSA_Context pContext)
5919 * @brief        This function deletes current editing profile, unallocate
5920 *                ressources and change xVSS internal state.
5921 * @note        After this function, the user can call a new M4xVSS_SendCommand
5922 *
5923 * @param    pContext            (IN) Pointer on the xVSS edit context
5924 * @return    M4NO_ERROR:            No error
5925 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
5926 * @return    M4ERR_STATE:        This function cannot not be called at this time
5927 ******************************************************************************
5928 */
5929M4OSA_ERR M4xVSS_CloseCommand( M4OSA_Context pContext )
5930{
5931    M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
5932    M4OSA_ERR err = M4NO_ERROR;
5933
5934    /* Check state */
5935    /* Depending of the state, differents things have to be done */
5936    switch( xVSS_context->m_state )
5937    {
5938        case M4xVSS_kStateOpened:
5939            /* Nothing to do here */
5940            err = M4xVSS_internalFreeSaving(xVSS_context);
5941            break;
5942
5943        case M4xVSS_kStateSaving:
5944            {
5945                if( xVSS_context->editingStep == M4xVSS_kMicroStateEditing )
5946                {
5947                    err = M4xVSS_internalCloseEditedFile(xVSS_context);
5948
5949                    if( err != M4NO_ERROR )
5950                    {
5951                        /* Fix for blrnxpsw#234---->*/
5952                        if( err == ((M4OSA_UInt32)M4ERR_FILE_INVALID_POSITION) )
5953                        {
5954                            err = M4xVSSERR_NO_MORE_SPACE;
5955                        }
5956                        M4OSA_TRACE1_1("M4xVSS_CloseCommand:\
5957                                       M4xVSS_internalCloseEditedFile returned an error: 0x%x",
5958                                        err);
5959                        /* we are retaining error here and returning error  in the end of the
5960                        function  as to aviod memory leak*/
5961                        //return err;
5962                    }
5963                }
5964                else if( xVSS_context->editingStep
5965                    == M4xVSS_kMicroStateAudioMixing )
5966                {
5967                    err = M4xVSS_internalCloseAudioMixedFile(xVSS_context);
5968
5969                    if( err != M4NO_ERROR )
5970                    {
5971                        /* Fix for blrnxpsw#234---->*/
5972                        if( err == ((M4OSA_UInt32)M4ERR_FILE_INVALID_POSITION) )
5973                        {
5974                            err = M4xVSSERR_NO_MORE_SPACE;
5975                        }
5976                        M4OSA_TRACE1_1("M4xVSS_CloseCommand: \
5977                                M4xVSS_internalCloseAudioMixedFile returned an error: 0x%x", err);
5978                        /* we are retaining error here and returning error  in the end of
5979                        the function  as to aviod memory leak*/
5980                        //return err;
5981                        /* <----Fix for blrnxpsw#234*/
5982                    }
5983                }
5984                err = M4xVSS_internalFreeSaving(xVSS_context);
5985                /* We free this pointer only if a BGM track is present, because in that case,
5986                this pointer owns to us */
5987                if( xVSS_context->pSettings->xVSS.pBGMtrack != M4OSA_NULL ) {
5988                    /*if(M4OSA_NULL != xVSS_context->pSettings->pOutputFile)
5989                    {
5990                    free(xVSS_context->pSettings->pOutputFile);
5991                    xVSS_context->pSettings->pOutputFile = M4OSA_NULL;
5992                    }*/
5993                    /*if(M4OSA_NULL != xVSS_context->pSettings->pTemporaryFile)
5994                    {
5995                    free(xVSS_context->pSettings->pTemporaryFile);
5996                    xVSS_context->pSettings->pTemporaryFile = M4OSA_NULL;
5997                    }*/
5998                }
5999            }
6000            break;
6001
6002        case M4xVSS_kStateSaved:
6003            break;
6004
6005        case M4xVSS_kStateAnalyzing:
6006            {
6007                if( xVSS_context->analyseStep == M4xVSS_kMicroStateConvertPto3GPP )
6008                {
6009                    /* Free Pto3GPP module */
6010                    err = M4xVSS_internalStopConvertPictureTo3gp(xVSS_context);
6011                    /* Fix for blrnxpsw#234---->*/
6012                    if( err != M4NO_ERROR )
6013                    {
6014                        if( err == ((M4OSA_UInt32)M4ERR_FILE_INVALID_POSITION) )
6015                        {
6016                            err = M4xVSSERR_NO_MORE_SPACE;
6017                        }
6018                        M4OSA_TRACE1_1("M4xVSS_Step: \
6019                                       M4xVSS_internalStopConvertPictureTo3gp returned 0x%x", err);
6020                        /* we are retaining error here and returning error  in the end of the
6021                        function  as to aviod memory leak*/
6022                        //return err;
6023                    }
6024                    /* <-----Fix for blrnxpsw#234>*/
6025                }
6026                else if( xVSS_context->analyseStep
6027                    == M4xVSS_kMicroStateTranscodeMCS )
6028                {
6029                    /* Free MCS module */
6030                    err = M4MCS_abort(xVSS_context->pMCS_Ctxt);
6031                    /* Fix for blrnxpsw#234---->*/
6032                    if( err != M4NO_ERROR )
6033                    {
6034                        if( err == ((M4OSA_UInt32)M4ERR_FILE_INVALID_POSITION) )
6035                        {
6036                            err = M4xVSSERR_NO_MORE_SPACE;
6037                        }
6038                        M4OSA_TRACE1_1("M4xVSS_Step: M4MCS_abort returned 0x%x",
6039                            err);
6040                        /* we are retaining error here and returning error  in the end of the
6041                        function  as to aviod memory leak*/
6042                        //return err;
6043                    }
6044                    /* <---Fix for blrnxpsw#234*/
6045                }
6046            }
6047            break;
6048
6049        default:
6050            M4OSA_TRACE1_1(
6051                "Bad state when calling M4xVSS_CloseCommand function! State is %d",
6052                xVSS_context->m_state);
6053            return M4ERR_STATE;
6054    }
6055
6056    /* Free Send command */
6057    M4xVSS_freeCommand(xVSS_context);
6058
6059    xVSS_context->m_state = M4xVSS_kStateInitialized; /* Change xVSS state */
6060
6061    return err;
6062}
6063
6064/**
6065 ******************************************************************************
6066 * prototype    M4OSA_ERR M4xVSS_CleanUp(M4OSA_Context pContext)
6067 * @brief        This function deletes all xVSS ressources
6068 * @note        This function must be called after M4xVSS_CloseCommand.
6069 *
6070 * @param    pContext            (IN) Pointer on the xVSS edit context
6071 * @return    M4NO_ERROR:            No error
6072 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
6073 * @return    M4ERR_STATE:        This function cannot not be called at this time
6074 ******************************************************************************
6075 */
6076M4OSA_ERR M4xVSS_CleanUp( M4OSA_Context pContext )
6077{
6078    M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
6079    M4OSA_TRACE3_0("M4xVSS_CleanUp:entering");
6080
6081    /* Check state */
6082    if( xVSS_context->m_state != M4xVSS_kStateInitialized )
6083    {
6084        M4OSA_TRACE1_1(\
6085            "Bad state when calling M4xVSS_CleanUp function! State is %d",\
6086            xVSS_context->m_state);
6087        return M4ERR_STATE;
6088    }
6089
6090    /**
6091    * UTF conversion: free temporary buffer*/
6092    if( xVSS_context->UTFConversionContext.pTempOutConversionBuffer
6093        != M4OSA_NULL )
6094    {
6095        free(xVSS_context->
6096            UTFConversionContext.pTempOutConversionBuffer);
6097        xVSS_context->UTFConversionContext.pTempOutConversionBuffer =
6098            M4OSA_NULL;
6099    }
6100
6101    free(xVSS_context->pTempPath);
6102    xVSS_context->pTempPath = M4OSA_NULL;
6103
6104    free(xVSS_context->pSettings);
6105    xVSS_context->pSettings = M4OSA_NULL;
6106
6107    free(xVSS_context);
6108    xVSS_context = M4OSA_NULL;
6109    M4OSA_TRACE3_0("M4xVSS_CleanUp:leaving ");
6110
6111    return M4NO_ERROR;
6112}
6113
6114/**
6115 ******************************************************************************
6116 * prototype    M4xVSS_GetVersion(M4_VersionInfo *pVersion)
6117 * @brief        This function get the version of the Video Studio 2.1
6118 *
6119 * @param    pVersion            (IN) Pointer on the version info struct
6120 * @return    M4NO_ERROR:            No error
6121 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
6122 ******************************************************************************
6123 */
6124M4OSA_ERR M4xVSS_GetVersion( M4_VersionInfo *pVersion )
6125{
6126    /* Just used for a grep in code */
6127    /* CHANGE_VERSION_HERE */
6128    static const M4OSA_Char cVersion[26] = "NXPSW_VideoStudio21_1_3_0";
6129
6130    if( M4OSA_NULL == pVersion )
6131    {
6132        return M4ERR_PARAMETER;
6133    }
6134
6135    pVersion->m_major = M4_xVSS_MAJOR;
6136    pVersion->m_minor = M4_xVSS_MINOR;
6137    pVersion->m_revision = M4_xVSS_REVISION;
6138    pVersion->m_structSize = sizeof(M4_VersionInfo);
6139
6140    return M4NO_ERROR;
6141}
6142
6143/**
6144 ******************************************************************************
6145 * M4OSA_ERR M4xVSS_CreateClipSettings()
6146 * @brief    Allows filling a clip settings structure with default values
6147 *
6148 * @note    WARNING: pClipSettings->Effects[ ] will be allocated in this function.
6149 *                   pClipSettings->pFile      will be allocated in this function.
6150 *
6151 * @param    pClipSettings        (IN) Pointer to a valid M4VSS3GPP_ClipSettings structure
6152 * @param   pFile               (IN) Clip file name
6153 * @param   filePathSize        (IN) Size of the clip path (needed for the UTF16 conversion)
6154 * @param    nbEffects           (IN) Nb of effect settings to allocate
6155 * @return    M4NO_ERROR:            No error
6156 * @return    M4ERR_PARAMETER:    pClipSettings is M4OSA_NULL (debug only)
6157 ******************************************************************************
6158 */
6159M4OSA_ERR M4xVSS_CreateClipSettings( M4VSS3GPP_ClipSettings *pClipSettings,
6160                                    M4OSA_Void *pFile, M4OSA_UInt32 filePathSize,
6161                                     M4OSA_UInt8 nbEffects )
6162{
6163    M4OSA_ERR err = M4NO_ERROR;
6164
6165    M4OSA_TRACE3_1("M4xVSS_CreateClipSettings called with pClipSettings=0x%p",
6166        pClipSettings);
6167
6168    /**
6169    *    Check input parameter */
6170    M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettings), M4ERR_PARAMETER,
6171        "M4xVSS_CreateClipSettings: pClipSettings is NULL");
6172
6173    /* Create inherited VSS3GPP stuff */
6174    /*err = M4VSS3GPP_editCreateClipSettings(pClipSettings, pFile,nbEffects);*/
6175    /*FB: add clip path size (needed for UTF 16 conversion)*/
6176    err = M4VSS3GPP_editCreateClipSettings(pClipSettings, pFile, filePathSize,
6177        nbEffects);
6178
6179    if( M4NO_ERROR != err )
6180    {
6181        M4OSA_TRACE1_1("M4xVSS_CreateClipSettings :\
6182                       ERROR in M4VSS3GPP_editCreateClipSettings = 0x%x", err);
6183        return err;
6184    }
6185
6186    /* Set the clip settings to default */
6187    pClipSettings->xVSS.uiBeginCutPercent = 0;
6188    pClipSettings->xVSS.uiEndCutPercent = 0;
6189    pClipSettings->xVSS.uiDuration = 0;
6190    pClipSettings->xVSS.isPanZoom = M4OSA_FALSE;
6191    pClipSettings->xVSS.PanZoomTopleftXa = 0;
6192    pClipSettings->xVSS.PanZoomTopleftYa = 0;
6193    pClipSettings->xVSS.PanZoomTopleftXb = 0;
6194    pClipSettings->xVSS.PanZoomTopleftYb = 0;
6195    pClipSettings->xVSS.PanZoomXa = 0;
6196    pClipSettings->xVSS.PanZoomXb = 0;
6197
6198    /**
6199    * Return with no error */
6200    M4OSA_TRACE3_0("M4xVSS_CreateClipSettings(): returning M4NO_ERROR");
6201
6202    return M4NO_ERROR;
6203}
6204
6205/**
6206 ******************************************************************************
6207 * M4OSA_ERR M4xVSS_DuplicateClipSettings()
6208 * @brief    Duplicates a clip settings structure, performing allocations if required
6209 *
6210 * @param    pClipSettingsDest    (IN) Pointer to a valid M4VSS3GPP_ClipSettings structure
6211 * @param    pClipSettingsOrig    (IN) Pointer to a valid M4VSS3GPP_ClipSettings structure
6212 * @param   bCopyEffects        (IN) Flag to know if we have to duplicate effects
6213 * @return    M4NO_ERROR:            No error
6214 * @return    M4ERR_PARAMETER:    pClipSettings is M4OSA_NULL (debug only)
6215 ******************************************************************************
6216 */
6217M4OSA_ERR M4xVSS_DuplicateClipSettings( M4VSS3GPP_ClipSettings
6218                                       *pClipSettingsDest,
6219                                       M4VSS3GPP_ClipSettings *pClipSettingsOrig,
6220                                        M4OSA_Bool bCopyEffects )
6221{
6222    M4OSA_ERR err = M4NO_ERROR;
6223
6224    M4OSA_TRACE3_2(
6225        "M4xVSS_DuplicateClipSettings called with dest=0x%p src=0x%p",
6226        pClipSettingsDest, pClipSettingsOrig);
6227
6228    /* Check input parameter */
6229    M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettingsDest), M4ERR_PARAMETER,
6230        "M4xVSS_DuplicateClipSettings: pClipSettingsDest is NULL");
6231    M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettingsOrig), M4ERR_PARAMETER,
6232        "M4xVSS_DuplicateClipSettings: pClipSettingsOrig is NULL");
6233
6234    /* Call inherited VSS3GPP duplication */
6235    err = M4VSS3GPP_editDuplicateClipSettings(pClipSettingsDest,
6236        pClipSettingsOrig, bCopyEffects);
6237
6238    if( M4NO_ERROR != err )
6239    {
6240        M4OSA_TRACE1_1("M4xVSS_CreateClipSettings :\
6241                       ERROR in M4VSS3GPP_editDuplicateClipSettings = 0x%x", err);
6242        return err;
6243    }
6244
6245    /* Return with no error */
6246    M4OSA_TRACE3_0("M4xVSS_DuplicateClipSettings(): returning M4NO_ERROR");
6247
6248    return M4NO_ERROR;
6249}
6250
6251/**
6252 ******************************************************************************
6253 * M4OSA_ERR M4xVSS_FreeClipSettings()
6254 * @brief    Free the pointers allocated in the ClipSetting structure (pFile, Effects, ...).
6255 *
6256 * @param    pClipSettings        (IN) Pointer to a valid M4VSS3GPP_ClipSettings structure
6257 * @return    M4NO_ERROR:            No error
6258 * @return    M4ERR_PARAMETER:    pClipSettings is M4OSA_NULL (debug only)
6259 ******************************************************************************
6260 */
6261M4OSA_ERR M4xVSS_FreeClipSettings( M4VSS3GPP_ClipSettings *pClipSettings )
6262{
6263    /**
6264    *    Check input parameter */
6265    M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettings), M4ERR_PARAMETER,
6266        "M4xVSS_FreeClipSettings: pClipSettings is NULL");
6267
6268    /* Free inherited VSS3GPP stuff */
6269    M4VSS3GPP_editFreeClipSettings(pClipSettings);
6270
6271    return M4NO_ERROR;
6272}
6273
6274/**
6275 ******************************************************************************
6276 * prototype    M4OSA_ERR M4xVSS_getMCSContext(M4OSA_Context pContext, M4OSA_Context* mcsContext)
6277 * @brief        This function returns the MCS context within the xVSS internal context
6278 * @note        This function must be called only after VSS state has moved to analyzing state or
6279 * beyond
6280 *
6281 * @param    pContext            (IN) Pointer on the xVSS edit context
6282 * @param    mcsContext        (OUT) Pointer to pointer of mcs context to return
6283 * @return    M4NO_ERROR:        No error
6284 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
6285 * @return    M4ERR_STATE:        This function cannot not be called at this time
6286 ******************************************************************************
6287 */
6288M4OSA_ERR M4xVSS_getMCSContext( M4OSA_Context pContext,
6289                               M4OSA_Context *mcsContext )
6290{
6291    M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
6292    M4OSA_ERR err = M4NO_ERROR;
6293
6294    /**
6295    *    Check input parameter */
6296    M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
6297        "M4xVSS_getMCSContext: pContext is NULL");
6298
6299    if( xVSS_context->m_state == M4xVSS_kStateInitialized )
6300    {
6301        M4OSA_TRACE1_1("M4xVSS_getMCSContext: Bad state! State is %d",\
6302            xVSS_context->m_state);
6303        return M4ERR_STATE;
6304    }
6305
6306    *mcsContext = xVSS_context->pMCS_Ctxt;
6307
6308    return err;
6309}
6310
6311/**
6312 ******************************************************************************
6313 * prototype    M4OSA_ERR M4xVSS_getVSS3GPPContext(M4OSA_Context pContext,
6314 *                                                   M4OSA_Context* mcsContext)
6315 * @brief        This function returns the VSS3GPP context within the xVSS internal context
6316 * @note        This function must be called only after VSS state has moved to Generating preview
6317 *              or beyond
6318 * @param    pContext            (IN) Pointer on the xVSS edit context
6319 * @param    vss3gppContext        (OUT) Pointer to pointer of vss3gpp context to return
6320 * @return    M4NO_ERROR:        No error
6321 * @return    M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
6322 * @return    M4ERR_STATE:        This function cannot not be called at this time
6323 ******************************************************************************
6324 */
6325M4OSA_ERR M4xVSS_getVSS3GPPContext( M4OSA_Context pContext,
6326                                   M4OSA_Context *vss3gppContext )
6327{
6328    M4xVSS_Context *xVSS_context = (M4xVSS_Context *)pContext;
6329    M4OSA_ERR err = M4NO_ERROR;
6330
6331    /**
6332    *    Check input parameter */
6333    M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
6334        "M4xVSS_getVSS3GPPContext: pContext is NULL");
6335
6336    if( xVSS_context->m_state < M4xVSS_kStateSaving )
6337    {
6338        M4OSA_TRACE1_1("M4xVSS_getVSS3GPPContext: Bad state! State is %d",\
6339            xVSS_context->m_state);
6340        return M4ERR_STATE;
6341    }
6342
6343    *vss3gppContext = xVSS_context->pCurrentEditContext;
6344
6345    return err;
6346}
6347
6348M4OSA_ERR M4xVSS_getVideoDecoderCapabilities(M4DECODER_VideoDecoders **decoders) {
6349    M4OSA_ERR err = M4NO_ERROR;
6350
6351    // Call the decoder api directly
6352    // to get all the video decoder capablities.
6353    err = VideoEditorVideoDecoder_getVideoDecodersAndCapabilities(decoders);
6354    return err;
6355}
6356