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