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