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