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