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