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