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