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