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