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