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