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