• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  *************************************************************************
19  * @file   M4MCS_API.c
20  * @brief  MCS implementation (Video Compressor Service)
21  * @note   This file implements the API and the processing of the MCS
22  *************************************************************************
23  **/
24 
25 /**
26  ********************************************************************
27  * Includes
28  ********************************************************************
29  */
30 /**
31  * OSAL headers */
32 #include "M4OSA_Memory.h" /**< OSAL memory management */
33 #include "M4OSA_Debug.h"  /**< OSAL debug management */
34 
35 /* PCM samples */
36 #include "VideoEditorResampler.h"
37 /**
38  * Decoder interface */
39 #include "M4DECODER_Common.h"
40 
41 /* Encoder interface*/
42 #include "M4ENCODER_common.h"
43 
44 /* Enable for DEBUG logging */
45 //#define MCS_DUMP_PCM_TO_FILE
46 #ifdef MCS_DUMP_PCM_TO_FILE
47 #include <stdio.h>
48 FILE *file_au_reader = NULL;
49 FILE *file_pcm_decoder = NULL;
50 FILE *file_pcm_encoder = NULL;
51 #endif
52 
53 /* Core headers */
54 #include "M4MCS_API.h"
55 #include "M4MCS_ErrorCodes.h"
56 #include "M4MCS_InternalTypes.h"
57 #include "M4MCS_InternalConfig.h"
58 #include "M4MCS_InternalFunctions.h"
59 
60 #ifdef M4MCS_SUPPORT_STILL_PICTURE
61 #include "M4MCS_StillPicture.h"
62 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
63 
64 /* Common headers (for aac) */
65 #include "M4_Common.h"
66 
67 #include "NXPSW_CompilerSwitches.h"
68 
69 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
70 #include "M4VD_EXTERNAL_Interface.h"
71 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
72 
73 #include "M4AIR_API.h"
74 #include "OMX_Video.h"
75 
76 /* Version */
77 #define M4MCS_VERSION_MAJOR 3
78 #define M4MCS_VERSION_MINOR 4
79 #define M4MCS_VERSION_REVISION  3
80 
81 /**
82  ********************************************************************
83  * Static local functions
84  ********************************************************************
85  */
86 
87 static M4OSA_ERR M4MCS_intStepSet( M4MCS_InternalContext *pC );
88 static M4OSA_ERR M4MCS_intPrepareVideoDecoder(
89                                     M4MCS_InternalContext *pC );
90 static M4OSA_ERR M4MCS_intPrepareVideoEncoder(
91                                     M4MCS_InternalContext *pC );
92 static M4OSA_ERR M4MCS_intPrepareAudioProcessing(
93                                     M4MCS_InternalContext *pC );
94 static M4OSA_ERR M4MCS_intPrepareWriter( M4MCS_InternalContext *pC );
95 static M4OSA_ERR M4MCS_intPrepareAudioBeginCut(
96                                     M4MCS_InternalContext *pC );
97 static M4OSA_ERR M4MCS_intStepEncoding(
98                                     M4MCS_InternalContext *pC,
99                                     M4OSA_UInt8 *pTranscodedTime );
100 static M4OSA_ERR M4MCS_intStepBeginVideoJump(
101                                     M4MCS_InternalContext *pC );
102 static M4OSA_ERR M4MCS_intStepBeginVideoDecode(
103                                     M4MCS_InternalContext *pC );
104 static M4OSA_ERR M4MCS_intAudioNullEncoding( M4MCS_InternalContext *pC );
105 static M4OSA_ERR M4MCS_intAudioTranscoding( M4MCS_InternalContext *pC );
106 static M4OSA_ERR M4MCS_intVideoNullEncoding( M4MCS_InternalContext *pC );
107 static M4OSA_ERR M4MCS_intVideoTranscoding( M4MCS_InternalContext *pC );
108 static M4OSA_ERR M4MCS_intGetInputClipProperties(
109                                     M4MCS_InternalContext   *pContext );
110 static M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB(
111                                     M4OSA_MemAddr8 pAudioFrame );
112 static M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC(
113                                     M4OSA_MemAddr8 pAudioFrame );
114 static M4OSA_ERR M4MCS_intCheckMaxFileSize( M4MCS_Context pContext );
115 static M4VIDEOEDITING_Bitrate M4MCS_intGetNearestBitrate(
116                                     M4OSA_Int32 freebitrate,
117                                     M4OSA_Int8 mode );
118 static M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders(
119                                     M4MCS_InternalContext *pC );
120 static M4OSA_ERR M4MCS_intReallocTemporaryAU(
121                                     M4OSA_MemAddr8 *addr,
122                                     M4OSA_UInt32 newSize );
123 static M4OSA_ERR M4MCS_intCheckAndGetCodecProperties(
124                                  M4MCS_InternalContext *pC);
125 
126 static M4OSA_ERR M4MCS_intLimitBitratePerCodecProfileLevel(
127                                  M4ENCODER_AdvancedParams* EncParams);
128 static M4OSA_Int32 M4MCS_intLimitBitrateForH263Enc(M4OSA_Int32 profile,
129                                  M4OSA_Int32 level, M4OSA_Int32 bitrate);
130 static M4OSA_Int32 M4MCS_intLimitBitrateForMpeg4Enc(M4OSA_Int32 profile,
131                                  M4OSA_Int32 level, M4OSA_Int32 bitrate);
132 static M4OSA_Int32 M4MCS_intLimitBitrateForH264Enc(M4OSA_Int32 profile,
133                                  M4OSA_Int32 level, M4OSA_Int32 bitrate);
134 
135 /**
136  **********************************************************************
137  * External function used only by VideoEditor and that does not appear
138  * in the API
139  **********************************************************************
140  */
141 
142 M4OSA_ERR M4MCS_open_normalMode( M4MCS_Context pContext,
143                                  M4OSA_Void *pFileIn,
144                                  M4VIDEOEDITING_FileType InputFileType,
145                                  M4OSA_Void *pFileOut,
146                                  M4OSA_Void *pTempFile );
147 
148 /* All errors are fatal in the MCS */
149 #define M4ERR_CHECK_RETURN(err) if(M4NO_ERROR!=err) return err;
150 
151 /* A define used with SSRC 1.04 and above to avoid taking blocks smaller
152  * that the minimal block size
153  */
154 #define M4MCS_SSRC_MINBLOCKSIZE        100
155 
156 static M4OSA_UChar Tab_MCS[8] =
157 {
158     17, 5, 3, 3, 1, 1, 1, 1
159 };
160 
H264MCS_Getinstance(NSWAVC_MCS_t ** instance)161 M4OSA_ERR H264MCS_Getinstance( NSWAVC_MCS_t ** instance )
162 {
163     NSWAVC_MCS_t *p_bs = M4OSA_NULL;
164     M4OSA_ERR err = M4NO_ERROR;
165     p_bs = (NSWAVC_MCS_t *)M4OSA_32bitAlignedMalloc(sizeof(NSWAVC_MCS_t), M4MCS,
166         (M4OSA_Char *)"NSWAVC_MCS_t");
167 
168     if( M4OSA_NULL == p_bs )
169     {
170         M4OSA_TRACE1_0("H264MCS_Getinstance: allocation error");
171         return M4ERR_ALLOC;
172     }
173 
174     p_bs->prev_frame_num = 0;
175     p_bs->cur_frame_num = 0;
176     p_bs->log2_max_frame_num_minus4 = 0;
177     p_bs->prev_new_frame_num = 0;
178     p_bs->is_done = 0;
179     p_bs->is_first = 1;
180 
181     p_bs->m_pDecoderSpecificInfo = M4OSA_NULL;
182     p_bs->m_decoderSpecificInfoSize = 0;
183 
184     p_bs->m_pEncoderSPS = M4OSA_NULL;
185     p_bs->m_encoderSPSSize = 0;
186 
187     p_bs->m_pEncoderPPS = M4OSA_NULL;
188     p_bs->m_encoderPPSSize = 0;
189 
190     p_bs->m_pFinalDSI = M4OSA_NULL;
191     p_bs->m_pFinalDSISize = 0;
192 
193     p_bs->p_clip_sps = M4OSA_NULL;
194     p_bs->m_encoder_SPS_Cnt = 0;
195 
196     p_bs->p_clip_pps = M4OSA_NULL;
197     p_bs->m_encoder_PPS_Cnt = 0;
198 
199     p_bs->p_encoder_sps = M4OSA_NULL;
200     p_bs->p_encoder_pps = M4OSA_NULL;
201 
202     p_bs->encoder_pps.slice_group_id = M4OSA_NULL;
203 
204     *instance = (NSWAVC_MCS_t *)p_bs;
205     return err;
206 }
207 
H264MCS_getBits(ComBitStreamMCS_t * p_bs,M4OSA_UInt32 numBits)208 M4OSA_UInt32 H264MCS_getBits( ComBitStreamMCS_t *p_bs, M4OSA_UInt32 numBits )
209 {
210     M4OSA_UInt32 ui32RetBits;
211     M4OSA_UInt8 *pbs;
212     M4OSA_Int32 bcnt;
213     p_bs->i8BitCnt -= numBits;
214     bcnt = p_bs->i8BitCnt;
215 
216     /* Measure the quantity of bits to be read in ui32TempBuff */
217     ui32RetBits = p_bs->ui32TempBuff >> (32 - numBits);
218 
219     /* Read numBits in ui32TempBuff */
220     p_bs->ui32TempBuff <<= numBits;
221     p_bs->bitPos += numBits;
222 
223     if( bcnt > 24 )
224     {
225         return (ui32RetBits);
226     }
227     else
228     { /* at least one byte can be buffered in ui32TempBuff */
229         pbs = (M4OSA_UInt8 *)p_bs->pui8BfrPtr;
230 
231         if( bcnt < (int)(p_bs->numBitsInBuffer - p_bs->bitPos) )
232         { /* not enough remaining bits in ui32TempBuff: need to be filled */
233             do
234             {
235                 /* On the fly detection of EPB byte */
236                 if( ( *(pbs) == 0x03)
237                     && (!(( pbs[-1])
238                     | (pbs[-2])))) //(p_bs->ui32LastTwoBytes & 0x0000FFFF) == 0)
239                 {
240                     /* EPB byte found: skip it and update bitPos accordingly */
241                             (pbs)++;
242                             p_bs->bitPos += 8;
243                         }
244 
245                         p_bs->ui32TempBuff |= *(pbs)++ << (24 - bcnt);
246                         bcnt += 8;
247             } while ( bcnt <= 24 );
248 
249             p_bs->pui8BfrPtr = (M4OSA_Int8 *)pbs;
250             p_bs->i8BitCnt = bcnt;
251             return (ui32RetBits);
252         }
253     }
254 
255     if( p_bs->bitPos <= p_bs->numBitsInBuffer )
256     {
257         return (ui32RetBits);
258     }
259     else
260     {
261         return (0);
262     }
263 }
264 
H264MCS_flushBits(ComBitStreamMCS_t * p_bs,M4OSA_UInt32 numBits)265 M4OSA_Void H264MCS_flushBits( ComBitStreamMCS_t *p_bs, M4OSA_UInt32 numBits )
266 {
267     M4OSA_UInt8 *pbs;
268     M4OSA_UInt32 bcnt;
269     p_bs->i8BitCnt -= numBits;
270     bcnt = p_bs->i8BitCnt;
271 
272     p_bs->ui32TempBuff <<= numBits;
273     p_bs->bitPos += numBits;
274 
275     if( bcnt > 24 )
276     {
277         return;
278     }
279     else
280     { /* at least one byte can be buffered in ui32TempBuff */
281         pbs = (M4OSA_UInt8 *)p_bs->pui8BfrPtr;
282 
283         if( bcnt < (p_bs->numBitsInBuffer - p_bs->bitPos) )
284         {   /* Not enough remaining bits in ui32TempBuff: need to be filled */
285             do
286             {
287                 /*  On the fly detection of EPB byte */
288                 if( ( *(pbs) == 0x03) && (!(( pbs[-1]) | (pbs[-2]))) )
289                 { /* JC: EPB byte found: skip it and update bitPos accordingly */
290                     (pbs)++;
291                     p_bs->bitPos += 8;
292                 }
293                 p_bs->ui32TempBuff |= *(pbs)++ << (24 - bcnt);
294                 bcnt += 8;
295             } while ( bcnt <= 24 );
296 
297             p_bs->pui8BfrPtr = (M4OSA_Int8 *)pbs;
298             p_bs->i8BitCnt = bcnt;
299         }
300     }
301 
302     return;
303 }
304 
H264MCS_DecVLCReadExpGolombCode(ComBitStreamMCS_t * p_bs)305 M4OSA_UInt32 H264MCS_DecVLCReadExpGolombCode( ComBitStreamMCS_t *p_bs )
306 {
307     M4OSA_UInt32 code, l0 = 0, l1;
308     /* Reading 32 Bits from local cache buffer of Bitstream structure*/
309     code = p_bs->ui32TempBuff;
310 
311     /* Checking in first 3 bits*/
312     if( code >> 29 )
313     {
314         l0 = Tab_MCS[(code >> 29)];
315         code = code >> (32 - l0);
316         H264MCS_flushBits(p_bs, l0);
317     }
318     else
319         {
320             if( code )
321             {
322                 code <<= 3;
323 
324                 for ( l0 = 3; code < 0x80000000; code <<= 1, l0++ );
325 
326                 if( l0 < 16 ) /*all useful bits are inside the 32 bits read */
327                 {
328                     code = code >> (31 - l0);
329                     H264MCS_flushBits(p_bs, 2 * l0 + 1);
330                 }
331                 else
332             { /* Read the useful bits in 2 parts */
333                     l1 = ( l0 << 1) - 31;
334                     code >>= l0;
335                     H264MCS_flushBits(p_bs, 32);
336                     code = ( code << l1) | H264MCS_getBits(p_bs, l1);
337                 }
338             }
339             else
340             {
341                 H264MCS_flushBits(p_bs, 32);
342 
343                 if( H264MCS_getBits(p_bs, 1) )
344                 {
345                     /* if number of leading 0's is 32, the only code allowed is 1 followed
346                     by 32 0's */
347 
348                     /*reading 32 more bits from bitstream buffer*/
349                     code = H264MCS_getBits(p_bs, 32);
350 
351                     if( code == 0 )
352                     {
353                         return (code - 1);
354                     }
355                 }
356                 /*if number of leading 0's is >32, then symbol is >32 bits,
357                 which is an error */
358                 //p_bs->state = _BS_ERR;
359                 //p_bs->flags |= _BF_SYM_ERR;
360                 return (0);
361             }
362         }
363 
364         if( 1 ) //(p_bs->state == _BS_OK)
365         {
366             return (code - 1);
367         }
368         else
369         {
370             return (0);
371         }
372     }
373 
H264MCS_DecVLCReadSignedExpGolombCode(ComBitStreamMCS_t * p_bs)374 M4OSA_Int32 H264MCS_DecVLCReadSignedExpGolombCode( ComBitStreamMCS_t *p_bs )
375 {
376     M4OSA_Int32 codeNo, ret;
377 
378     /* read the unsigned code number */
379     codeNo = H264MCS_DecVLCReadExpGolombCode(p_bs);
380 
381     /* map to the signed value, if value is odd then it's positive,
382     if even then it's negative, formula is (-1)^(k+1)*CEIL(k/2) */
383 
384     ret = (codeNo & 0x01) ? (( codeNo + 1) >> 1) : (( -codeNo) >> 1);
385 
386     return ret;
387 }
388 
DecBitStreamReset_MCS(ComBitStreamMCS_t * p_bs,M4OSA_UInt32 bytes_read)389 M4OSA_Void DecBitStreamReset_MCS( ComBitStreamMCS_t *p_bs,
390                                  M4OSA_UInt32 bytes_read )
391 {
392     p_bs->bitPos = 0;
393 
394     p_bs->lastTotalBits = 0;
395     p_bs->numBitsInBuffer = bytes_read << 3;
396     p_bs->readableBytesInBuffer = bytes_read;
397     //p_bs->state = M4NO_ERROR;//_BS_OK;
398     //p_bs->flags = 0;
399 
400     p_bs->ui32TempBuff = 0;
401     p_bs->i8BitCnt = 0;
402     p_bs->pui8BfrPtr = (M4OSA_Int8 *)p_bs->Buffer;
403     p_bs->ui32LastTwoBytes = 0xFFFFFFFF;
404     H264MCS_getBits(p_bs, 0);
405 }
406 
NSWAVCMCS_initBitstream(NSWAVC_bitStream_t_MCS * bS)407 M4OSA_ERR NSWAVCMCS_initBitstream( NSWAVC_bitStream_t_MCS *bS )
408 {
409     bS->bitPos = 0;
410     bS->byteCnt = 0;
411     bS->currBuff = 0;
412     bS->prevByte = 0xff;
413     bS->prevPrevByte = 0xff;
414 
415     return M4NO_ERROR;
416 }
417 
NSWAVCMCS_putBits(NSWAVC_bitStream_t_MCS * bS,M4OSA_UInt32 value,M4OSA_UInt8 length)418 M4OSA_ERR NSWAVCMCS_putBits( NSWAVC_bitStream_t_MCS *bS, M4OSA_UInt32 value,
419                             M4OSA_UInt8 length )
420 {
421     M4OSA_UInt32 maskedValue = 0, temp = 0;
422     M4OSA_UInt8 byteOne;
423 
424     M4OSA_UInt32 len1 = (length == 32) ? 31 : length;
425 
426     if( !(length) )
427     {
428         /* Length = 0, return OK*/
429         return M4NO_ERROR;
430     }
431 
432     maskedValue = (M4OSA_UInt32)(value &(( 1 << len1) - 1));
433 
434     if( 32 > (length + bS->bitPos) )
435     {
436         bS->bitPos += length;
437         bS->currBuff |= maskedValue << (32 - bS->bitPos);
438     }
439     else
440     {
441         temp = (( bS->bitPos + length) - 32);
442 
443         bS->currBuff |= (maskedValue >> (temp));
444 
445         byteOne =
446             bS->streamBuffer[bS->byteCnt++] = (M4OSA_UInt8)(bS->currBuff >> 24);
447 
448         if( (( bS->prevPrevByte
449             == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
450         {
451             bS->byteCnt -= 1;
452             bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
453             bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
454         }
455         else
456         {
457             bS->prevPrevByte = bS->prevByte;
458             bS->prevByte = byteOne;
459         }
460         byteOne = bS->streamBuffer[bS->byteCnt++] =
461             (M4OSA_UInt8)(( bS->currBuff >> 16) & 0xff);
462 
463         if( (( bS->prevPrevByte
464             == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
465         {
466             bS->byteCnt -= 1;
467             bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
468             bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
469         }
470         else
471         {
472             bS->prevPrevByte = bS->prevByte;
473             bS->prevByte = byteOne;
474         }
475         byteOne = bS->streamBuffer[bS->byteCnt++] =
476             (M4OSA_UInt8)(( bS->currBuff >> 8) & 0xff);
477 
478         if( (( bS->prevPrevByte
479             == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
480         {
481             bS->byteCnt -= 1;
482             bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
483             bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
484         }
485         else
486         {
487             bS->prevPrevByte = bS->prevByte;
488             bS->prevByte = byteOne;
489         }
490         byteOne = bS->streamBuffer[bS->byteCnt++] =
491             (M4OSA_UInt8)((bS->currBuff) &0xff);
492 
493         if( (( bS->prevPrevByte
494             == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
495         {
496             bS->byteCnt -= 1;
497             bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
498             bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
499         }
500         else
501         {
502             bS->prevPrevByte = bS->prevByte;
503             bS->prevByte = byteOne;
504         }
505 
506         bS->currBuff = 0;
507 
508         bS->currBuff |= ( maskedValue &(( 1 << temp) - 1)) << (32 - temp);
509 
510         bS->bitPos = temp;
511     }
512 
513     return M4NO_ERROR;
514 }
515 
NSWAVCMCS_putBit(NSWAVC_bitStream_t_MCS * bS,M4OSA_UInt32 value)516 M4OSA_ERR NSWAVCMCS_putBit( NSWAVC_bitStream_t_MCS *bS, M4OSA_UInt32 value )
517 {
518     M4OSA_UInt32 maskedValue = 0, temp = 0;
519     M4OSA_UInt8 byteOne;
520 
521     maskedValue = (value ? 1 : 0);
522 
523     if( 32 > (1 + bS->bitPos) )
524     {
525         bS->bitPos += 1;
526         bS->currBuff |= maskedValue << (32 - bS->bitPos);
527     }
528     else
529     {
530         temp = 0;
531 
532         bS->currBuff |= (maskedValue);
533 
534         /* writing it to memory*/
535         byteOne =
536             bS->streamBuffer[bS->byteCnt++] =
537             (M4OSA_UInt8)(bS->currBuff >> 24);
538 
539         if( (( bS->prevPrevByte
540             == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
541         {
542             bS->byteCnt -= 1;
543             bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
544             bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
545         }
546         else
547         {
548             bS->prevPrevByte = bS->prevByte;
549             bS->prevByte = byteOne;
550         }
551         byteOne = bS->streamBuffer[bS->byteCnt++] =
552             (M4OSA_UInt8)(( bS->currBuff >> 16) & 0xff);
553 
554         if( (( bS->prevPrevByte
555             == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
556         {
557             bS->byteCnt -= 1;
558             bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
559             bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
560         }
561         else
562         {
563             bS->prevPrevByte = bS->prevByte;
564             bS->prevByte = byteOne;
565         }
566         byteOne = bS->streamBuffer[bS->byteCnt++] =
567             (M4OSA_UInt8)(( bS->currBuff >> 8) & 0xff);
568 
569         if( (( bS->prevPrevByte
570             == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
571         {
572             bS->byteCnt -= 1;
573             bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
574             bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
575         }
576         else
577         {
578             bS->prevPrevByte = bS->prevByte;
579             bS->prevByte = byteOne;
580         }
581         byteOne = bS->streamBuffer[bS->byteCnt++] =
582             (M4OSA_UInt8)((bS->currBuff) &0xff);
583 
584         if( (( bS->prevPrevByte
585             == 0) & (bS->prevByte == 0) & (!(byteOne & 0xFC))) )
586         {
587             bS->byteCnt -= 1;
588             bS->prevPrevByte = bS->streamBuffer[bS->byteCnt++] = 0x03;
589             bS->prevByte = bS->streamBuffer[bS->byteCnt++] = byteOne;
590         }
591         else
592         {
593             bS->prevPrevByte = bS->prevByte;
594             bS->prevByte = byteOne;
595         }
596         bS->currBuff = 0;
597         bS->bitPos = 0;
598     }
599 
600     return M4NO_ERROR;
601 }
602 
NSWAVCMCS_putRbspTbits(NSWAVC_bitStream_t_MCS * bS)603 M4OSA_Int32 NSWAVCMCS_putRbspTbits( NSWAVC_bitStream_t_MCS *bS )
604 {
605     M4OSA_UInt8 trailBits = 0;
606     M4OSA_UInt8 byteCnt = 0;
607 
608     trailBits = (M4OSA_UInt8)(bS->bitPos % 8);
609 
610     /* Already in the byte aligned position,
611     RBSP trailing bits will be 1000 0000 */
612     if( 0 == trailBits )
613     {
614         trailBits = (1 << 7);
615         NSWAVCMCS_putBits(bS, trailBits, 8);
616     }
617     else
618     {
619         trailBits = (8 - trailBits);
620         NSWAVCMCS_putBit(bS, 1);
621         trailBits--;
622 
623         if( trailBits )
624         { /* put trailBits times zeros */
625             NSWAVCMCS_putBits(bS, 0, trailBits);
626         }
627     }
628 
629     /* For writting the currBuff in streamBuff 4byte alignment is required*/
630     byteCnt = (M4OSA_UInt8)(( bS->bitPos + 4) / 8);
631 
632     switch( byteCnt )
633     {
634         case 1:
635             bS->streamBuffer[bS->byteCnt++] = (M4OSA_UInt8)(bS->currBuff >> 24);
636             break;
637 
638         case 2:
639             bS->streamBuffer[bS->byteCnt++] = (M4OSA_UInt8)(bS->currBuff >> 24);
640             bS->streamBuffer[bS->byteCnt++] =
641                 (M4OSA_UInt8)(( bS->currBuff >> 16) & 0xff);
642             break;
643 
644         case 3:
645             bS->streamBuffer[bS->byteCnt++] = (M4OSA_UInt8)(bS->currBuff >> 24);
646             bS->streamBuffer[bS->byteCnt++] =
647                 (M4OSA_UInt8)(( bS->currBuff >> 16) & 0xff);
648             bS->streamBuffer[bS->byteCnt++] =
649                 (M4OSA_UInt8)(( bS->currBuff >> 8) & 0xff);
650 
651             break;
652 
653         default:
654             /* It will not come here */
655             break;
656     }
657 
658     //    bS->bitPos =0;
659     //    bS->currBuff = 0;
660 
661     return M4NO_ERROR;
662 }
663 
NSWAVCMCS_uExpVLC(NSWAVC_bitStream_t_MCS * bS,M4OSA_Int32 codeNum)664 M4OSA_ERR NSWAVCMCS_uExpVLC( NSWAVC_bitStream_t_MCS *bS, M4OSA_Int32 codeNum )
665 {
666 
667     M4OSA_Int32 loop, temp;
668     M4OSA_Int32 data = 0;
669     M4OSA_UInt8 codeLen = 0;
670 
671     /* The codeNum cannot be less than zero for this ue(v) */
672     if( codeNum < 0 )
673     {
674         return 0;
675     }
676 
677     /* Implementation for Encoding of the Table 9-1 in the Standard */
678     temp = codeNum + 1;
679 
680     for ( loop = 0; temp != 0; loop++ )
681     {
682         temp /= 2;
683     }
684 
685     codeLen = (( loop * 2) - 1);
686 
687     data = codeNum + 1;
688 
689     NSWAVCMCS_putBits(bS, data, codeLen);
690 
691     return M4NO_ERROR;
692 }
693 
NSWAVCMCS_sExpVLC(NSWAVC_bitStream_t_MCS * bS,M4OSA_Int32 codeNum)694 M4OSA_ERR NSWAVCMCS_sExpVLC( NSWAVC_bitStream_t_MCS *bS, M4OSA_Int32 codeNum )
695 {
696 
697     M4OSA_Int32 loop, temp1, temp2;
698     M4OSA_Int32 data = 0;
699     M4OSA_UInt8 codeLen = 0, isPositive = 0;
700     M4OSA_UInt32 abscodeNum;
701 
702     if( codeNum > 0 )
703     {
704         isPositive = 1;
705     }
706 
707     if( codeNum > 0 )
708     {
709         abscodeNum = codeNum;
710     }
711     else
712     {
713         abscodeNum = -codeNum;
714     }
715 
716     temp1 = ( ( ( abscodeNum) << 1) - isPositive) + 1;
717     temp2 = temp1;
718 
719     for ( loop = 0; loop < 16 && temp2 != 0; loop++ )
720     {
721         temp2 /= 2;
722     }
723 
724     codeLen = ( loop * 2) - 1;
725 
726     data = temp1;
727 
728     NSWAVCMCS_putBits(bS, data, codeLen);
729 
730     return M4NO_ERROR;
731 }
732 
H264MCS_ProcessEncodedNALU(M4OSA_Void * ainstance,M4OSA_UInt8 * inbuff,M4OSA_Int32 inbuf_size,M4OSA_UInt8 * outbuff,M4OSA_Int32 * outbuf_size)733 M4OSA_ERR H264MCS_ProcessEncodedNALU(   M4OSA_Void *ainstance,
734                                         M4OSA_UInt8 *inbuff,
735                                         M4OSA_Int32 inbuf_size,
736                                         M4OSA_UInt8 *outbuff,
737                                         M4OSA_Int32 *outbuf_size )
738 {
739     ComBitStreamMCS_t *p_bs, bs;
740     NSWAVC_MCS_t *instance;
741     M4OSA_UInt8 nalu_info;
742     M4OSA_Int32 forbidden_bit, nal_ref_idc, nal_unit_type;
743     M4OSA_Int32 first_mb_in_slice, slice_type, pic_parameter_set_id, frame_num;
744     M4OSA_Int32 seq_parameter_set_id;
745     M4OSA_UInt8 temp1, temp2, temp3, temp4;
746     M4OSA_Int32 temp_frame_num;
747     M4OSA_Int32 bitstoDiacard, bytes;
748     M4OSA_UInt32 mask_bits = 0xFFFFFFFF;
749     M4OSA_Int32 new_bytes, init_bit_pos;
750     M4OSA_UInt32 nal_size;
751     M4OSA_UInt32 cnt;
752     M4OSA_UInt32 outbuffpos = 0;
753     M4OSA_UInt32 nal_size_low16, nal_size_high16;
754     M4OSA_UInt32 frame_size = 0;
755     M4OSA_UInt32 temp = 0;
756 
757     // StageFright encoder does not provide the size in the first 4 bytes of the AU, add it
758     M4OSA_Int8 *pTmpBuff1 = M4OSA_NULL;
759     M4OSA_Int8 *pTmpBuff2 = M4OSA_NULL;
760 
761     p_bs = &bs;
762     instance = (NSWAVC_MCS_t *)ainstance;
763 
764     M4OSA_TRACE1_2(
765         "In  H264MCS_ProcessEncodedNALU with FrameSize = %d  inBuf_Size=%d",
766         frame_size, inbuf_size);
767 
768     // StageFright codecs may add a start code, make sure it is not present
769 
770     if( !memcmp((void *)inbuff,
771         "\x00\x00\x00\x01", 4) )
772     {
773         M4OSA_TRACE1_3(
774             "H264MCS_ProcessNALU ERROR : NALU start code has not been removed %d "
775             "0x%X 0x%X", inbuf_size, ((M4OSA_UInt32 *)inbuff)[0],
776             ((M4OSA_UInt32 *)inbuff)[1]);
777 
778         return M4ERR_PARAMETER;
779     }
780 
781     // StageFright encoder does not provide the size in the first 4 bytes of the AU, add it
782     pTmpBuff1 = (M4OSA_Int8 *)M4OSA_32bitAlignedMalloc(inbuf_size + 4, M4MCS,
783         (M4OSA_Char *)"tmpNALU");
784     memcpy((void *)(pTmpBuff1 + 4), (void *)inbuff,
785         inbuf_size);
786     pTmpBuff1[3] = ( (M4OSA_UInt32)inbuf_size) & 0x000000FF;
787     pTmpBuff1[2] = ( (M4OSA_UInt32)inbuf_size >> 8) & 0x000000FF;
788     pTmpBuff1[1] = ( (M4OSA_UInt32)inbuf_size >> 16) & 0x000000FF;
789     pTmpBuff1[0] = ( (M4OSA_UInt32)inbuf_size >> 24) & 0x000000FF;
790     pTmpBuff2 = (M4OSA_Int8 *)inbuff;
791     inbuff = (M4OSA_UInt8 *)pTmpBuff1;
792     inbuf_size += 4;
793 
794     // Make sure the available size was set
795     if( inbuf_size >= *outbuf_size )
796     {
797         M4OSA_TRACE1_1(
798             "!!! H264MCS_ProcessNALU ERROR : specified available size is incorrect %d ",
799             *outbuf_size);
800         return M4ERR_PARAMETER;
801     }
802 
803 
804 
805     while( (M4OSA_Int32)frame_size < inbuf_size )
806     {
807         mask_bits = 0xFFFFFFFF;
808         p_bs->Buffer = (M4OSA_UInt8 *)(inbuff + frame_size);
809 
810         // Use unsigned value to fix errors due to bit sign extension, this fix should be generic
811 
812         nal_size_high16 = ( ( (M4OSA_UInt8 *)p_bs->Buffer)[0] << 8)
813             + ((M4OSA_UInt8 *)p_bs->Buffer)[1];
814         nal_size_low16 = ( ( (M4OSA_UInt8 *)p_bs->Buffer)[2] << 8)
815             + ((M4OSA_UInt8 *)p_bs->Buffer)[3];
816 
817         nalu_info = (unsigned char)p_bs->Buffer[4];
818 
819         outbuff[outbuffpos] = p_bs->Buffer[4];
820 
821         p_bs->Buffer = p_bs->Buffer + 5;
822 
823         p_bs->bitPos = 0;
824         p_bs->lastTotalBits = 0;
825         p_bs->numBitsInBuffer = ( inbuf_size - frame_size - 5) << 3;
826         p_bs->readableBytesInBuffer = inbuf_size - frame_size - 5;
827 
828         p_bs->ui32TempBuff = 0;
829         p_bs->i8BitCnt = 0;
830         p_bs->pui8BfrPtr = (M4OSA_Int8 *)p_bs->Buffer;
831         p_bs->ui32LastTwoBytes = 0xFFFFFFFF;
832 
833         H264MCS_getBits(p_bs, 0);
834 
835         nal_size = ( nal_size_high16 << 16) + nal_size_low16;
836 
837         frame_size += nal_size + 4;
838 
839         forbidden_bit = ( nalu_info >> 7) & 1;
840         nal_ref_idc = ( nalu_info >> 5) & 3;
841         nal_unit_type = (nalu_info) &0x1f;
842 
843         NSWAVCMCS_initBitstream(&instance->encbs);
844 
845         instance->encbs.streamBuffer = outbuff + outbuffpos + 1;
846 
847         if( nal_unit_type == 8 )
848         {
849             M4OSA_TRACE1_0("Error : PPS");
850             return 0;
851         }
852 
853         if( nal_unit_type == 7 )
854         {
855             /*SPS Packet */
856             M4OSA_TRACE1_0("Error : SPS");
857             return 0;
858         }
859 
860         if( (nal_unit_type == 5) )
861         {
862             instance->frame_count = 0;
863             instance->POC_lsb = 0;
864         }
865 
866         if( ( nal_unit_type == 1) || (nal_unit_type == 5) )
867         {
868             first_mb_in_slice = H264MCS_DecVLCReadExpGolombCode(p_bs);
869             slice_type = H264MCS_DecVLCReadExpGolombCode(p_bs);
870             pic_parameter_set_id = H264MCS_DecVLCReadExpGolombCode(p_bs);
871 
872             /* First MB in slice */
873             NSWAVCMCS_uExpVLC(&instance->encbs, first_mb_in_slice);
874 
875             /* Slice Type */
876             NSWAVCMCS_uExpVLC(&instance->encbs, slice_type);
877 
878             /* Picture Parameter set Id */
879             pic_parameter_set_id = instance->encoder_pps.pic_parameter_set_id;
880             NSWAVCMCS_uExpVLC(&instance->encbs, pic_parameter_set_id);
881 
882             temp = H264MCS_getBits(p_bs,
883                 instance->encoder_sps.log2_max_frame_num_minus4 + 4);
884             NSWAVCMCS_putBits(&instance->encbs, instance->frame_count,
885                 instance->clip_sps.log2_max_frame_num_minus4 + 4);
886 
887             // In Baseline Profile: frame_mbs_only_flag should be ON
888             if( nal_unit_type == 5 )
889             {
890                 temp = H264MCS_DecVLCReadExpGolombCode(p_bs);
891                 NSWAVCMCS_uExpVLC(&instance->encbs, temp);
892             }
893 
894             if( instance->encoder_sps.pic_order_cnt_type == 0 )
895             {
896                 temp = H264MCS_getBits(p_bs,
897                     instance->encoder_sps.log2_max_pic_order_cnt_lsb_minus4
898                     + 4);
899 
900                 // in baseline profile field_pic_flag should be off.
901                 if( instance->encoder_pps.pic_order_present_flag )
902                 {
903                     temp = H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
904                 }
905             }
906 
907             if( ( instance->encoder_sps.pic_order_cnt_type == 1)
908                 && (instance->encoder_sps.delta_pic_order_always_zero_flag) )
909             {
910                 temp = H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
911 
912                 // in baseline profile field_pic_flag should be off.
913                 if( instance->encoder_pps.pic_order_present_flag )
914                 {
915                     temp = H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
916                 }
917             }
918 
919             if( instance->clip_sps.pic_order_cnt_type == 0 )
920             {
921                 NSWAVCMCS_putBits(&instance->encbs, instance->POC_lsb,
922                     instance->clip_sps.log2_max_pic_order_cnt_lsb_minus4 + 4);
923 
924                 // in baseline profile field_pic_flag should be off.
925                 if( instance->encoder_pps.pic_order_present_flag )
926                 {
927                     NSWAVCMCS_sExpVLC(&instance->encbs, 0);
928                 }
929             }
930 
931             if( ( instance->clip_sps.pic_order_cnt_type == 1)
932                 && (instance->clip_sps.delta_pic_order_always_zero_flag) )
933             {
934                 NSWAVCMCS_sExpVLC(&instance->encbs, 0);
935 
936                 // in baseline profile field_pic_flag should be off.
937                 if( instance->encoder_pps.pic_order_present_flag )
938                 {
939                     NSWAVCMCS_sExpVLC(&instance->encbs, 0);
940                 }
941             }
942 
943             cnt = p_bs->bitPos & 0x7;
944 
945             if( cnt )
946             {
947                 cnt = 8 - cnt;
948                 temp = H264MCS_getBits(p_bs, cnt);
949                 NSWAVCMCS_putBits(&instance->encbs, temp, cnt);
950             }
951 
952             cnt = p_bs->bitPos >> 3;
953 
954             while( cnt < (nal_size - 2) )
955             {
956                 temp = H264MCS_getBits(p_bs, 8);
957                 NSWAVCMCS_putBits(&instance->encbs, temp, 8);
958                 cnt = p_bs->bitPos >> 3;
959             }
960 
961             temp = H264MCS_getBits(p_bs, 8);
962 
963             if( temp != 0 )
964             {
965                 cnt = 0;
966 
967                 while( ( temp & 0x1) == 0 )
968                 {
969                     cnt++;
970                     temp = temp >> 1;
971                 }
972                 cnt++;
973                 temp = temp >> 1;
974 
975                 if( 8 - cnt )
976                 {
977                     NSWAVCMCS_putBits(&instance->encbs, temp, (8 - cnt));
978                 }
979 
980                 NSWAVCMCS_putRbspTbits(&instance->encbs);
981             }
982             else
983             {
984 
985                 M4OSA_TRACE1_1(
986                     "H264MCS_ProcessEncodedNALU : 13 temp = 0 trailing bits = %d",
987                     instance->encbs.bitPos % 8);
988 
989                 if( instance->encbs.bitPos % 8 )
990                 {
991                     NSWAVCMCS_putBits(&instance->encbs, 0,
992                         (8 - instance->encbs.bitPos % 8));
993                 }
994             }
995 
996             temp = instance->encbs.byteCnt;
997             temp = temp + 1;
998 
999             outbuffpos = outbuffpos + temp;
1000         }
1001     }
1002 
1003     *outbuf_size = outbuffpos;
1004 
1005     instance->POC_lsb = instance->POC_lsb + 1;
1006 
1007     if( instance->POC_lsb == instance->POC_lsb_mod )
1008     {
1009         instance->POC_lsb = 0;
1010     }
1011     instance->frame_count = instance->frame_count + 1;
1012 
1013     if( instance->frame_count == instance->frame_mod_count )
1014     {
1015         instance->frame_count = 0;
1016     }
1017 
1018     // StageFright encoder does not provide the size in the first 4 bytes of the AU, add it
1019 
1020     free(pTmpBuff1);
1021     pTmpBuff1 = M4OSA_NULL;
1022     inbuff = (M4OSA_UInt8 *)pTmpBuff2;
1023 
1024     return M4NO_ERROR;
1025 }
1026 
DecSPSMCS(ComBitStreamMCS_t * p_bs,ComSequenceParameterSet_t_MCS * sps)1027 M4OSA_Int32 DecSPSMCS( ComBitStreamMCS_t *p_bs,
1028                       ComSequenceParameterSet_t_MCS *sps )
1029 {
1030     M4OSA_UInt32 i;
1031     M4OSA_Int32 temp_max_dpb_size;
1032     M4OSA_Int32 nb_ignore_bits;
1033     M4OSA_Int32 error;
1034     M4OSA_UInt8 profile_idc, level_idc, reserved_zero_4bits,
1035         seq_parameter_set_id;
1036     M4OSA_UInt8 constraint_set0_flag, constraint_set1_flag,
1037         constraint_set2_flag, constraint_set3_flag;
1038 
1039     sps->profile_idc = (M4OSA_UInt8)H264MCS_getBits(p_bs, 8);
1040     sps->constraint_set0_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1041     sps->constraint_set1_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1042     sps->constraint_set2_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1043     sps->constraint_set3_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1044     reserved_zero_4bits = (M4OSA_UInt8)H264MCS_getBits(p_bs, 4);
1045     sps->level_idc = (M4OSA_UInt8)H264MCS_getBits(p_bs, 8);
1046     sps->seq_parameter_set_id =
1047         (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1048     sps->log2_max_frame_num_minus4 =
1049         (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1050     sps->MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1051     sps->pic_order_cnt_type =
1052         (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1053 
1054     if (sps->pic_order_cnt_type == 0)
1055     {
1056         sps->log2_max_pic_order_cnt_lsb_minus4 =
1057             (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1058         sps->MaxPicOrderCntLsb =
1059             1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1060     }
1061     else if( sps->pic_order_cnt_type == 1 )
1062     {
1063         sps->delta_pic_order_always_zero_flag =
1064             (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1065 
1066         // This fix should be generic to remove codec dependency
1067 
1068         sps->offset_for_non_ref_pic =
1069             H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1070         sps->offset_for_top_to_bottom_field =
1071             H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1072 
1073 
1074         /*num_ref_frames_in_pic_order_cnt_cycle must be in the range 0, 255*/
1075 
1076         sps->num_ref_frames_in_pic_order_cnt_cycle =
1077             (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1078 
1079         /* compute deltaPOC */
1080         sps->expectedDeltaPerPicOrderCntCycle = 0;
1081 
1082         for ( i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++ )
1083         {
1084             // This fix should be generic to remove codec dependency
1085             sps->offset_for_ref_frame[i] =
1086                 H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1087 
1088             sps->expectedDeltaPerPicOrderCntCycle +=
1089                 sps->offset_for_ref_frame[i];
1090         }
1091     }
1092 
1093     /* num_ref_frames must be in the range 0,16 */
1094     sps->num_ref_frames = (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1095     sps->gaps_in_frame_num_value_allowed_flag =
1096         (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1097 
1098     sps->pic_width_in_mbs_minus1 =
1099         (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1100     sps->pic_height_in_map_units_minus1 =
1101         (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1102 
1103     sps->frame_mbs_only_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1104 
1105     if (!sps->frame_mbs_only_flag)
1106     {
1107         sps->mb_adaptive_frame_field_flag =
1108             (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1109     }
1110     else
1111     {
1112         sps->mb_adaptive_frame_field_flag = 0;
1113     }
1114 
1115     sps->PicWidthInMbs = sps->pic_width_in_mbs_minus1 + 1;
1116     sps->FrameHeightInMbs = ( 2 - sps->frame_mbs_only_flag) * \
1117         (sps->pic_height_in_map_units_minus1 + 1);
1118 #ifdef _CAP_FMO_
1119 
1120     sps->NumSliceGroupMapUnits =
1121         sps->PicWidthInMbs * (sps->pic_height_in_map_units_minus1 + 1);
1122     sps->MaxPicSizeInMbs = sps->PicWidthInMbs * sps->FrameHeightInMbs;
1123 
1124 #endif /*_CAP_FMO_*/
1125 
1126     sps->direct_8x8_inference_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1127 
1128     if( sps->frame_mbs_only_flag == 0 )
1129         sps->direct_8x8_inference_flag = 1;
1130 
1131     sps->frame_cropping_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1132 
1133     if( sps->frame_cropping_flag )
1134     {
1135         sps->frame_crop_left_offset = H264MCS_DecVLCReadExpGolombCode(p_bs);
1136         sps->frame_crop_right_offset = H264MCS_DecVLCReadExpGolombCode(p_bs);
1137         sps->frame_crop_top_offset = H264MCS_DecVLCReadExpGolombCode(p_bs);
1138         sps->frame_crop_bottom_offset = H264MCS_DecVLCReadExpGolombCode(p_bs);
1139     }
1140     else
1141     {
1142         sps->frame_crop_left_offset = 0;
1143         sps->frame_crop_right_offset = 0;
1144         sps->frame_crop_top_offset = 0;
1145         sps->frame_crop_bottom_offset = 0;
1146     }
1147 
1148     sps->vui_parameters_present_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1149 
1150     if (sps->vui_parameters_present_flag) {
1151         /* no error message as stream can be decoded without VUI messages */
1152     }
1153 
1154     return M4NO_ERROR;
1155 }
1156 
DecPPSMCS(ComBitStreamMCS_t * p_bs,ComPictureParameterSet_t_MCS * pps)1157 M4OSA_Int32 DecPPSMCS( ComBitStreamMCS_t *p_bs,
1158                       ComPictureParameterSet_t_MCS *pps )
1159 {
1160     M4OSA_Int32 error;
1161     M4OSA_UInt32 pic_parameter_set_id;
1162 
1163 #ifdef _CAP_FMO_
1164     M4OSA_UInt32 i, length, v;
1165 #endif
1166 
1167     M4OSA_Int32 nb_ignore_bits;
1168 
1169     pic_parameter_set_id = H264MCS_DecVLCReadExpGolombCode(p_bs);
1170     pps->pic_parameter_set_id = (M4OSA_UInt8)pic_parameter_set_id;
1171 
1172     pps->seq_parameter_set_id =
1173         (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1174 
1175     /* entropy_coding_mode_flag must be 0 or 1 */
1176     pps->entropy_coding_mode_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1177     pps->pic_order_present_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1178 
1179     pps->num_slice_groups_minus1 =
1180         (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1181 
1182 #ifdef _CAP_FMO_
1183     /* FMO stuff begins here */
1184 
1185     pps->map_initialized = FALSE;
1186 
1187     if( pps->num_slice_groups_minus1 > 0 )
1188     {
1189         pps->slice_group_map_type =
1190             (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1191 
1192         switch( pps->slice_group_map_type )
1193         {
1194             case 0:
1195                 for ( i = 0; i <= pps->num_slice_groups_minus1; i++ )
1196                 {
1197                     pps->run_length_minus1[i] =
1198                         (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1199                 }
1200                 break;
1201 
1202             case 2:
1203                 for ( i = 0; i < pps->num_slice_groups_minus1; i++ )
1204                 {
1205                     pps->top_left[i] =
1206                         (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1207                     pps->bottom_right[i] =
1208                         (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1209                 }
1210                 break;
1211 
1212             case 3:
1213             case 4:
1214             case 5:
1215                 pps->slice_group_change_direction_flag =
1216                     (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1217                 pps->slice_group_change_rate_minus1 =
1218                     (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1219                 break;
1220 
1221             case 6:
1222                 pps->pic_size_in_map_units_minus1 =
1223                     (M4OSA_UInt16)H264MCS_DecVLCReadExpGolombCode(p_bs);
1224 
1225                 pps->slice_group_id = (H264UInt8
1226                     *)M4H264Dec_malloc((pps->pic_size_in_map_units_minus1
1227                     + 1), M4H264_COREID, (M4OSA_Char *)"PPS");
1228 
1229                 if (M4OSA_NULL == pps->slice_group_id)
1230                 {
1231                     M4OSA_TRACE1_0("DecPPSMCS: allocation error");
1232                     return M4ERR_ALLOC;
1233                 }
1234 
1235                 for ( length = 0, v = pps->num_slice_groups_minus1 + 1; v != 0;
1236                     v >>= 1, length++ );
1237 
1238                     for ( i = 0; i <= pps->pic_size_in_map_units_minus1; i++ )
1239                     {
1240                         pps->slice_group_id[i] =
1241                             (M4OSA_UInt8)getBits(p_vlc_engine->p_bs, length);
1242                     }
1243                     break;
1244         }
1245     }
1246     else
1247     {
1248         pps->slice_group_map_type = 0;
1249     }
1250     /* End of FMO stuff */
1251 
1252 #else
1253 
1254 #endif /* _CAP_FMO_ */
1255 
1256     /* num_ref_idx_l0_active_minus1 must be in the range 0, 31 */
1257 
1258     pps->num_ref_idx_l0_active_minus1 =
1259         (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1260     /* num_ref_idx_l1_active_minus1 must be in the range 0, 31 */
1261     pps->num_ref_idx_l1_active_minus1 =
1262         (M4OSA_UInt8)H264MCS_DecVLCReadExpGolombCode(p_bs);
1263     pps->weighted_pred_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1264 
1265     /* weighted_bipred_idc must be in the range 0,2 */
1266     pps->weighted_bipred_idc = (M4OSA_Bool)H264MCS_getBits(p_bs, 2);
1267 
1268     /* pic_init_qp_minus26 must be in the range -26,25 */
1269     pps->pic_init_qp_minus26 =
1270         (M4OSA_Int16)H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1271 
1272     /* pic_init_qs_minus26 must be in the range -26,25 */
1273     pps->pic_init_qs_minus26 =
1274         (M4OSA_Int16)H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1275 
1276     /* chroma_qp_index_offset must be in the range -12,+12 */
1277     pps->chroma_qp_index_offset =
1278         (M4OSA_Int16)H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1279     pps->deblocking_filter_control_present_flag =
1280         (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1281     pps->constrained_intra_pred_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1282     pps->redundant_pic_cnt_present_flag = (M4OSA_Bool)H264MCS_getBits(p_bs, 1);
1283 
1284     return M4NO_ERROR;
1285 }
1286 
H264MCS_ProcessSPS_PPS(NSWAVC_MCS_t * instance,M4OSA_UInt8 * inbuff,M4OSA_Int32 inbuf_size)1287 M4OSA_ERR H264MCS_ProcessSPS_PPS( NSWAVC_MCS_t *instance, M4OSA_UInt8 *inbuff,
1288                                  M4OSA_Int32 inbuf_size )
1289 {
1290     ComBitStreamMCS_t *p_bs, bs;
1291     ComBitStreamMCS_t *p_bs1, bs1;
1292 
1293     M4OSA_UInt8 nalu_info = 0;
1294     M4OSA_Int32 forbidden_bit, nal_ref_idc, nal_unit_type;
1295     M4OSA_Int32 first_mb_in_slice, slice_type, pic_parameter_set_id = 0,
1296         frame_num;
1297     M4OSA_Int32 seq_parameter_set_id;
1298     M4OSA_UInt8 temp1, temp2, temp3, temp4;
1299     M4OSA_Int32 temp_frame_num;
1300     M4OSA_Int32 bitstoDiacard, bytes;
1301     M4OSA_UInt32 mask_bits = 0xFFFFFFFF;
1302     M4OSA_Int32 new_bytes, init_bit_pos;
1303     M4OSA_UInt32 nal_size = 0;
1304     M4OSA_UInt32 cnt, cnt1;
1305     M4OSA_UInt32 outbuffpos = 0;
1306     M4OSA_UInt32 nal_size_low16, nal_size_high16;
1307     M4OSA_UInt32 frame_size = 0;
1308     M4OSA_UInt32 temp = 0;
1309     M4OSA_UInt8 *lClipDSI;
1310     M4OSA_UInt8 *lClipDSI_PPS_start;
1311     M4OSA_UInt32 lClipDSI_PPS_offset = 0;
1312 
1313     M4OSA_UInt8 *lPPS_Buffer = M4OSA_NULL;
1314     M4OSA_UInt32 lPPS_Buffer_Size = 0;
1315 
1316     M4OSA_UInt32 lSize, lSize1;
1317     M4OSA_UInt32 lActiveSPSID_Clip;
1318     M4OSA_UInt32 lClipPPSRemBits = 0;
1319 
1320     M4OSA_UInt32 lEncoder_SPSID = 0;
1321     M4OSA_UInt32 lEncoder_PPSID = 0;
1322     M4OSA_UInt32 lEncoderPPSRemBits = 0;
1323     M4OSA_UInt32 lFound = 0;
1324     M4OSA_UInt32 size;
1325 
1326     M4OSA_UInt8 Clip_SPSID[32] = { 0 };
1327     M4OSA_UInt8 Clip_UsedSPSID[32] = { 0 };
1328     M4OSA_UInt8 Clip_PPSID[256] = { 0 };
1329     M4OSA_UInt8 Clip_SPSID_in_PPS[256] = { 0 };
1330     M4OSA_UInt8 Clip_UsedPPSID[256] = { 0 };
1331     M4OSA_ERR err = M4NO_ERROR;
1332 
1333     p_bs = &bs;
1334     p_bs1 = &bs1;
1335 
1336     /* Find the active SPS ID */
1337     M4OSA_DEBUG_IF2((M4OSA_NULL == instance), M4ERR_PARAMETER,
1338         "H264MCS_ProcessSPS_PPS: instance is M4OSA_NULL");
1339 
1340     instance->m_Num_Bytes_NALUnitLength =
1341             (instance->m_pDecoderSpecificInfo[4] & 0x03) + 1;
1342 
1343     instance->m_encoder_SPS_Cnt = instance->m_pDecoderSpecificInfo[5] & 0x1F;
1344 
1345     lClipDSI = instance->m_pDecoderSpecificInfo + 6;
1346 
1347     lClipDSI_PPS_offset = 6;
1348 
1349     for ( cnt = 0; cnt < instance->m_encoder_SPS_Cnt; cnt++ )
1350     {
1351         lSize = ( lClipDSI[0] << 8) + lClipDSI[1];
1352         lClipDSI = lClipDSI + 2;
1353 
1354         p_bs->Buffer = (M4OSA_UInt8 *)(lClipDSI + 4);
1355         DecBitStreamReset_MCS(p_bs, lSize - 4);
1356 
1357         Clip_SPSID[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs);
1358         Clip_UsedSPSID[Clip_SPSID[cnt]] = 1;
1359 
1360         lClipDSI = lClipDSI + lSize;
1361         lClipDSI_PPS_offset = lClipDSI_PPS_offset + 2 + lSize;
1362     }
1363 
1364     instance->m_encoder_PPS_Cnt = lClipDSI[0];
1365     lClipDSI = lClipDSI + 1;
1366 
1367     lClipDSI_PPS_start = lClipDSI;
1368 
1369     for ( cnt = 0; cnt < instance->m_encoder_PPS_Cnt; cnt++ )
1370     {
1371         lSize = ( lClipDSI[0] << 8) + lClipDSI[1];
1372         lClipDSI = lClipDSI + 2;
1373 
1374         p_bs->Buffer = (M4OSA_UInt8 *)(lClipDSI + 1);
1375         DecBitStreamReset_MCS(p_bs, lSize - 1);
1376 
1377         Clip_PPSID[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs);
1378         Clip_UsedPPSID[Clip_PPSID[cnt]] = 1;
1379         Clip_SPSID_in_PPS[Clip_PPSID[cnt]] =
1380             H264MCS_DecVLCReadExpGolombCode(p_bs);
1381 
1382         lClipDSI = lClipDSI + lSize;
1383     }
1384 
1385     /* Find the clip SPS ID used at the cut start frame */
1386     while( ( (M4OSA_Int32)frame_size) < inbuf_size )
1387     {
1388         mask_bits = 0xFFFFFFFF;
1389         p_bs->Buffer = (M4OSA_UInt8 *)(inbuff + frame_size);
1390 
1391         switch( instance->m_Num_Bytes_NALUnitLength )
1392         {
1393             case 1:
1394                 nal_size = (unsigned char)p_bs->Buffer[0];
1395                 nalu_info = (unsigned char)p_bs->Buffer[1];
1396                 p_bs->Buffer = p_bs->Buffer + 2;
1397 
1398                 break;
1399 
1400             case 2:
1401                 nal_size_high16 = ( p_bs->Buffer[0] << 8) + p_bs->Buffer[1];
1402                 nal_size = nal_size_high16;
1403                 nalu_info = (unsigned char)p_bs->Buffer[2];
1404                 p_bs->Buffer = p_bs->Buffer + 3;
1405 
1406                 break;
1407 
1408             case 4:
1409                 nal_size_high16 = ( p_bs->Buffer[0] << 8) + p_bs->Buffer[1];
1410                 nal_size_low16 = ( p_bs->Buffer[2] << 8) + p_bs->Buffer[3];
1411                 nal_size = ( nal_size_high16 << 16) + nal_size_low16;
1412                 nalu_info = (unsigned char)p_bs->Buffer[4];
1413                 p_bs->Buffer = p_bs->Buffer + 5;
1414 
1415                 break;
1416         }
1417 
1418         if (nal_size == 0) {
1419             M4OSA_TRACE1_1("0 size nal unit at line %d", __LINE__);
1420             frame_size += instance->m_Num_Bytes_NALUnitLength;
1421             continue;
1422         }
1423 
1424         p_bs->bitPos = 0;
1425         p_bs->lastTotalBits = 0;
1426         p_bs->numBitsInBuffer =
1427             ( inbuf_size - frame_size - instance->m_Num_Bytes_NALUnitLength - 1)
1428             << 3;
1429         p_bs->readableBytesInBuffer =
1430             inbuf_size - frame_size - instance->m_Num_Bytes_NALUnitLength - 1;
1431 
1432         p_bs->ui32TempBuff = 0;
1433         p_bs->i8BitCnt = 0;
1434         p_bs->pui8BfrPtr = (M4OSA_Int8 *)p_bs->Buffer;
1435         p_bs->ui32LastTwoBytes = 0xFFFFFFFF;
1436 
1437         H264MCS_getBits(p_bs, 0);
1438 
1439         frame_size += nal_size + instance->m_Num_Bytes_NALUnitLength;
1440 
1441         forbidden_bit = ( nalu_info >> 7) & 1;
1442         nal_ref_idc = ( nalu_info >> 5) & 3;
1443         nal_unit_type = (nalu_info) &0x1f;
1444 
1445         if( nal_unit_type == 8 )
1446         {
1447             M4OSA_TRACE1_0("H264MCS_ProcessSPS_PPS() Error: PPS");
1448             return err;
1449         }
1450 
1451         if( nal_unit_type == 7 )
1452         {
1453             /*SPS Packet */
1454             M4OSA_TRACE1_0("H264MCS_ProcessSPS_PPS() Error: SPS");
1455             return err;
1456         }
1457 
1458         if( ( nal_unit_type == 1) || (nal_unit_type == 5) )
1459         {
1460             first_mb_in_slice = H264MCS_DecVLCReadExpGolombCode(p_bs);
1461             slice_type = H264MCS_DecVLCReadExpGolombCode(p_bs);
1462             pic_parameter_set_id = H264MCS_DecVLCReadExpGolombCode(p_bs);
1463             break;
1464         }
1465     }
1466 
1467     lActiveSPSID_Clip = Clip_SPSID_in_PPS[pic_parameter_set_id];
1468 
1469     instance->final_SPS_ID = lActiveSPSID_Clip;
1470     /* Do we need to add encoder PPS to clip PPS */
1471 
1472     lClipDSI = lClipDSI_PPS_start;
1473 
1474     for ( cnt = 0; cnt < instance->m_encoder_PPS_Cnt; cnt++ )
1475     {
1476         lSize = ( lClipDSI[0] << 8) + lClipDSI[1];
1477         lClipDSI = lClipDSI + 2;
1478 
1479         if( lActiveSPSID_Clip == Clip_SPSID_in_PPS[Clip_PPSID[cnt]] )
1480         {
1481             lPPS_Buffer = lClipDSI + 1;
1482             lPPS_Buffer_Size = lSize - 1;
1483 
1484             p_bs->Buffer = (M4OSA_UInt8 *)(lClipDSI + 1);
1485             DecBitStreamReset_MCS(p_bs, lSize - 1);
1486 
1487             Clip_PPSID[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs);
1488             Clip_UsedPPSID[Clip_SPSID[cnt]] = 1;
1489             Clip_SPSID_in_PPS[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs);
1490             lClipPPSRemBits = ( lSize - 1) << 3;
1491             lClipPPSRemBits -= p_bs->bitPos;
1492 
1493             temp = lClipDSI[lSize - 1];
1494 
1495             cnt1 = 0;
1496 
1497             while( ( temp & 0x1) == 0 )
1498             {
1499                 cnt1++;
1500                 temp = temp >> 1;
1501             }
1502             cnt1++;
1503             lClipPPSRemBits -= cnt1;
1504 
1505             lSize1 = instance->m_encoderPPSSize - 1;
1506             p_bs1->Buffer = (M4OSA_UInt8 *)(instance->m_pEncoderPPS + 1);
1507             DecBitStreamReset_MCS(p_bs1, lSize1);
1508 
1509             lEncoder_PPSID = H264MCS_DecVLCReadExpGolombCode(p_bs1);
1510             lEncoder_SPSID = H264MCS_DecVLCReadExpGolombCode(p_bs1);
1511 
1512             lEncoderPPSRemBits = ( lSize1) << 3;
1513             lEncoderPPSRemBits -= p_bs1->bitPos;
1514 
1515             temp = instance->m_pEncoderPPS[lSize1];
1516 
1517             cnt1 = 0;
1518 
1519             while( ( temp & 0x1) == 0 )
1520             {
1521                 cnt1++;
1522                 temp = temp >> 1;
1523             }
1524             cnt1++;
1525             lEncoderPPSRemBits -= cnt1;
1526 
1527             if( lEncoderPPSRemBits == lClipPPSRemBits )
1528             {
1529                 while( lEncoderPPSRemBits > 8 )
1530                 {
1531                     temp1 = H264MCS_getBits(p_bs, 8);
1532                     temp2 = H264MCS_getBits(p_bs1, 8);
1533                     lEncoderPPSRemBits = lEncoderPPSRemBits - 8;
1534 
1535                     if( temp1 != temp2 )
1536                     {
1537                         break;
1538                     }
1539                 }
1540 
1541                 if( lEncoderPPSRemBits < 8 )
1542                 {
1543                     if( lEncoderPPSRemBits )
1544                     {
1545                         temp1 = H264MCS_getBits(p_bs, lEncoderPPSRemBits);
1546                         temp2 = H264MCS_getBits(p_bs1, lEncoderPPSRemBits);
1547 
1548                         if( temp1 == temp2 )
1549                         {
1550                             lFound = 1;
1551                         }
1552                     }
1553                     else
1554                     {
1555                         lFound = 1;
1556                     }
1557                 }
1558                 break;
1559             }
1560         }
1561 
1562         lClipDSI = lClipDSI + lSize;
1563     }
1564 
1565     /* Form the final SPS and PPS data */
1566 
1567     if( lFound == 1 )
1568     {
1569         /* No need to add PPS */
1570         instance->final_PPS_ID = Clip_PPSID[cnt];
1571 
1572         instance->m_pFinalDSI =
1573             (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(instance->m_decoderSpecificInfoSize,
1574             M4MCS, (M4OSA_Char *)"instance->m_pFinalDSI");
1575 
1576         if( instance->m_pFinalDSI == M4OSA_NULL )
1577         {
1578             M4OSA_TRACE1_0("instance->m_pFinalDSI: allocation error");
1579             return M4ERR_ALLOC;
1580         }
1581 
1582         instance->m_pFinalDSISize = instance->m_decoderSpecificInfoSize;
1583         memcpy((void *)instance->m_pFinalDSI,
1584             (void *)instance->m_pDecoderSpecificInfo,
1585             instance->m_decoderSpecificInfoSize);
1586     }
1587     else
1588     {
1589         /* ADD PPS */
1590         /* find the free PPS ID */
1591 
1592         cnt = 0;
1593 
1594         while( Clip_UsedPPSID[cnt] )
1595         {
1596             cnt++;
1597         }
1598         instance->final_PPS_ID = cnt;
1599 
1600         size = instance->m_decoderSpecificInfoSize + instance->m_encoderPPSSize
1601             + 10;
1602 
1603         instance->m_pFinalDSI = (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(size, M4MCS,
1604             (M4OSA_Char *)"instance->m_pFinalDSI");
1605 
1606         if( instance->m_pFinalDSI == M4OSA_NULL )
1607         {
1608             M4OSA_TRACE1_0("instance->m_pFinalDSI: allocation error");
1609             return M4ERR_ALLOC;
1610         }
1611 
1612         memcpy((void *)instance->m_pFinalDSI,
1613             (void *)instance->m_pDecoderSpecificInfo,
1614             instance->m_decoderSpecificInfoSize);
1615 
1616         temp = instance->m_pFinalDSI[lClipDSI_PPS_offset];
1617         temp = temp + 1;
1618         instance->m_pFinalDSI[lClipDSI_PPS_offset] = temp;
1619 
1620         //temp = instance->m_pEncoderPPS[0];
1621         lSize1 = instance->m_encoderPPSSize - 1;
1622         p_bs1->Buffer = (M4OSA_UInt8 *)(instance->m_pEncoderPPS + 1);
1623         DecBitStreamReset_MCS(p_bs1, lSize1);
1624 
1625         lEncoder_PPSID = H264MCS_DecVLCReadExpGolombCode(p_bs1);
1626         lEncoder_SPSID = H264MCS_DecVLCReadExpGolombCode(p_bs1);
1627 
1628         lEncoderPPSRemBits = ( lSize1) << 3;
1629         lEncoderPPSRemBits -= p_bs1->bitPos;
1630 
1631         temp = instance->m_pEncoderPPS[lSize1];
1632 
1633         cnt1 = 0;
1634 
1635         while( ( temp & 0x1) == 0 )
1636         {
1637             cnt1++;
1638             temp = temp >> 1;
1639         }
1640         cnt1++;
1641         lEncoderPPSRemBits -= cnt1;
1642 
1643         instance->m_pFinalDSI[instance->m_decoderSpecificInfoSize + 2] =
1644             instance->m_pEncoderPPS[0];
1645 
1646         NSWAVCMCS_initBitstream(&instance->encbs);
1647         instance->encbs.streamBuffer =
1648             &(instance->m_pFinalDSI[instance->m_decoderSpecificInfoSize + 3]);
1649         lPPS_Buffer = instance->encbs.streamBuffer;
1650 
1651         NSWAVCMCS_uExpVLC(&instance->encbs, instance->final_PPS_ID);
1652         NSWAVCMCS_uExpVLC(&instance->encbs, instance->final_SPS_ID);
1653 
1654         while( lEncoderPPSRemBits > 8 )
1655         {
1656             temp = H264MCS_getBits(p_bs1, 8);
1657             NSWAVCMCS_putBits(&instance->encbs, temp, 8);
1658             lEncoderPPSRemBits = lEncoderPPSRemBits - 8;
1659         }
1660 
1661         if( lEncoderPPSRemBits )
1662         {
1663             temp = H264MCS_getBits(p_bs1, lEncoderPPSRemBits);
1664             NSWAVCMCS_putBits(&instance->encbs, temp, lEncoderPPSRemBits);
1665         }
1666         NSWAVCMCS_putRbspTbits(&instance->encbs);
1667 
1668         temp = instance->encbs.byteCnt;
1669         lPPS_Buffer_Size = temp;
1670         temp = temp + 1;
1671 
1672         instance->m_pFinalDSI[instance->m_decoderSpecificInfoSize] =
1673             ( temp >> 8) & 0xFF;
1674         instance->m_pFinalDSI[instance->m_decoderSpecificInfoSize + 1] =
1675             (temp) &0xFF;
1676         instance->m_pFinalDSISize =
1677             instance->m_decoderSpecificInfoSize + 2 + temp;
1678     }
1679 
1680     /* Decode the clip SPS */
1681 
1682     lClipDSI = instance->m_pDecoderSpecificInfo + 6;
1683 
1684     lClipDSI_PPS_offset = 6;
1685 
1686     for ( cnt = 0; cnt < instance->m_encoder_SPS_Cnt; cnt++ )
1687     {
1688         lSize = ( lClipDSI[0] << 8) + lClipDSI[1];
1689         lClipDSI = lClipDSI + 2;
1690 
1691         if( Clip_SPSID[cnt] == instance->final_SPS_ID )
1692         {
1693             p_bs->Buffer = (M4OSA_UInt8 *)(lClipDSI + 1);
1694             DecBitStreamReset_MCS(p_bs, lSize - 1);
1695 
1696             err = DecSPSMCS(p_bs, &instance->clip_sps);
1697             if(err != M4NO_ERROR) {
1698                 return M4ERR_PARAMETER;
1699             }
1700 
1701             //Clip_SPSID[cnt] = H264MCS_DecVLCReadExpGolombCode(p_bs);
1702             //Clip_UsedSPSID[Clip_SPSID[cnt]] = 1;
1703             break;
1704         }
1705 
1706         lClipDSI = lClipDSI + lSize;
1707     }
1708 
1709     /* Decode encoder SPS */
1710     p_bs->Buffer = (M4OSA_UInt8 *)(instance->m_pEncoderSPS + 1);
1711     DecBitStreamReset_MCS(p_bs, instance->m_encoderSPSSize - 1);
1712     err = DecSPSMCS(p_bs, &instance->encoder_sps);
1713     if(err != M4NO_ERROR) {
1714         return M4ERR_PARAMETER;
1715     }
1716 
1717     if( instance->encoder_sps.num_ref_frames
1718     > instance->clip_sps.num_ref_frames )
1719     {
1720         return 100; //not supported
1721     }
1722 
1723     p_bs->Buffer = (M4OSA_UInt8 *)lPPS_Buffer;
1724     DecBitStreamReset_MCS(p_bs, lPPS_Buffer_Size);
1725     DecPPSMCS(p_bs, &instance->encoder_pps);
1726 
1727     instance->frame_count = 0;
1728     instance->frame_mod_count =
1729         1 << (instance->clip_sps.log2_max_frame_num_minus4 + 4);
1730 
1731     instance->POC_lsb = 0;
1732     instance->POC_lsb_mod =
1733         1 << (instance->clip_sps.log2_max_pic_order_cnt_lsb_minus4 + 4);
1734 
1735     return M4NO_ERROR;
1736 }
1737 
H264MCS_ProcessNALU(NSWAVC_MCS_t * ainstance,M4OSA_UInt8 * inbuff,M4OSA_Int32 inbuf_size,M4OSA_UInt8 * outbuff,M4OSA_Int32 * outbuf_size)1738 M4OSA_ERR H264MCS_ProcessNALU( NSWAVC_MCS_t *ainstance, M4OSA_UInt8 *inbuff,
1739                                M4OSA_Int32 inbuf_size, M4OSA_UInt8 *outbuff,
1740                                M4OSA_Int32 *outbuf_size )
1741 {
1742     ComBitStreamMCS_t *p_bs, bs;
1743     NSWAVC_MCS_t *instance;
1744     M4OSA_UInt8 nalu_info;
1745     M4OSA_Int32 forbidden_bit, nal_ref_idc, nal_unit_type;
1746     M4OSA_Int32 first_mb_in_slice, slice_type, pic_parameter_set_id, frame_num;
1747     M4OSA_Int32 seq_parameter_set_id;
1748     M4OSA_UInt8 temp1, temp2, temp3, temp4;
1749     M4OSA_Int32 temp_frame_num;
1750     M4OSA_Int32 bitstoDiacard, bytes;
1751     M4OSA_UInt32 mask_bits = 0xFFFFFFFF;
1752     M4OSA_Int32 new_bytes, init_bit_pos;
1753     M4OSA_UInt32 nal_size;
1754     M4OSA_UInt32 cnt;
1755     M4OSA_UInt32 outbuffpos = 0;
1756     //#ifndef DGR_FIX // + new
1757     M4OSA_UInt32 nal_size_low16, nal_size_high16;
1758     //#endif // + end new
1759     M4OSA_UInt32 frame_size = 0;
1760     M4OSA_UInt32 temp = 0;
1761     M4OSA_ERR err = M4NO_ERROR;
1762     M4OSA_UInt8 *buff;
1763 
1764     p_bs = &bs;
1765     instance = (NSWAVC_MCS_t *)ainstance;
1766     M4OSA_DEBUG_IF2((M4OSA_NULL == instance), M4ERR_PARAMETER,
1767         "H264MCS_ProcessNALU: instance is M4OSA_NULL");
1768 
1769     if( instance->is_done )
1770         return err;
1771 
1772     inbuff[0] = 0x00;
1773     inbuff[1] = 0x00;
1774     inbuff[2] = 0x00;
1775     inbuff[3] = 0x01;
1776 
1777 
1778     while( (M4OSA_Int32)frame_size < inbuf_size )
1779     {
1780         mask_bits = 0xFFFFFFFF;
1781         p_bs->Buffer = (M4OSA_UInt8 *)(inbuff + frame_size);
1782 
1783 
1784         nalu_info = (unsigned char)p_bs->Buffer[4];
1785 
1786         outbuff[outbuffpos] = p_bs->Buffer[0];
1787         outbuff[outbuffpos + 1] = p_bs->Buffer[1];
1788         outbuff[outbuffpos + 2] = p_bs->Buffer[2];
1789         outbuff[outbuffpos + 3] = p_bs->Buffer[3];
1790         outbuff[outbuffpos + 4] = p_bs->Buffer[4];
1791 
1792         p_bs->Buffer = p_bs->Buffer + 5;
1793 
1794         p_bs->bitPos = 0;
1795         p_bs->lastTotalBits = 0;
1796         p_bs->numBitsInBuffer = ( inbuf_size - frame_size - 5) << 3;
1797         p_bs->readableBytesInBuffer = inbuf_size - frame_size - 5;
1798 
1799         p_bs->ui32TempBuff = 0;
1800         p_bs->i8BitCnt = 0;
1801         p_bs->pui8BfrPtr = (M4OSA_Int8 *)p_bs->Buffer;
1802         p_bs->ui32LastTwoBytes = 0xFFFFFFFF;
1803 
1804         H264MCS_getBits(p_bs, 0);
1805 
1806 
1807 
1808         nal_size = inbuf_size - frame_size - 4;
1809         buff = inbuff + frame_size + 4;
1810 
1811         while( nal_size > 4 )
1812         {
1813             if( ( buff[0] == 0x00) && (buff[1] == 0x00) && (buff[2] == 0x00)
1814                 && (buff[3] == 0x01) )
1815             {
1816                 break;
1817             }
1818             buff = buff + 1;
1819             nal_size = nal_size - 1;
1820         }
1821 
1822         if( nal_size <= 4 )
1823         {
1824             nal_size = 0;
1825         }
1826         nal_size = ( inbuf_size - frame_size - 4) - nal_size;
1827 
1828         //      M4OSA_TRACE1_3("H264MCS_ProcessNALU frame  input buff size = %d  current position
1829         //= %d   nal size = %d",
1830         //  inbuf_size, frame_size,  nal_size + 4);
1831         frame_size += nal_size + 4;
1832 
1833 
1834 
1835         forbidden_bit = ( nalu_info >> 7) & 1;
1836         nal_ref_idc = ( nalu_info >> 5) & 3;
1837         nal_unit_type = (nalu_info) &0x1f;
1838 
1839         if( nal_unit_type == 5 )
1840         {
1841             /*IDR/PPS Packet - Do nothing*/
1842             instance->is_done = 1;
1843             return err;
1844         }
1845 
1846         NSWAVCMCS_initBitstream(&instance->encbs);
1847         instance->encbs.streamBuffer = outbuff + outbuffpos + 5;
1848 
1849         if( nal_unit_type == 8 )
1850         {
1851             M4OSA_TRACE1_0("H264MCS_ProcessNALU() Error: PPS");
1852             return err;
1853         }
1854 
1855         if( nal_unit_type == 7 )
1856         {
1857             /*SPS Packet */
1858             M4OSA_TRACE1_0("H264MCS_ProcessNALU() Error: SPS");
1859             return 0;
1860         }
1861 
1862         if( (nal_unit_type == 5) )
1863         {
1864             instance->frame_count = 0;
1865             instance->POC_lsb = 0;
1866         }
1867 
1868         if( (nal_unit_type == 1) )
1869         {
1870             first_mb_in_slice = H264MCS_DecVLCReadExpGolombCode(p_bs);
1871             NSWAVCMCS_uExpVLC(&instance->encbs, first_mb_in_slice);
1872 
1873             slice_type = H264MCS_DecVLCReadExpGolombCode(p_bs);
1874             NSWAVCMCS_uExpVLC(&instance->encbs, slice_type);
1875 
1876             pic_parameter_set_id = H264MCS_DecVLCReadExpGolombCode(p_bs);
1877             NSWAVCMCS_uExpVLC(&instance->encbs, pic_parameter_set_id);
1878 
1879             temp = H264MCS_getBits(p_bs,
1880                 instance->clip_sps.log2_max_frame_num_minus4 + 4);
1881             NSWAVCMCS_putBits(&instance->encbs, instance->frame_count,
1882                 instance->clip_sps.log2_max_frame_num_minus4 + 4);
1883 
1884             // In Baseline Profile: frame_mbs_only_flag should be ON
1885 
1886             if( nal_unit_type == 5 )
1887             {
1888                 temp = H264MCS_DecVLCReadExpGolombCode(p_bs);
1889                 NSWAVCMCS_uExpVLC(&instance->encbs, temp);
1890             }
1891 
1892             if( instance->clip_sps.pic_order_cnt_type == 0 )
1893             {
1894                 temp = H264MCS_getBits(p_bs,
1895                     instance->clip_sps.log2_max_pic_order_cnt_lsb_minus4
1896                     + 4);
1897                 NSWAVCMCS_putBits(&instance->encbs, instance->POC_lsb,
1898                     instance->clip_sps.log2_max_pic_order_cnt_lsb_minus4 + 4);
1899             }
1900 
1901             if( ( instance->clip_sps.pic_order_cnt_type == 1)
1902                 && (instance->clip_sps.delta_pic_order_always_zero_flag) )
1903             {
1904                 temp = H264MCS_DecVLCReadSignedExpGolombCode(p_bs);
1905                 NSWAVCMCS_sExpVLC(&instance->encbs, temp);
1906             }
1907 
1908             cnt = p_bs->bitPos & 0x7;
1909 
1910             if( cnt )
1911             {
1912                 cnt = 8 - cnt;
1913                 temp = H264MCS_getBits(p_bs, cnt);
1914                 NSWAVCMCS_putBits(&instance->encbs, temp, cnt);
1915             }
1916 
1917             cnt = p_bs->bitPos >> 3;
1918 
1919             while( cnt < (nal_size - 2) )
1920             {
1921                 temp = H264MCS_getBits(p_bs, 8);
1922                 NSWAVCMCS_putBits(&instance->encbs, temp, 8);
1923                 cnt = p_bs->bitPos >> 3;
1924             }
1925 
1926             temp = H264MCS_getBits(p_bs, 8);
1927 
1928             if( temp != 0 )
1929             {
1930                 cnt = 0;
1931 
1932                 while( ( temp & 0x1) == 0 )
1933                 {
1934                     cnt++;
1935                     temp = temp >> 1;
1936                 }
1937                 cnt++;
1938                 temp = temp >> 1;
1939 
1940                 if( 8 - cnt )
1941                 {
1942                     NSWAVCMCS_putBits(&instance->encbs, temp, (8 - cnt));
1943                 }
1944 
1945                 NSWAVCMCS_putRbspTbits(&instance->encbs);
1946             }
1947             else
1948             {
1949                 if( instance->encbs.bitPos % 8 )
1950                 {
1951                     NSWAVCMCS_putBits(&instance->encbs, 0,
1952                         (8 - instance->encbs.bitPos % 8));
1953                 }
1954             }
1955 
1956             temp = instance->encbs.byteCnt;
1957             temp = temp + 1;
1958 
1959             outbuff[outbuffpos] = (M4OSA_UInt8)(( temp >> 24) & 0xFF);
1960             outbuff[outbuffpos + 1] = (M4OSA_UInt8)(( temp >> 16) & 0xFF);
1961             outbuff[outbuffpos + 2] = (M4OSA_UInt8)(( temp >> 8) & 0xFF);
1962             outbuff[outbuffpos + 3] = (M4OSA_UInt8)((temp) &0xFF);
1963             outbuffpos = outbuffpos + temp + 4;
1964         }
1965         else
1966         {
1967             p_bs->Buffer = p_bs->Buffer - 5;
1968             memcpy((void *) &outbuff[outbuffpos],
1969                 (void *)p_bs->Buffer, nal_size + 4);
1970 
1971             outbuff[outbuffpos] = (M4OSA_UInt8)((nal_size >> 24)& 0xFF);
1972         outbuff[outbuffpos + 1] = (M4OSA_UInt8)((nal_size >> 16)& 0xFF);;
1973         outbuff[outbuffpos + 2] = (M4OSA_UInt8)((nal_size >> 8)& 0xFF);;
1974         outbuff[outbuffpos + 3] = (M4OSA_UInt8)((nal_size)& 0xFF);;
1975 
1976             outbuffpos = outbuffpos + nal_size + 4;
1977         }
1978     }
1979 
1980     *outbuf_size = outbuffpos;
1981 
1982     instance->POC_lsb = instance->POC_lsb + 1;
1983 
1984     if( instance->POC_lsb == instance->POC_lsb_mod )
1985     {
1986         instance->POC_lsb = 0;
1987     }
1988     instance->frame_count = instance->frame_count + 1;
1989 
1990     if( instance->frame_count == instance->frame_mod_count )
1991     {
1992         instance->frame_count = 0;
1993     }
1994     return M4NO_ERROR;
1995 }
1996 
M4MCS_convetFromByteStreamtoNALStream(M4OSA_UInt8 * inbuff,M4OSA_UInt32 inbuf_size)1997 M4OSA_ERR   M4MCS_convetFromByteStreamtoNALStream(  M4OSA_UInt8 *inbuff,
1998                                                     M4OSA_UInt32 inbuf_size )
1999 {
2000     M4OSA_ERR err = M4NO_ERROR;
2001     M4OSA_UInt32 framesize = 0;
2002     M4OSA_UInt32 nal_size =0;
2003     M4OSA_UInt8 *buff;
2004 
2005 
2006     while(framesize < inbuf_size)
2007     {
2008             nal_size = inbuf_size - framesize - 4;
2009             buff =  inbuff + framesize + 4;
2010 
2011             while(nal_size > 4){
2012                 if((buff[0] == 0x00) &&
2013                 (buff[1] == 0x00) &&
2014                 (buff[2] == 0x00) &&
2015                 (buff[3] == 0x01)){
2016                     break;
2017                 }
2018                 buff = buff + 1;
2019                 nal_size = nal_size -1;
2020             }
2021 
2022             if(nal_size <= 4){
2023                 nal_size = 0;
2024             }
2025             nal_size = (inbuf_size - framesize - 4) - nal_size;
2026 
2027         inbuff[framesize + 0]  = (M4OSA_UInt8)((nal_size >> 24)& 0xFF);
2028         inbuff[framesize + 1]  = (M4OSA_UInt8)((nal_size >> 16)& 0xFF);
2029         inbuff[framesize + 2]  = (M4OSA_UInt8)((nal_size >> 8)& 0xFF);
2030         inbuff[framesize + 3]  = (M4OSA_UInt8)((nal_size )& 0xFF);
2031         framesize += nal_size + 4;
2032 
2033         M4OSA_TRACE1_2("M4MCS_convetFromByteStreamtoNALStream framesize = %x nalsize = %x",
2034             framesize, nal_size)
2035     }
2036 
2037     return  err;
2038 }
2039 
2040 
H264MCS_Freeinstance(NSWAVC_MCS_t * instance)2041 M4OSA_ERR H264MCS_Freeinstance( NSWAVC_MCS_t *instance )
2042 {
2043     M4OSA_ERR err = M4NO_ERROR;
2044     M4OSA_DEBUG_IF2((M4OSA_NULL == instance), M4ERR_PARAMETER,
2045         "H264MCS_Freeinstance: instance is M4OSA_NULL");
2046 
2047     if( M4OSA_NULL != instance->encoder_pps.slice_group_id )
2048     {
2049         free(instance->encoder_pps.slice_group_id);
2050     }
2051 
2052     if( M4OSA_NULL != instance->p_encoder_sps )
2053     {
2054         free(instance->p_encoder_sps);
2055         instance->p_encoder_sps = M4OSA_NULL;
2056     }
2057 
2058     if( M4OSA_NULL != instance->p_encoder_pps )
2059     {
2060         free(instance->p_encoder_pps);
2061         instance->p_encoder_pps = M4OSA_NULL;
2062     }
2063 
2064     if( M4OSA_NULL != instance->m_pFinalDSI )
2065     {
2066         free(instance->m_pFinalDSI);
2067         instance->m_pFinalDSI = M4OSA_NULL;
2068     }
2069 
2070     if( M4OSA_NULL != instance )
2071     {
2072         free(instance);
2073         instance = M4OSA_NULL;
2074     }
2075 
2076     return err;
2077 }
2078 /**
2079  ******************************************************************************
2080  * M4OSA_ERR M4MCS_getVersion(M4_VersionInfo* pVersionInfo);
2081  * @brief    Get the MCS version.
2082  * @note Can be called anytime. Do not need any context.
2083  * @param    pVersionInfo        (OUT) Pointer to a version info structure
2084  * @return   M4NO_ERROR:         No error
2085  * @return   M4ERR_PARAMETER:    pVersionInfo is M4OSA_NULL (If Debug Level >= 2)
2086  ******************************************************************************
2087  */
M4MCS_getVersion(M4_VersionInfo * pVersionInfo)2088 M4OSA_ERR M4MCS_getVersion( M4_VersionInfo *pVersionInfo )
2089 {
2090     M4OSA_TRACE3_1("M4MCS_getVersion called with pVersionInfo=0x%x",
2091         pVersionInfo);
2092 
2093     /**
2094     * Check input parameters */
2095     M4OSA_DEBUG_IF2((M4OSA_NULL == pVersionInfo), M4ERR_PARAMETER,
2096         "M4MCS_getVersion: pVersionInfo is M4OSA_NULL");
2097 
2098     pVersionInfo->m_major = M4MCS_VERSION_MAJOR;
2099     pVersionInfo->m_minor = M4MCS_VERSION_MINOR;
2100     pVersionInfo->m_revision = M4MCS_VERSION_REVISION;
2101 
2102     /**
2103     * Return with no error */
2104     M4OSA_TRACE3_0("M4MCS_getVersion(): returning M4NO_ERROR");
2105     return M4NO_ERROR;
2106 }
2107 
2108 /**
2109  ******************************************************************************
2110  * @brief    Initializes the MCS (allocates an execution context).
2111  * @note
2112  * @param    pContext            (OUT) Pointer on the MCS context to allocate
2113  * @param    pFileReadPtrFct     (IN) Pointer to OSAL file reader functions
2114  * @param    pFileWritePtrFct    (IN) Pointer to OSAL file writer functions
2115  * @return   M4NO_ERROR:         No error
2116  * @return   M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (If Debug Level >= 2)
2117  * @return   M4ERR_ALLOC:        There is no more available memory
2118  ******************************************************************************
2119  */
2120 
M4MCS_init(M4MCS_Context * pContext,M4OSA_FileReadPointer * pFileReadPtrFct,M4OSA_FileWriterPointer * pFileWritePtrFct)2121 M4OSA_ERR M4MCS_init( M4MCS_Context *pContext,
2122                      M4OSA_FileReadPointer *pFileReadPtrFct,
2123                      M4OSA_FileWriterPointer *pFileWritePtrFct )
2124 {
2125     M4MCS_InternalContext *pC = M4OSA_NULL;
2126     M4OSA_ERR err;
2127 
2128     M4OSA_TRACE3_3(
2129         "M4MCS_init called with pContext=0x%x, pFileReadPtrFct=0x%x, pFileWritePtrFct=0x%x",
2130         pContext, pFileReadPtrFct, pFileWritePtrFct);
2131 
2132     /**
2133     * Check input parameters */
2134     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
2135         "M4MCS_init: pContext is M4OSA_NULL");
2136     M4OSA_DEBUG_IF2((M4OSA_NULL == pFileReadPtrFct), M4ERR_PARAMETER,
2137         "M4MCS_init: pFileReadPtrFct is M4OSA_NULL");
2138     M4OSA_DEBUG_IF2((M4OSA_NULL == pFileWritePtrFct), M4ERR_PARAMETER,
2139         "M4MCS_init: pFileWritePtrFct is M4OSA_NULL");
2140 
2141     /**
2142     * Allocate the MCS context and return it to the user */
2143     pC = (M4MCS_InternalContext *)M4OSA_32bitAlignedMalloc(sizeof(M4MCS_InternalContext),
2144         M4MCS, (M4OSA_Char *)"M4MCS_InternalContext");
2145     *pContext = pC;
2146 
2147     if( M4OSA_NULL == pC )
2148     {
2149         M4OSA_TRACE1_0(
2150             "M4MCS_init(): unable to allocate M4MCS_InternalContext, returning M4ERR_ALLOC");
2151         return M4ERR_ALLOC;
2152     }
2153 
2154     /**
2155     * Init the context. All pointers must be initialized to M4OSA_NULL
2156     * because CleanUp() can be called just after Init(). */
2157     pC->State = M4MCS_kState_CREATED;
2158     pC->pOsaFileReadPtr = pFileReadPtrFct;
2159     pC->pOsaFileWritPtr = pFileWritePtrFct;
2160     pC->VideoState = M4MCS_kStreamState_NOSTREAM;
2161     pC->AudioState = M4MCS_kStreamState_NOSTREAM;
2162     pC->noaudio = M4OSA_FALSE;
2163     pC->novideo = M4OSA_FALSE;
2164     pC->uiProgress = 0;
2165 
2166     /**
2167     * Reader stuff */
2168     pC->pInputFile = M4OSA_NULL;
2169     pC->InputFileType = M4VIDEOEDITING_kFileType_Unsupported;
2170     pC->bFileOpenedInFastMode = M4OSA_FALSE;
2171     pC->pReaderContext = M4OSA_NULL;
2172     pC->pReaderVideoStream = M4OSA_NULL;
2173     pC->pReaderAudioStream = M4OSA_NULL;
2174     pC->bUnsupportedVideoFound = M4OSA_FALSE;
2175     pC->bUnsupportedAudioFound = M4OSA_FALSE;
2176     pC->iAudioCtsOffset = 0;
2177     /* First temporary video AU to have more precise end video cut*/
2178     pC->ReaderVideoAU1.m_structSize = 0;
2179     /* Second temporary video AU to have more precise end video cut*/
2180     pC->ReaderVideoAU2.m_structSize = 0;
2181     pC->ReaderAudioAU1.m_structSize = 0;
2182     pC->ReaderAudioAU2.m_structSize = 0;
2183     pC->m_audioAUDuration = 0;
2184     pC->m_pDataAddress1 = M4OSA_NULL;
2185     pC->m_pDataAddress2 = M4OSA_NULL;
2186     /* First temporary video AU data to have more precise end video cut*/
2187     pC->m_pDataVideoAddress1 = M4OSA_NULL;
2188     /* Second temporary video AU data to have more precise end video cut*/
2189     pC->m_pDataVideoAddress2 = M4OSA_NULL;
2190 
2191     /**
2192     * Video decoder stuff */
2193     pC->pViDecCtxt = M4OSA_NULL;
2194     pC->dViDecStartingCts = 0.0;
2195     pC->iVideoBeginDecIncr = 0;
2196     pC->dViDecCurrentCts = 0.0;
2197     pC->dCtsIncrement = 0.0;
2198     pC->isRenderDup = M4OSA_FALSE;
2199 
2200     /**
2201     * Video encoder stuff */
2202     pC->pViEncCtxt = M4OSA_NULL;
2203     pC->pPreResizeFrame = M4OSA_NULL;
2204     pC->uiEncVideoBitrate = 0;
2205     pC->encoderState = M4MCS_kNoEncoder;
2206 
2207     /**
2208     * Audio decoder stuff */
2209     pC->pAudioDecCtxt = M4OSA_NULL;
2210     pC->AudioDecBufferIn.m_dataAddress = M4OSA_NULL;
2211     pC->AudioDecBufferIn.m_bufferSize = 0;
2212     pC->AudioDecBufferOut.m_dataAddress = M4OSA_NULL;
2213     pC->AudioDecBufferOut.m_bufferSize = 0;
2214     pC->pPosInDecBufferOut = M4OSA_NULL;
2215     /**
2216     * Ssrc stuff */
2217     pC->pSsrcBufferIn = M4OSA_NULL;
2218     pC->pSsrcBufferOut = M4OSA_NULL;
2219     pC->pPosInSsrcBufferIn = M4OSA_NULL;
2220     pC->pPosInSsrcBufferOut = M4OSA_NULL;
2221     pC->iSsrcNbSamplIn = 0;
2222     pC->iSsrcNbSamplOut = 0;
2223     pC->SsrcScratch = M4OSA_NULL;
2224     pC->pLVAudioResampler = M4OSA_NULL;
2225     /**
2226     * Audio encoder */
2227     pC->pAudioEncCtxt = M4OSA_NULL;
2228     pC->pAudioEncDSI.infoSize = 0;
2229     pC->pAudioEncDSI.pInfo = M4OSA_NULL;
2230     pC->pAudioEncoderBuffer = M4OSA_NULL;
2231     pC->pPosInAudioEncoderBuffer = M4OSA_NULL;
2232     pC->audioEncoderGranularity = 0;
2233 
2234     /**
2235     * Writer stuff */
2236     pC->pOutputFile = M4OSA_NULL;
2237     pC->pTemporaryFile = M4OSA_NULL;
2238     pC->pWriterContext = M4OSA_NULL;
2239     pC->uiVideoAUCount = 0;
2240     pC->uiVideoMaxAuSize = 0;
2241     pC->uiVideoMaxChunckSize = 0;
2242     pC->uiAudioAUCount = 0;
2243     pC->uiAudioMaxAuSize = 0;
2244 
2245     pC->uiAudioCts = 0;
2246     pC->b_isRawWriter = M4OSA_FALSE;
2247     pC->pOutputPCMfile = M4OSA_NULL;
2248 
2249     /* Encoding config */
2250     pC->EncodingVideoFormat = M4ENCODER_kNULL; /**< No format set yet */
2251     pC->EncodingWidth = 0;                     /**< No size set yet */
2252     pC->EncodingHeight = 0;                    /**< No size set yet */
2253     pC->EncodingVideoFramerate = 0;            /**< No framerate set yet */
2254 
2255     pC->uiBeginCutTime = 0;                    /**< No begin cut */
2256     pC->uiEndCutTime = 0;                      /**< No end cut */
2257     pC->uiMaxFileSize = 0;                     /**< No limit */
2258     pC->uiAudioBitrate =
2259         M4VIDEOEDITING_kUndefinedBitrate; /**< No bitrate set yet */
2260     pC->uiVideoBitrate =
2261         M4VIDEOEDITING_kUndefinedBitrate; /**< No bitrate set yet */
2262 
2263     pC->WriterVideoStream.streamType = M4SYS_kVideoUnknown;
2264     pC->WriterVideoStreamInfo.Header.pBuf = M4OSA_NULL;
2265     pC->WriterAudioStream.streamType = M4SYS_kAudioUnknown;
2266 
2267     pC->outputVideoTimescale = 0;
2268 
2269     /*FB 2008/10/20: add media rendering parameter and AIR context to keep media aspect ratio*/
2270     pC->MediaRendering = M4MCS_kResizing;
2271     pC->m_air_context = M4OSA_NULL;
2272     /**/
2273 
2274     /**
2275     * FlB 2009.03.04: add audio Effects*/
2276     pC->pEffects = M4OSA_NULL;
2277     pC->nbEffects = 0;
2278     pC->pActiveEffectNumber = -1;
2279     /**/
2280 
2281     /*
2282     * Reset pointers for media and codecs interfaces */
2283     err = M4MCS_clearInterfaceTables(pC);
2284     M4ERR_CHECK_RETURN(err);
2285 
2286     /*
2287     *  Call the media and codecs subscription module */
2288     err = M4MCS_subscribeMediaAndCodec(pC);
2289     M4ERR_CHECK_RETURN(err);
2290 
2291 #ifdef M4MCS_SUPPORT_STILL_PICTURE
2292     /**
2293     * Initialize the Still picture part of MCS*/
2294 
2295     err = M4MCS_stillPicInit(pC, pFileReadPtrFct, pFileWritePtrFct);
2296     M4ERR_CHECK_RETURN(err);
2297 
2298     pC->m_bIsStillPicture = M4OSA_FALSE;
2299 
2300 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
2301 
2302     pC->m_pInstance = M4OSA_NULL;
2303     pC->H264MCSTempBuffer = M4OSA_NULL;
2304     pC->H264MCSTempBufferSize = 0;
2305     pC->H264MCSTempBufferDataSize = 0;
2306     pC->bH264Trim = M4OSA_FALSE;
2307 
2308     /* Flag to get the last decoded frame cts */
2309     pC->bLastDecodedFrameCTS = M4OSA_FALSE;
2310 
2311     if( pC->m_pInstance == M4OSA_NULL )
2312     {
2313         err = H264MCS_Getinstance(&pC->m_pInstance);
2314     }
2315     pC->bExtOMXAudDecoder = M4OSA_FALSE;
2316 
2317     /**
2318     * Return with no error */
2319     M4OSA_TRACE3_0("M4MCS_init(): returning M4NO_ERROR");
2320     return M4NO_ERROR;
2321 }
2322 
2323 /**
2324  ******************************************************************************
2325  * M4OSA_ERR M4MCS_open(M4MCS_Context pContext, M4OSA_Void* pFileIn,
2326  *                         M4OSA_Void* pFileOut, M4OSA_Void* pTempFile);
2327  * @brief   Set the MCS input and output files.
2328  * @note    It opens the input file, but the output file is not created yet.
2329  * @param   pContext            (IN) MCS context
2330  * @param   pFileIn             (IN) Input file to transcode (The type of this parameter
2331  *                                 (URL, pipe...) depends on the OSAL implementation).
2332  * @param   mediaType           (IN) Container type (.3gp,.amr,mp3 ...) of input file.
2333  * @param   pFileOut            (IN) Output file to create  (The type of this parameter
2334  *                                    (URL, pipe...) depends on the OSAL implementation).
2335  * @param   pTempFile           (IN) Temporary file for the constant memory writer to
2336  *                                     store metadata ("moov.bin").
2337  * @return  M4NO_ERROR:         No error
2338  * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
2339  * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
2340  * @return  M4ERR_ALLOC:        There is no more available memory
2341  * @return  M4ERR_FILE_NOT_FOUND:   The input file has not been found
2342  * @return  M4MCS_ERR_INVALID_INPUT_FILE:   The input file is not a valid file, or is corrupted
2343  * @return  M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM:  The input file contains no
2344  *                                supported audio or video stream
2345  ******************************************************************************
2346  */
M4MCS_open(M4MCS_Context pContext,M4OSA_Void * pFileIn,M4VIDEOEDITING_FileType InputFileType,M4OSA_Void * pFileOut,M4OSA_Void * pTempFile)2347 M4OSA_ERR M4MCS_open( M4MCS_Context pContext, M4OSA_Void *pFileIn,
2348                      M4VIDEOEDITING_FileType InputFileType, M4OSA_Void *pFileOut,
2349                      M4OSA_Void *pTempFile )
2350 {
2351     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
2352     M4OSA_ERR err;
2353 
2354     M4READER_MediaFamily mediaFamily;
2355     M4_StreamHandler *pStreamHandler;
2356 
2357     M4OSA_TRACE2_3(
2358         "M4MCS_open called with pContext=0x%x, pFileIn=0x%x, pFileOut=0x%x",
2359         pContext, pFileIn, pFileOut);
2360 
2361     /**
2362     * Check input parameters */
2363     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
2364         "M4MCS_open: pContext is M4OSA_NULL");
2365     M4OSA_DEBUG_IF2((M4OSA_NULL == pFileIn), M4ERR_PARAMETER,
2366         "M4MCS_open: pFileIn is M4OSA_NULL");
2367 
2368     if( ( InputFileType == M4VIDEOEDITING_kFileType_JPG)
2369         || (InputFileType == M4VIDEOEDITING_kFileType_PNG)
2370         || (InputFileType == M4VIDEOEDITING_kFileType_GIF)
2371         || (InputFileType == M4VIDEOEDITING_kFileType_BMP) )
2372     {
2373 #ifdef M4MCS_SUPPORT_STILL_PICTURE
2374         /**
2375         * Indicate that we must use the still picture functions*/
2376 
2377         pC->m_bIsStillPicture = M4OSA_TRUE;
2378 
2379         /**
2380         * Call the still picture MCS functions*/
2381         return M4MCS_stillPicOpen(pC, pFileIn, InputFileType, pFileOut);
2382 
2383 #else
2384 
2385         M4OSA_TRACE1_0(
2386             "M4MCS_open: Still picture is not supported with this version of MCS");
2387         return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM;
2388 
2389 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
2390 
2391     }
2392 
2393     /**
2394     * Check state automaton */
2395     if( M4MCS_kState_CREATED != pC->State )
2396     {
2397         M4OSA_TRACE1_1("M4MCS_open(): Wrong State (%d), returning M4ERR_STATE",
2398             pC->State);
2399         return M4ERR_STATE;
2400     }
2401 
2402     /* Copy function input parameters into our context */
2403     pC->pInputFile = pFileIn;
2404     pC->InputFileType = InputFileType;
2405     pC->pOutputFile = pFileOut;
2406     pC->pTemporaryFile = pTempFile;
2407     pC->uiProgress = 0;
2408 
2409     /***********************************/
2410     /* Open input file with the reader */
2411     /***********************************/
2412 
2413     err = M4MCS_setCurrentReader(pContext, pC->InputFileType);
2414     M4ERR_CHECK_RETURN(err);
2415 
2416     /**
2417     * Reset reader related variables */
2418     pC->VideoState = M4MCS_kStreamState_NOSTREAM;
2419     pC->AudioState = M4MCS_kStreamState_NOSTREAM;
2420     pC->pReaderVideoStream = M4OSA_NULL;
2421     pC->pReaderAudioStream = M4OSA_NULL;
2422 
2423     /*******************************************************/
2424     /* Initializes the reader shell and open the data file */
2425     /*******************************************************/
2426     err = pC->m_pReader->m_pFctCreate(&pC->pReaderContext);
2427 
2428     if( M4NO_ERROR != err )
2429     {
2430         M4OSA_TRACE1_1("M4MCS_open(): m_pReader->m_pFctCreate returns 0x%x",
2431             err);
2432         return err;
2433     }
2434 
2435     /**
2436     * Link the reader interface to the reader context */
2437     pC->m_pReaderDataIt->m_readerContext = pC->pReaderContext;
2438 
2439     /**
2440     * Set the reader shell file access functions */
2441     err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext,
2442         M4READER_kOptionID_SetOsaFileReaderFctsPtr,
2443         (M4OSA_DataOption)pC->pOsaFileReadPtr);
2444 
2445     if( M4NO_ERROR != err )
2446     {
2447         M4OSA_TRACE1_1("M4MCS_open(): m_pReader->m_pFctSetOption returns 0x%x",
2448             err);
2449         return err;
2450     }
2451 
2452 #ifdef M4MCS_WITH_FAST_OPEN
2453 
2454     if( M4OSA_FALSE == pC->bFileOpenedInFastMode )
2455     {
2456         M4OSA_Bool trueValue = M4OSA_TRUE;
2457 
2458         /* For first call use fast open mode */
2459         err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext,
2460             M4READER_3GP_kOptionID_FastOpenMode, &trueValue);
2461 
2462         if( M4NO_ERROR == err )
2463         {
2464             pC->bFileOpenedInFastMode = M4OSA_TRUE;
2465         }
2466         else
2467         {
2468             M4OSA_TRACE1_1(
2469                 "M4MCS_open(): M4READER_3GP_kOptionID_FastOpenMode returns 0x%x",
2470                 err);
2471 
2472             if( ( ( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID) == err)
2473                 || (( (M4OSA_UInt32)M4ERR_PARAMETER) == err) )
2474             {
2475                 /* Not fatal, some readers may not support fast open mode */
2476                 pC->bFileOpenedInFastMode = M4OSA_FALSE;
2477             }
2478             else
2479                 return err;
2480         }
2481     }
2482     else
2483     {
2484         M4OSA_Bool falseValue = M4OSA_FALSE;
2485 
2486         /* For second call use normal open mode */
2487         err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext,
2488             M4READER_3GP_kOptionID_FastOpenMode, &falseValue);
2489     }
2490 
2491 #endif /* M4MCS_WITH_FAST_OPEN */
2492 
2493     /**
2494     * Open the input file */
2495 
2496     err = pC->m_pReader->m_pFctOpen(pC->pReaderContext, pC->pInputFile);
2497 
2498     if( M4NO_ERROR != err )
2499     {
2500         M4OSA_UInt32 uiDummy, uiCoreId;
2501         M4OSA_TRACE1_1("M4MCS_open(): m_pReader->m_pFctOpen returns 0x%x", err);
2502 
2503         /**
2504         * If the error is from the core reader, we change it to a public VXS error */
2505         M4OSA_ERR_SPLIT(err, uiDummy, uiCoreId, uiDummy);
2506 
2507         if( M4MP4_READER == uiCoreId )
2508         {
2509             M4OSA_TRACE1_0(
2510                 "M4MCS_open(): returning M4MCS_ERR_INVALID_INPUT_FILE");
2511             return M4MCS_ERR_INVALID_INPUT_FILE;
2512         }
2513         return err;
2514     }
2515 
2516     /**
2517     * Get the streams from the input file */
2518     while( M4NO_ERROR == err )
2519     {
2520         err =
2521             pC->m_pReader->m_pFctGetNextStream( pC->pReaderContext,
2522                                                 &mediaFamily,
2523                                                 &pStreamHandler);
2524 
2525         /**
2526         * In case we found a BIFS stream or something else...*/
2527         if( ( err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE))
2528             || (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS)) )
2529         {
2530             err = M4NO_ERROR;
2531             continue;
2532         }
2533 
2534         if( M4NO_ERROR == err ) /**< One stream found */
2535         {
2536             /**
2537             * Found the first video stream */
2538             if( ( M4READER_kMediaFamilyVideo == mediaFamily)
2539                 && (M4OSA_NULL == pC->pReaderVideoStream) )
2540             {
2541                 if( ( M4DA_StreamTypeVideoH263 == pStreamHandler->m_streamType)
2542                     || (M4DA_StreamTypeVideoMpeg4
2543                     == pStreamHandler->m_streamType)
2544                     || (M4DA_StreamTypeVideoMpeg4Avc
2545                     == pStreamHandler->m_streamType) )
2546                 {
2547                     M4OSA_TRACE3_0(
2548                         "M4MCS_open(): Found a H263 or MPEG-4 video stream in input 3gpp clip");
2549 
2550                     /**
2551                     * Keep pointer to the video stream */
2552                     pC->pReaderVideoStream =
2553                         (M4_VideoStreamHandler *)pStreamHandler;
2554                     pC->bUnsupportedVideoFound = M4OSA_FALSE;
2555                     pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
2556 
2557                     /**
2558                     * Init our video stream state variable */
2559                     pC->VideoState = M4MCS_kStreamState_STARTED;
2560 
2561                     /**
2562                     * Reset the stream reader */
2563                     err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
2564                         (M4_StreamHandler *)pC->pReaderVideoStream);
2565 
2566                     if( M4NO_ERROR != err )
2567                     {
2568                         M4OSA_TRACE1_1(
2569                             "M4MCS_open():\
2570                             m_pReader->m_pFctReset(video) returns 0x%x",
2571                             err);
2572                         return err;
2573                     }
2574 
2575                     /**
2576                     * Initializes an access Unit */
2577                     err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
2578                         pStreamHandler, &pC->ReaderVideoAU);
2579 
2580                     if( M4NO_ERROR != err )
2581                     {
2582                         M4OSA_TRACE1_1(
2583                             "M4MCS_open():\
2584                             m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
2585                             err);
2586                         return err;
2587                     }
2588                 }
2589                 else /**< Not H263 or MPEG-4 (H264, etc.) */
2590                 {
2591                     M4OSA_TRACE1_1("M4MCS_open(): Found an unsupported video stream (0x%x) in\
2592                                    input 3gpp clip",
2593                                    pStreamHandler->m_streamType);
2594 
2595                     pC->bUnsupportedVideoFound = M4OSA_TRUE;
2596                     pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
2597                 }
2598                 /* +CRLV6775 -H.264 Trimming */
2599                 if( M4DA_StreamTypeVideoMpeg4Avc
2600                     == pStreamHandler->m_streamType )
2601                 {
2602 
2603                     // SPS and PPS are storead as per the 3gp file format
2604                     pC->m_pInstance->m_pDecoderSpecificInfo =
2605                         pStreamHandler->m_pH264DecoderSpecificInfo;
2606                     pC->m_pInstance->m_decoderSpecificInfoSize =
2607                         pStreamHandler->m_H264decoderSpecificInfoSize;
2608                 }
2609                 /* -CRLV6775 -H.264 Trimming */
2610             }
2611             /**
2612             * Found the first audio stream */
2613             else if( ( M4READER_kMediaFamilyAudio == mediaFamily)
2614                 && (M4OSA_NULL == pC->pReaderAudioStream) )
2615             {
2616                 if( ( M4DA_StreamTypeAudioAmrNarrowBand
2617                     == pStreamHandler->m_streamType)
2618                     || (M4DA_StreamTypeAudioAac == pStreamHandler->m_streamType)
2619                     || (M4DA_StreamTypeAudioMp3
2620                     == pStreamHandler->m_streamType)
2621                     || (M4DA_StreamTypeAudioEvrc
2622                     == pStreamHandler->m_streamType) )
2623                 {
2624                     M4OSA_TRACE3_0(
2625                         "M4MCS_open(): Found an AMR-NB, AAC or MP3 audio stream in input clip");
2626 
2627                     /**
2628                     * Keep pointer to the audio stream */
2629                     pC->pReaderAudioStream =
2630                         (M4_AudioStreamHandler *)pStreamHandler;
2631                     pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
2632                     pC->bUnsupportedAudioFound = M4OSA_FALSE;
2633 
2634                     /**
2635                     * Init our audio stream state variable */
2636                     pC->AudioState = M4MCS_kStreamState_STARTED;
2637 
2638                     /**
2639                     * Reset the stream reader */
2640                     err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
2641                         (M4_StreamHandler *)pC->pReaderAudioStream);
2642 
2643                     if( M4NO_ERROR != err )
2644                     {
2645                         M4OSA_TRACE1_1(
2646                             "M4MCS_open():\
2647                             m_pReader->m_pFctReset(audio) returns 0x%x",
2648                             err);
2649                         return err;
2650                     }
2651 
2652                     /**
2653                     * Initializes an access Unit */
2654                     err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
2655                         pStreamHandler, &pC->ReaderAudioAU);
2656 
2657                     if( M4NO_ERROR != err )
2658                     {
2659                         M4OSA_TRACE1_1(
2660                             "M4MCS_open():\
2661                             m_pReader->m_pFctFillAuStruct(audio) returns 0x%x",
2662                             err);
2663                         return err;
2664                     }
2665 
2666                     /**
2667                     * Output max AU size is equal to input max AU size (this value
2668                     * will be changed if there is audio transcoding) */
2669                     pC->uiAudioMaxAuSize = pStreamHandler->m_maxAUSize;
2670                 }
2671                 else
2672                 {
2673                     /**< Not AMR-NB, AAC, MP3 nor EVRC (AMR-WB, WAV...) */
2674                     M4OSA_TRACE1_1("M4MCS_open(): Found an unsupported audio stream (0x%x) in \
2675                                    input 3gpp clip", pStreamHandler->m_streamType);
2676 
2677                     pC->bUnsupportedAudioFound = M4OSA_TRUE;
2678                     pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
2679                 }
2680             }
2681         }
2682     } /**< end of while (M4NO_ERROR == err) */
2683 
2684     /**
2685     * Check we found at least one supported stream */
2686     if( ( M4OSA_NULL == pC->pReaderVideoStream)
2687         && (M4OSA_NULL == pC->pReaderAudioStream) )
2688     {
2689         M4OSA_TRACE1_0(
2690             "M4MCS_open(): returning M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM");
2691         return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM;
2692     }
2693 
2694     if( pC->VideoState == M4MCS_kStreamState_STARTED )
2695     {
2696         err = M4MCS_setCurrentVideoDecoder(pContext,
2697             pC->pReaderVideoStream->m_basicProperties.m_streamType);
2698         /*FB 2009-02-09: the error is check and returned only if video codecs are compiled,
2699         else only audio is used, that is why the editing process can continue*/
2700 #ifndef M4MCS_AUDIOONLY
2701 
2702         M4ERR_CHECK_RETURN(err);
2703 
2704 #else
2705 
2706         if( ( M4NO_ERROR != err) && (M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED != err) )
2707         {
2708             M4ERR_CHECK_RETURN(err);
2709         }
2710 
2711 #endif /*M4MCS_AUDIOONLY*/
2712 
2713     }
2714 
2715     if( pC->AudioState == M4MCS_kStreamState_STARTED )
2716     {
2717         //EVRC
2718         if( M4DA_StreamTypeAudioEvrc
2719             != pStreamHandler->
2720             m_streamType ) /* decoder not supported yet, but allow to do null encoding */
2721         {
2722             err = M4MCS_setCurrentAudioDecoder(pContext,
2723                 pC->pReaderAudioStream->m_basicProperties.m_streamType);
2724             M4ERR_CHECK_RETURN(err);
2725         }
2726     }
2727 
2728     /**
2729     * Get the audio and video stream properties */
2730     err = M4MCS_intGetInputClipProperties(pC);
2731 
2732     if( M4NO_ERROR != err )
2733     {
2734         M4OSA_TRACE1_1(
2735             "M4MCS_open(): M4MCS_intGetInputClipProperties returns 0x%x", err);
2736         return err;
2737     }
2738 
2739     /**
2740     * Set the begin cut decoding increment according to the input frame rate */
2741     if( 0. != pC->InputFileProperties.fAverageFrameRate ) /**< sanity check */
2742     {
2743         pC->iVideoBeginDecIncr = (M4OSA_Int32)(3000.
2744             / pC->InputFileProperties.
2745             fAverageFrameRate); /**< about 3 frames */
2746     }
2747     else
2748     {
2749         pC->iVideoBeginDecIncr =
2750             200; /**< default value: 200 milliseconds (3 frames @ 15fps)*/
2751     }
2752 
2753     /**
2754     * Update state automaton */
2755     pC->State = M4MCS_kState_OPENED;
2756 
2757     /**
2758     * Return with no error */
2759     M4OSA_TRACE3_0("M4MCS_open(): returning M4NO_ERROR");
2760     return M4NO_ERROR;
2761 }
2762 
2763 /**
2764  ******************************************************************************
2765  * M4OSA_ERR M4MCS_step(M4MCS_Context pContext, M4OSA_UInt8 *pProgress);
2766  * @brief   Perform one step of trancoding.
2767  * @note
2768  * @param   pContext            (IN) MCS context
2769  * @param   pProgress           (OUT) Progress percentage (0 to 100) of the transcoding
2770  * @note    pProgress must be a valid address.
2771  * @return  M4NO_ERROR:         No error
2772  * @return  M4ERR_PARAMETER:    One of the parameters is M4OSA_NULL (debug only)
2773  * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
2774  * @return  M4MCS_WAR_TRANSCODING_DONE: Transcoding is over, user should now call M4MCS_close()
2775  * @return  M4MCS_ERR_AUDIO_CONVERSION_FAILED: The audio conversion (AAC to AMR-NB or MP3) failed
2776  * @return  M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY: The input file contains an AAC audio track
2777  *                                 with an invalid sampling frequency (should never happen)
2778  ******************************************************************************
2779  */
M4MCS_step(M4MCS_Context pContext,M4OSA_UInt8 * pProgress)2780 M4OSA_ERR M4MCS_step( M4MCS_Context pContext, M4OSA_UInt8 *pProgress )
2781 {
2782     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
2783 
2784     M4OSA_TRACE3_1("M4MCS_step called with pContext=0x%x", pContext);
2785 
2786     /**
2787     * Check input parameters */
2788     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
2789         "M4MCS_step: pContext is M4OSA_NULL");
2790     M4OSA_DEBUG_IF2((M4OSA_NULL == pProgress), M4ERR_PARAMETER,
2791         "M4MCS_step: pProgress is M4OSA_NULL");
2792 
2793 #ifdef M4MCS_SUPPORT_STILL_PICTURE
2794 
2795     if( pC->m_bIsStillPicture )
2796     {
2797         /**
2798         * Call the still picture MCS functions*/
2799         return M4MCS_stillPicStep(pC, pProgress);
2800     }
2801 
2802 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
2803 
2804     /**
2805     * Check state automaton */
2806 
2807     switch( pC->State )
2808     {
2809         case M4MCS_kState_READY:
2810             *pProgress = 0;
2811             return M4MCS_intStepSet(pC);
2812             break;
2813 
2814         case M4MCS_kState_BEGINVIDEOJUMP:
2815             *pProgress = pC->uiProgress;
2816             return M4MCS_intStepBeginVideoJump(pC);
2817             break;
2818 
2819         case M4MCS_kState_BEGINVIDEODECODE:
2820             *pProgress = pC->uiProgress;
2821             return M4MCS_intStepBeginVideoDecode(pC);
2822             break;
2823 
2824         case M4MCS_kState_PROCESSING:
2825             {
2826                 M4OSA_ERR err = M4NO_ERROR;
2827                 err = M4MCS_intStepEncoding(pC, pProgress);
2828                 /* Save progress info in case of pause */
2829                 pC->uiProgress = *pProgress;
2830                 return err;
2831             }
2832             break;
2833 
2834         default: /**< State error */
2835             M4OSA_TRACE1_1(
2836                 "M4MCS_step(): Wrong State (%d), returning M4ERR_STATE",
2837                 pC->State);
2838             return M4ERR_STATE;
2839     }
2840 }
2841 
2842 /**
2843  ******************************************************************************
2844  * M4OSA_ERR M4MCS_pause(M4MCS_Context pContext);
2845  * @brief   Pause the transcoding i.e. release the (external hardware) video decoder.
2846  * @note    This function is not needed if no hardware accelerators are used.
2847  *          In that case, pausing the MCS is simply achieved by temporarily suspending
2848  *          the M4MCS_step function calls.
2849  * @param   pContext            (IN) MCS context
2850  * @return  M4NO_ERROR:         No error
2851  * @return  M4ERR_PARAMETER:    pContext is M4OSA_NULL (debug only)
2852  * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
2853  ******************************************************************************
2854  */
M4MCS_pause(M4MCS_Context pContext)2855 M4OSA_ERR M4MCS_pause( M4MCS_Context pContext )
2856 {
2857     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
2858     M4OSA_ERR err;
2859 
2860     M4OSA_TRACE2_1("M4MCS_pause called with pContext=0x%x", pContext);
2861 
2862     /**
2863     * Check input parameters */
2864     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
2865         "M4MCS_pause: pContext is M4OSA_NULL");
2866 
2867 #ifdef M4MCS_SUPPORT_STILL_PICTURE
2868 
2869     if( pC->m_bIsStillPicture )
2870     {
2871         /**
2872         * Call the corresponding still picture MCS function*/
2873         return M4MCS_stillPicPause(pC);
2874     }
2875 
2876 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
2877 
2878     /**
2879     * Check state automaton */
2880 
2881     switch( pC->State )
2882     {
2883         case M4MCS_kState_BEGINVIDEOJUMP: /**< the video decoder has been created,
2884                                             we must destroy it */
2885         case M4MCS_kState_BEGINVIDEODECODE: /**< the video is being used, we must destroy it */
2886         case M4MCS_kState_PROCESSING: /**< the video is being used, we must destroy it */
2887                     /**< OK, nothing to do here */
2888             break;
2889 
2890         default: /**< State error */
2891             M4OSA_TRACE1_1(
2892                 "M4MCS_pause(): Wrong State (%d), returning M4ERR_STATE",
2893                 pC->State);
2894             return M4ERR_STATE;
2895     }
2896 
2897     /**
2898     * Set the CTS at which we will resume the decoding */
2899     if( pC->dViDecCurrentCts > pC->dViDecStartingCts )
2900     {
2901         /**
2902         * We passed the starting CTS, so the resume target is the current CTS */
2903         pC->dViDecStartingCts = pC->dViDecCurrentCts;
2904     }
2905     else {
2906         /**
2907         * We haven't passed the starting CTS yet, so the resume target is still the starting CTS
2908         * --> nothing to do in the else block */
2909     }
2910 
2911     /**
2912     * Free video decoder stuff */
2913     if( M4OSA_NULL != pC->pViDecCtxt )
2914     {
2915         err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt);
2916         pC->pViDecCtxt = M4OSA_NULL;
2917 
2918         if( M4NO_ERROR != err )
2919         {
2920             M4OSA_TRACE1_1(
2921                 "M4MCS_pause: m_pVideoDecoder->pFctDestroy returns 0x%x", err);
2922             return err;
2923         }
2924     }
2925 
2926     /**
2927     * State transition */
2928     pC->State = M4MCS_kState_PAUSED;
2929 
2930     M4OSA_TRACE3_0("M4MCS_pause(): returning M4NO_ERROR");
2931     return M4NO_ERROR;
2932 }
2933 
2934 /**
2935  ******************************************************************************
2936  * M4OSA_ERR M4MCS_resume(M4MCS_Context pContext);
2937  * @brief   Resume the transcoding after a pause (see M4MCS_pause).
2938  * @note    This function is not needed if no hardware accelerators are used.
2939  *          In that case, resuming the MCS is simply achieved by calling
2940  *          the M4MCS_step function.
2941  * @param   pContext            (IN) MCS context
2942  * @return  M4NO_ERROR:         No error
2943  * @return  M4ERR_PARAMETER:    pContext is M4OSA_NULL (debug only)
2944  * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
2945  ******************************************************************************
2946  */
M4MCS_resume(M4MCS_Context pContext)2947 M4OSA_ERR M4MCS_resume( M4MCS_Context pContext )
2948 {
2949     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
2950     M4OSA_ERR err;
2951 
2952     M4OSA_TRACE2_1("M4MCS_resume called with pContext=0x%x", pContext);
2953 
2954     /**
2955     * Check input parameters */
2956     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
2957         "M4MCS_resume: pContext is M4OSA_NULL");
2958 
2959 #ifdef M4MCS_SUPPORT_STILL_PICTURE
2960 
2961     if( pC->m_bIsStillPicture )
2962     {
2963         /**
2964         * Call the corresponding still picture MCS function*/
2965         return M4MCS_stillPicResume(pC);
2966     }
2967 
2968 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
2969 
2970     /**
2971     * Check state automaton */
2972 
2973     switch( pC->State )
2974     {
2975         case M4MCS_kState_PAUSED: /**< OK, nothing to do here */
2976             break;
2977 
2978         default:                  /**< State error */
2979             M4OSA_TRACE1_1(
2980                 "M4MCS_resume(): Wrong State (%d), returning M4ERR_STATE",
2981                 pC->State);
2982             return M4ERR_STATE;
2983             break;
2984     }
2985 
2986     /**
2987     * Prepare the video decoder */
2988     err = M4MCS_intPrepareVideoDecoder(pC);
2989 
2990     if( M4NO_ERROR != err )
2991     {
2992         M4OSA_TRACE1_1(
2993             "M4MCS_resume(): M4MCS_intPrepareVideoDecoder() returns 0x%x", err);
2994         return err;
2995     }
2996 
2997     /**
2998     * State transition */
2999     if( 0.0 == pC->dViDecStartingCts )
3000     {
3001         /**
3002         * We are still at the beginning of the decoded stream, no need to jump, we can proceed */
3003         pC->State = M4MCS_kState_PROCESSING;
3004     }
3005     else
3006     {
3007         /**
3008         * Jumping */
3009         pC->State = M4MCS_kState_BEGINVIDEOJUMP;
3010     }
3011 
3012     M4OSA_TRACE3_0("M4MCS_resume(): returning M4NO_ERROR");
3013     return M4NO_ERROR;
3014 }
3015 
3016 /**
3017  ******************************************************************************
3018  * M4OSA_ERR M4MCS_close(M4MCS_Context pContext);
3019  * @brief    Finish the MCS transcoding.
3020  * @note The output 3GPP file is ready to be played after this call
3021  * @param    pContext            (IN) MCS context
3022  * @return   M4NO_ERROR:         No error
3023  * @return   M4ERR_PARAMETER:    pContext is M4OSA_NULL (If Debug Level >= 2)
3024  * @return   M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
3025  ******************************************************************************
3026  */
M4MCS_close(M4MCS_Context pContext)3027 M4OSA_ERR M4MCS_close( M4MCS_Context pContext )
3028 {
3029     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
3030     M4ENCODER_Header *encHeader;
3031     M4SYS_StreamIDmemAddr streamHeader;
3032 
3033     M4OSA_ERR err = M4NO_ERROR, err2;
3034 
3035     M4OSA_TRACE2_1("M4MCS_close called with pContext=0x%x", pContext);
3036 
3037     /**
3038     * Check input parameters */
3039     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
3040         "M4MCS_close: pContext is M4OSA_NULL");
3041 
3042 #ifdef M4MCS_SUPPORT_STILL_PICTURE
3043 
3044     if( pC->m_bIsStillPicture )
3045     {
3046         /**
3047         * Indicate that current file is no longer a still picture*/
3048         pC->m_bIsStillPicture = M4OSA_FALSE;
3049 
3050         /**
3051         * Call the corresponding still picture MCS function*/
3052         return M4MCS_stillPicClose(pC);
3053     }
3054 
3055 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
3056 
3057     /**
3058     * Check state automaton */
3059 
3060     if( M4MCS_kState_FINISHED != pC->State )
3061     {
3062         M4OSA_TRACE1_1("M4MCS_close(): Wrong State (%d), returning M4ERR_STATE",
3063             pC->State);
3064         return M4ERR_STATE;
3065     }
3066 
3067     /* Close the encoder before the writer to be certain all the AUs have been written and we can
3068     get the DSI. */
3069 
3070     /* Has the encoder actually been started? Don't stop it if that's not the case. */
3071     if( M4MCS_kEncoderRunning == pC->encoderState )
3072     {
3073         if( pC->pVideoEncoderGlobalFcts->pFctStop != M4OSA_NULL )
3074         {
3075             err = pC->pVideoEncoderGlobalFcts->pFctStop(pC->pViEncCtxt);
3076 
3077             if( M4NO_ERROR != err )
3078             {
3079                 M4OSA_TRACE1_1(
3080                     "M4MCS_close: pVideoEncoderGlobalFcts->pFctStop returns 0x%x",
3081                     err);
3082                 /* Well... how the heck do you handle a failed cleanup? */
3083             }
3084         }
3085 
3086         pC->encoderState = M4MCS_kEncoderStopped;
3087     }
3088 
3089     /* Has the encoder actually been opened? Don't close it if that's not the case. */
3090     if( M4MCS_kEncoderStopped == pC->encoderState )
3091     {
3092         err = pC->pVideoEncoderGlobalFcts->pFctClose(pC->pViEncCtxt);
3093 
3094         if( M4NO_ERROR != err )
3095         {
3096             M4OSA_TRACE1_1(
3097                 "M4MCS_close: pVideoEncoderGlobalFcts->pFctClose returns 0x%x",
3098                 err);
3099             /* Well... how the heck do you handle a failed cleanup? */
3100         }
3101 
3102         pC->encoderState = M4MCS_kEncoderClosed;
3103     }
3104 
3105     /**********************************/
3106     /******** Close the writer ********/
3107     /**********************************/
3108     if( M4OSA_NULL != pC->pWriterContext ) /* happens in state _SET */
3109     {
3110         /* HW encoder: fetch the DSI from the shell video encoder, and feed it to the writer before
3111         closing it. */
3112 
3113         if( pC->novideo != M4OSA_TRUE )
3114         {
3115             if( ( M4ENCODER_kMPEG4 == pC->EncodingVideoFormat)
3116                 || (M4ENCODER_kH264 == pC->EncodingVideoFormat) )
3117             {
3118                 err = pC->pVideoEncoderGlobalFcts->pFctGetOption(pC->pViEncCtxt,
3119                     M4ENCODER_kOptionID_EncoderHeader,
3120                     (M4OSA_DataOption) &encHeader);
3121 
3122                 if( ( M4NO_ERROR != err) || (M4OSA_NULL == encHeader->pBuf) )
3123                 {
3124                     M4OSA_TRACE1_1(
3125                         "M4MCS_close: failed to get the encoder header (err 0x%x)",
3126                         err);
3127                     /**< no return here, we still have stuff to deallocate after close, even
3128                      if it fails. */
3129                 }
3130                 else
3131                 {
3132                     /* set this header in the writer */
3133                     streamHeader.streamID = M4MCS_WRITER_VIDEO_STREAM_ID;
3134                     streamHeader.size = encHeader->Size;
3135                     streamHeader.addr = (M4OSA_MemAddr32)encHeader->pBuf;
3136                 }
3137 
3138                 M4OSA_TRACE1_0("calling set option");
3139                 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
3140                     M4WRITER_kDSI, &streamHeader);
3141                 M4OSA_TRACE1_0("set option done");
3142 
3143                 if( M4NO_ERROR != err )
3144                 {
3145                     M4OSA_TRACE1_1(
3146                         "M4MCS_close: failed to set the DSI in the writer (err 0x%x)",
3147                         err);
3148                 }
3149             }
3150 
3151             if( ( M4OSA_TRUE == pC->bH264Trim)
3152                 && (M4ENCODER_kNULL == pC->EncodingVideoFormat) )
3153             {
3154                 if(pC->uiBeginCutTime == 0)
3155                 {
3156                     M4OSA_TRACE1_1("Decoder specific info size = %d",
3157                         pC->m_pInstance->m_decoderSpecificInfoSize);
3158                     pC->m_pInstance->m_pFinalDSISize =
3159                         pC->m_pInstance->m_decoderSpecificInfoSize;
3160                     M4OSA_TRACE1_1("Decoder specific info pointer = %d",
3161                         (M4OSA_MemAddr8)pC->m_pInstance->m_pDecoderSpecificInfo);
3162 
3163                     pC->m_pInstance->m_pFinalDSI =
3164                         (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(pC->m_pInstance-> \
3165                         m_decoderSpecificInfoSize, M4MCS,
3166                         (M4OSA_Char *)"instance->m_pFinalDSI");
3167 
3168                     if( pC->m_pInstance->m_pFinalDSI == M4OSA_NULL )
3169                     {
3170                         M4OSA_TRACE1_0("instance->m_pFinalDSI: allocation error");
3171                         return M4ERR_ALLOC;
3172                     }
3173                     memcpy((void *)pC->m_pInstance->m_pFinalDSI,
3174                         (void *)pC-> \
3175                         m_pInstance->m_pDecoderSpecificInfo,
3176                         pC->m_pInstance->m_decoderSpecificInfoSize);
3177                 }
3178                 streamHeader.streamID = M4MCS_WRITER_VIDEO_STREAM_ID;
3179                 streamHeader.size = pC->m_pInstance->m_pFinalDSISize;
3180                 streamHeader.addr =
3181                     (M4OSA_MemAddr32)pC->m_pInstance->m_pFinalDSI;
3182                 M4OSA_TRACE1_0("calling set option");
3183                 err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
3184                     M4WRITER_kDSI, &streamHeader);
3185                 M4OSA_TRACE1_0("set option done");
3186 
3187                 if( M4NO_ERROR != err )
3188                 {
3189                     M4OSA_TRACE1_1(
3190                         "M4MCS_close: failed to set the DSI in the writer (err 0x%x)",
3191                         err);
3192                 }
3193             }
3194         }
3195         /* Write and close the 3GP output file */
3196         err2 = pC->pWriterGlobalFcts->pFctCloseWrite(pC->pWriterContext);
3197         pC->pWriterContext = M4OSA_NULL;
3198 
3199         if( M4NO_ERROR != err2 )
3200         {
3201             M4OSA_TRACE1_1(
3202                 "M4MCS_close: pWriterGlobalFcts->pFctCloseWrite returns 0x%x",
3203                 err2);
3204 
3205             if( M4NO_ERROR == err )
3206                 err = err2;
3207             /**< no return here, we still have stuff to deallocate after close, even if it fails.*/
3208         }
3209     }
3210 
3211     /* Close output PCM file if needed */
3212     if( pC->pOutputPCMfile != M4OSA_NULL )
3213     {
3214         pC->pOsaFileWritPtr->closeWrite(pC->pOutputPCMfile);
3215         pC->pOutputPCMfile = M4OSA_NULL;
3216     }
3217 
3218     /*FlB 2009.03.04: add audio effects,
3219     free effects list*/
3220     if( M4OSA_NULL != pC->pEffects )
3221     {
3222         free(pC->pEffects);
3223         pC->pEffects = M4OSA_NULL;
3224     }
3225     pC->nbEffects = 0;
3226     pC->pActiveEffectNumber = -1;
3227 
3228     /**
3229     * State transition */
3230     pC->State = M4MCS_kState_CLOSED;
3231 
3232     if( M4OSA_NULL != pC->H264MCSTempBuffer )
3233     {
3234         free(pC->H264MCSTempBuffer);
3235     }
3236 
3237     M4OSA_TRACE3_0("M4MCS_close(): returning M4NO_ERROR");
3238     return err;
3239 }
3240 
3241 /**
3242  ******************************************************************************
3243  * M4OSA_ERR M4MCS_cleanUp(M4MCS_Context pContext);
3244  * @brief    Free all resources used by the MCS.
3245  * @note The context is no more valid after this call
3246  * @param    pContext            (IN) MCS context
3247  * @return   M4NO_ERROR:         No error
3248  * @return   M4ERR_PARAMETER:    pContext is M4OSA_NULL (If Debug Level >= 2)
3249  * @return   M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
3250  ******************************************************************************
3251  */
M4MCS_cleanUp(M4MCS_Context pContext)3252 M4OSA_ERR M4MCS_cleanUp( M4MCS_Context pContext )
3253 {
3254     M4OSA_ERR err = M4NO_ERROR;
3255     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
3256 
3257     M4OSA_TRACE3_1("M4MCS_cleanUp called with pContext=0x%x", pContext);
3258 
3259 #ifdef MCS_DUMP_PCM_TO_FILE
3260 
3261     if( file_au_reader )
3262     {
3263         fclose(file_au_reader);
3264         file_au_reader = NULL;
3265     }
3266 
3267     if( file_pcm_decoder )
3268     {
3269         fclose(file_pcm_decoder);
3270         file_pcm_decoder = NULL;
3271     }
3272 
3273     if( file_pcm_encoder )
3274     {
3275         fclose(file_pcm_encoder);
3276         file_pcm_encoder = NULL;
3277     }
3278 
3279 #endif
3280 
3281     /**
3282     * Check input parameter */
3283 
3284     if( M4OSA_NULL == pContext )
3285     {
3286         M4OSA_TRACE1_0(
3287             "M4MCS_cleanUp: pContext is M4OSA_NULL, returning M4ERR_PARAMETER");
3288         return M4ERR_PARAMETER;
3289     }
3290 
3291     /**
3292     * Check state automaton */
3293     if( M4MCS_kState_CLOSED != pC->State )
3294     {
3295         M4OSA_TRACE1_1(
3296             "M4MCS_cleanUp(): Wrong State (%d), returning M4ERR_STATE",
3297             pC->State);
3298         return M4ERR_STATE;
3299     }
3300 
3301     if( M4OSA_NULL != pC->m_pInstance )
3302     {
3303         err = H264MCS_Freeinstance(pC->m_pInstance);
3304         pC->m_pInstance = M4OSA_NULL;
3305     }
3306 
3307     /* ----- Free video encoder stuff, if needed ----- */
3308 
3309     if( ( M4OSA_NULL != pC->pViEncCtxt)
3310         && (M4OSA_NULL != pC->pVideoEncoderGlobalFcts) )
3311     {
3312         err = pC->pVideoEncoderGlobalFcts->pFctCleanup(pC->pViEncCtxt);
3313         pC->pViEncCtxt = M4OSA_NULL;
3314 
3315         if( M4NO_ERROR != err )
3316         {
3317             M4OSA_TRACE1_1(
3318                 "M4MCS_cleanUp: pVideoEncoderGlobalFcts->pFctCleanup returns 0x%x",
3319                 err);
3320             /**< don't return, we still have stuff to free */
3321         }
3322 
3323         pC->encoderState = M4MCS_kNoEncoder;
3324     }
3325 
3326     /**
3327     * In the H263 case, we allocated our own DSI buffer */
3328     if( ( M4ENCODER_kH263 == pC->EncodingVideoFormat)
3329         && (M4OSA_NULL != pC->WriterVideoStreamInfo.Header.pBuf) )
3330     {
3331         free(pC->WriterVideoStreamInfo.Header.pBuf);
3332         pC->WriterVideoStreamInfo.Header.pBuf = M4OSA_NULL;
3333     }
3334 
3335     if( M4OSA_NULL != pC->pPreResizeFrame )
3336     {
3337         if( M4OSA_NULL != pC->pPreResizeFrame[0].pac_data )
3338         {
3339             free(pC->pPreResizeFrame[0].pac_data);
3340             pC->pPreResizeFrame[0].pac_data = M4OSA_NULL;
3341         }
3342 
3343         if( M4OSA_NULL != pC->pPreResizeFrame[1].pac_data )
3344         {
3345             free(pC->pPreResizeFrame[1].pac_data);
3346             pC->pPreResizeFrame[1].pac_data = M4OSA_NULL;
3347         }
3348 
3349         if( M4OSA_NULL != pC->pPreResizeFrame[2].pac_data )
3350         {
3351             free(pC->pPreResizeFrame[2].pac_data);
3352             pC->pPreResizeFrame[2].pac_data = M4OSA_NULL;
3353         }
3354         free(pC->pPreResizeFrame);
3355         pC->pPreResizeFrame = M4OSA_NULL;
3356     }
3357 
3358     /* ----- Free the ssrc stuff ----- */
3359 
3360     if( M4OSA_NULL != pC->SsrcScratch )
3361     {
3362         free(pC->SsrcScratch);
3363         pC->SsrcScratch = M4OSA_NULL;
3364     }
3365 
3366     if( M4OSA_NULL != pC->pSsrcBufferIn )
3367     {
3368         free(pC->pSsrcBufferIn);
3369         pC->pSsrcBufferIn = M4OSA_NULL;
3370     }
3371 
3372     if( M4OSA_NULL != pC->pSsrcBufferOut )
3373     {
3374         free(pC->pSsrcBufferOut);
3375         pC->pSsrcBufferOut = M4OSA_NULL;
3376     }
3377 
3378     if (pC->pLVAudioResampler != M4OSA_NULL)
3379     {
3380         LVDestroy(pC->pLVAudioResampler);
3381         pC->pLVAudioResampler = M4OSA_NULL;
3382     }
3383 
3384     /* ----- Free the audio encoder stuff ----- */
3385 
3386     if( M4OSA_NULL != pC->pAudioEncCtxt )
3387     {
3388         err = pC->pAudioEncoderGlobalFcts->pFctClose(pC->pAudioEncCtxt);
3389 
3390         if( M4NO_ERROR != err )
3391         {
3392             M4OSA_TRACE1_1(
3393                 "M4MCS_cleanUp: pAudioEncoderGlobalFcts->pFctClose returns 0x%x",
3394                 err);
3395             /**< don't return, we still have stuff to free */
3396         }
3397 
3398         err = pC->pAudioEncoderGlobalFcts->pFctCleanUp(pC->pAudioEncCtxt);
3399 
3400         if( M4NO_ERROR != err )
3401         {
3402             M4OSA_TRACE1_1(
3403                 "M4MCS_cleanUp: pAudioEncoderGlobalFcts->pFctCleanUp returns 0x%x",
3404                 err);
3405             /**< don't return, we still have stuff to free */
3406         }
3407 
3408         pC->pAudioEncCtxt = M4OSA_NULL;
3409     }
3410 
3411     if( M4OSA_NULL != pC->pAudioEncoderBuffer )
3412     {
3413         free(pC->pAudioEncoderBuffer);
3414         pC->pAudioEncoderBuffer = M4OSA_NULL;
3415     }
3416 
3417     /* ----- Free all other stuff ----- */
3418 
3419     /**
3420     * Free the readers and the decoders */
3421     M4MCS_intCleanUp_ReadersDecoders(pC);
3422 
3423 #ifdef M4MCS_SUPPORT_STILL_PICTURE
3424     /**
3425     * Free the still picture resources */
3426 
3427     M4MCS_stillPicCleanUp(pC);
3428 
3429 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
3430 
3431     /**
3432     * Free the shells interfaces */
3433 
3434     M4MCS_unRegisterAllWriters(pContext);
3435     M4MCS_unRegisterAllEncoders(pContext);
3436     M4MCS_unRegisterAllReaders(pContext);
3437     M4MCS_unRegisterAllDecoders(pContext);
3438 
3439     /**
3440     * Free the context itself */
3441     free(pC);
3442     pC = M4OSA_NULL;
3443 
3444     M4OSA_TRACE3_0("M4MCS_cleanUp(): returning M4NO_ERROR");
3445     return M4NO_ERROR;
3446 }
3447 
3448 /**
3449  ******************************************************************************
3450  * M4OSA_ERR M4MCS_abort(M4MCS_Context pContext);
3451  * @brief    Finish the MCS transcoding and free all resources used by the MCS
3452  *          whatever the state is.
3453  * @note    The context is no more valid after this call
3454  * @param    pContext            (IN) MCS context
3455  * @return    M4NO_ERROR:            No error
3456  * @return    M4ERR_PARAMETER:    pContext is M4OSA_NULL (debug only)
3457  ******************************************************************************
3458  */
M4MCS_abort(M4MCS_Context pContext)3459 M4OSA_ERR M4MCS_abort( M4MCS_Context pContext )
3460 {
3461     M4OSA_ERR err = M4NO_ERROR;
3462     M4OSA_ERR err1 = M4NO_ERROR;
3463     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
3464 
3465     if( M4OSA_NULL == pContext )
3466     {
3467         return M4NO_ERROR;
3468     }
3469 
3470     if( ( pC->State == M4MCS_kState_CREATED)
3471         || (pC->State == M4MCS_kState_CLOSED) )
3472     {
3473         pC->State = M4MCS_kState_CLOSED;
3474 
3475         err = M4MCS_cleanUp(pContext);
3476 
3477         if( err != M4NO_ERROR )
3478         {
3479             M4OSA_TRACE1_1("M4MCS_abort : M4MCS_cleanUp fails err = 0x%x", err);
3480         }
3481     }
3482     else
3483     {
3484 #ifdef M4MCS_SUPPORT_STILL_PICTURE
3485 
3486         if( pC->m_bIsStillPicture )
3487         {
3488             /**
3489             * Cancel the ongoing processes if any*/
3490             err = M4MCS_stillPicCancel(pC);
3491 
3492             if( err != M4NO_ERROR )
3493             {
3494                 M4OSA_TRACE1_1(
3495                     "M4MCS_abort : M4MCS_stillPicCancel fails err = 0x%x", err);
3496             }
3497             /*Still picture process is now stopped; Carry on with close and cleanup*/
3498         }
3499 
3500 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
3501 
3502         pC->State = M4MCS_kState_FINISHED;
3503 
3504         err = M4MCS_close(pContext);
3505 
3506         if( err != M4NO_ERROR )
3507         {
3508             M4OSA_TRACE1_1("M4MCS_abort : M4MCS_close fails err = 0x%x", err);
3509             err1 = err;
3510         }
3511 
3512         err = M4MCS_cleanUp(pContext);
3513 
3514         if( err != M4NO_ERROR )
3515         {
3516             M4OSA_TRACE1_1("M4MCS_abort : M4MCS_cleanUp fails err = 0x%x", err);
3517         }
3518     }
3519     err = (err1 == M4NO_ERROR) ? err : err1;
3520     return err;
3521 }
3522 
3523 /**
3524  ******************************************************************************
3525  * M4OSA_ERR M4MCS_getInputFileProperties(M4MCS_Context pContext,
3526  *                                         M4VIDEOEDITING_ClipProperties* pFileProperties);
3527  * @brief   Retrieves the properties of the audio and video streams from the input file.
3528  * @param   pContext            (IN) MCS context
3529  * @param   pProperties         (OUT) Pointer on an allocated M4VIDEOEDITING_ClipProperties
3530 structure which is filled with the input stream properties.
3531  * @note    The structure pProperties must be allocated and further de-allocated
3532 by the application. The function must be called in the opened state.
3533  * @return  M4NO_ERROR:         No error
3534  * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL
3535  * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
3536  ******************************************************************************
3537  */
M4MCS_getInputFileProperties(M4MCS_Context pContext,M4VIDEOEDITING_ClipProperties * pFileProperties)3538 M4OSA_ERR M4MCS_getInputFileProperties( M4MCS_Context pContext,
3539                                        M4VIDEOEDITING_ClipProperties *pFileProperties )
3540 {
3541     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
3542 
3543     M4OSA_TRACE2_2("M4MCS_getInputFileProperties called with pContext=0x%x, \
3544                    pFileProperties=0x%x", pContext, pFileProperties);
3545 
3546     /**
3547     * Check input parameters */
3548     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
3549         "M4MCS_getInputFileProperties: pContext is M4OSA_NULL");
3550     M4OSA_DEBUG_IF2((M4OSA_NULL == pFileProperties), M4ERR_PARAMETER,
3551         "M4MCS_getInputFileProperties: pProperties is M4OSA_NULL");
3552 
3553 #ifdef M4MCS_SUPPORT_STILL_PICTURE
3554 
3555     if( pC->m_bIsStillPicture )
3556     {
3557         /**
3558         * Call the corresponding still picture MCS function*/
3559         return M4MCS_stillPicGetInputFileProperties(pC, pFileProperties);
3560     }
3561 
3562 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
3563 
3564     /**
3565     * Check state automaton */
3566 
3567     if( M4MCS_kState_OPENED != pC->State )
3568     {
3569         M4OSA_TRACE1_1(
3570             "M4MCS_getInputFileProperties(): Wrong State (%d), returning M4ERR_STATE",
3571             pC->State);
3572         return M4ERR_STATE;
3573     }
3574 
3575     /**
3576     * Copy previously computed properties into given structure */
3577     memcpy((void *)pFileProperties,
3578         (void *) &pC->InputFileProperties,
3579         sizeof(M4VIDEOEDITING_ClipProperties));
3580 
3581     return M4NO_ERROR;
3582 }
3583 
3584 /**
3585  ******************************************************************************
3586  * M4OSA_ERR M4MCS_setOutputParams(M4MCS_Context pContext, M4MCS_OutputParams* pParams);
3587  * @brief   Set the MCS video output parameters.
3588  * @note    Must be called after M4MCS_open. Must be called before M4MCS_step.
3589  * @param   pContext            (IN) MCS context
3590  * @param   pParams             (IN/OUT) Transcoding parameters
3591  * @return  M4NO_ERROR:         No error
3592  * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
3593  * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
3594  * @return  M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263 : Output video frame size parameter is
3595  *                                                        incompatible with H263 encoding
3596  * @return  M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263 : Output video frame size parameter is
3597  *                                                        incompatible with H263 encoding
3598  * @return  M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT     : Undefined output video format parameter
3599  * @return  M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE : Undefined output video frame size
3600  * @return  M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE : Undefined output video frame rate
3601  * @return  M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT : Undefined output audio format parameter
3602  * @return  M4MCS_ERR_DURATION_IS_NULL : Specified output parameters define a null duration stream
3603  *                                         (no audio and video)
3604  ******************************************************************************
3605  */
M4MCS_setOutputParams(M4MCS_Context pContext,M4MCS_OutputParams * pParams)3606 M4OSA_ERR M4MCS_setOutputParams( M4MCS_Context pContext,
3607                                 M4MCS_OutputParams *pParams )
3608 {
3609     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
3610     M4OSA_UInt32 uiFrameWidth;
3611     M4OSA_UInt32 uiFrameHeight;
3612     M4OSA_ERR err;
3613 
3614     M4OSA_TRACE2_2(
3615         "M4MCS_setOutputParams called with pContext=0x%x, pParams=0x%x",
3616         pContext, pParams);
3617 
3618     /**
3619     * Check input parameters */
3620     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
3621         "M4MCS_setOutputParams: pContext is M4OSA_NULL");
3622     M4OSA_DEBUG_IF2((M4OSA_NULL == pParams), M4ERR_PARAMETER,
3623         "M4MCS_setOutputParams: pParam is M4OSA_NULL");
3624 
3625 #ifdef M4MCS_SUPPORT_STILL_PICTURE
3626 
3627     if( pC->m_bIsStillPicture )
3628     {
3629         /**
3630         * Call the corresponding still picture MCS function*/
3631         return M4MCS_stillPicSetOutputParams(pC, pParams);
3632     }
3633 
3634 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
3635 
3636     /**
3637     * Check state automaton */
3638 
3639     if( M4MCS_kState_OPENED != pC->State )
3640     {
3641         M4OSA_TRACE1_1(
3642             "M4MCS_setOutputParams(): Wrong State (%d), returning M4ERR_STATE",
3643             pC->State);
3644         return M4ERR_STATE;
3645     }
3646 
3647     /* Ignore audio or video stream if the output do not need it, */
3648     /* or if the input file does not have any audio or video stream */
3649     /*FlB 26.02.2009: add mp3 as mcs output format*/
3650     if( ( pParams->OutputVideoFormat == M4VIDEOEDITING_kNoneVideo)
3651         || (pC->VideoState == M4MCS_kStreamState_NOSTREAM)
3652         || (pParams->OutputFileType == M4VIDEOEDITING_kFileType_AMR)
3653         || (pParams->OutputFileType == M4VIDEOEDITING_kFileType_MP3) )
3654     {
3655         pC->novideo = M4OSA_TRUE;
3656     }
3657 
3658     if( ( pParams->OutputAudioFormat == M4VIDEOEDITING_kNoneAudio)
3659         || (pC->AudioState == M4MCS_kStreamState_NOSTREAM) )
3660     {
3661         pC->noaudio = M4OSA_TRUE;
3662     }
3663 
3664     if( pC->noaudio && pC->novideo )
3665     {
3666         M4OSA_TRACE1_0(
3667             "!!! M4MCS_setOutputParams : clip is NULL, there is no audio, no video");
3668         return M4MCS_ERR_DURATION_IS_NULL;
3669     }
3670 
3671     /* Set writer */
3672     err = M4MCS_setCurrentWriter(pContext, pParams->OutputFileType);
3673     M4ERR_CHECK_RETURN(err);
3674 
3675     /* Set video parameters */
3676     if( pC->novideo == M4OSA_FALSE )
3677     {
3678         /**
3679         * Check Video Format correctness */
3680 
3681         switch( pParams->OutputVideoFormat )
3682         {
3683             case M4VIDEOEDITING_kH263:
3684                 if( pParams->OutputFileType == M4VIDEOEDITING_kFileType_MP4 )
3685                     return M4MCS_ERR_H263_FORBIDDEN_IN_MP4_FILE;
3686 
3687                 pC->EncodingVideoFormat = M4ENCODER_kH263;
3688                 err = M4MCS_setCurrentVideoEncoder(pContext,
3689                     pParams->OutputVideoFormat);
3690                 M4ERR_CHECK_RETURN(err);
3691                 break;
3692 
3693             case M4VIDEOEDITING_kMPEG4:
3694 
3695                 pC->EncodingVideoFormat = M4ENCODER_kMPEG4;
3696                 err = M4MCS_setCurrentVideoEncoder(pContext,
3697                     pParams->OutputVideoFormat);
3698                 M4ERR_CHECK_RETURN(err);
3699                 break;
3700 
3701             case M4VIDEOEDITING_kH264:
3702 
3703                 pC->EncodingVideoFormat = M4ENCODER_kH264;
3704                 err = M4MCS_setCurrentVideoEncoder(pContext,
3705                     pParams->OutputVideoFormat);
3706                 M4ERR_CHECK_RETURN(err);
3707                 break;
3708 
3709             case M4VIDEOEDITING_kNullVideo:
3710                 if( ( pParams->OutputFileType == M4VIDEOEDITING_kFileType_MP4)
3711                     && (pC->InputFileProperties.VideoStreamType
3712                     == M4VIDEOEDITING_kH263) )
3713                     return M4MCS_ERR_H263_FORBIDDEN_IN_MP4_FILE;
3714 
3715 
3716                 /* Encoder needed for begin cut to generate an I-frame */
3717                 pC->EncodingVideoFormat = M4ENCODER_kNULL;
3718                 err = M4MCS_setCurrentVideoEncoder(pContext,
3719                     pC->InputFileProperties.VideoStreamType);
3720                 M4ERR_CHECK_RETURN(err);
3721                 break;
3722 
3723             default:
3724                 M4OSA_TRACE1_1("M4MCS_setOutputParams: Undefined output video format (%d),\
3725                                returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT",
3726                                pParams->OutputVideoFormat);
3727                 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT;
3728         }
3729 
3730         /**
3731         * Check Video frame size correctness */
3732         if( M4VIDEOEDITING_kNullVideo == pParams->OutputVideoFormat )
3733         {
3734             uiFrameWidth =
3735                 pC->EncodingWidth = pC->InputFileProperties.uiVideoWidth;
3736             uiFrameHeight =
3737                 pC->EncodingHeight = pC->InputFileProperties.uiVideoHeight;
3738 
3739             /**
3740             * Set output video profile and level */
3741             pC->encodingVideoProfile = pC->InputFileProperties.uiVideoProfile;
3742             /** Set the target video level, because input 3gp file may
3743              *  have wrong video level value (some encoders do not respect
3744              *  level restrictions like video resolution when content is created).
3745              **/
3746             pC->encodingVideoLevel = pParams->outputVideoLevel;
3747 
3748             // Clip's original width and height may not be
3749             // multiple of 16.
3750             // Ensure encoding width and height are multiple of 16
3751 
3752             uint32_t remainder = pC->EncodingWidth % 16;
3753             if (remainder != 0) {
3754                 if (remainder >= 8) {
3755                     // Roll forward
3756                     pC->EncodingWidth =
3757                         pC->EncodingWidth + (16-remainder);
3758                 } else {
3759                     // Roll backward
3760                     pC->EncodingWidth =
3761                         pC->EncodingWidth - remainder;
3762                 }
3763                 uiFrameWidth = pC->EncodingWidth;
3764             }
3765 
3766             remainder = pC->EncodingHeight % 16;
3767             if (remainder != 0) {
3768                 if (remainder >= 8) {
3769                     // Roll forward
3770                     pC->EncodingHeight =
3771                         pC->EncodingHeight + (16-remainder);
3772                 } else {
3773                     // Roll backward
3774                     pC->EncodingHeight =
3775                         pC->EncodingHeight - remainder;
3776                 }
3777                 uiFrameHeight = pC->EncodingHeight;
3778             }
3779 
3780         }
3781         else
3782         {
3783             /**
3784             * Set output video profile and level */
3785             pC->encodingVideoProfile = pParams->outputVideoProfile;
3786             pC->encodingVideoLevel = pParams->outputVideoLevel;
3787 
3788             switch( pParams->OutputVideoFrameSize )
3789             {
3790                 case M4VIDEOEDITING_kSQCIF:
3791                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_SQCIF_Width;
3792                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_SQCIF_Height;
3793                     break;
3794 
3795                 case M4VIDEOEDITING_kQQVGA:
3796                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_QQVGA_Width;
3797                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_QQVGA_Height;
3798                     break;
3799 
3800                 case M4VIDEOEDITING_kQCIF:
3801                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_QCIF_Width;
3802                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_QCIF_Height;
3803                     break;
3804 
3805                 case M4VIDEOEDITING_kQVGA:
3806                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_QVGA_Width;
3807                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_QVGA_Height;
3808                     break;
3809 
3810                 case M4VIDEOEDITING_kCIF:
3811                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_CIF_Width;
3812                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_CIF_Height;
3813                     break;
3814 
3815                 case M4VIDEOEDITING_kVGA:
3816                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_VGA_Width;
3817                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_VGA_Height;
3818                     break;
3819                     /* +PR LV5807 */
3820                 case M4VIDEOEDITING_kWVGA:
3821                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_WVGA_Width;
3822                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_WVGA_Height;
3823                     break;
3824 
3825                 case M4VIDEOEDITING_kNTSC:
3826                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_NTSC_Width;
3827                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_NTSC_Height;
3828                     break;
3829                     /* -PR LV5807*/
3830                     /* +CR Google */
3831                 case M4VIDEOEDITING_k640_360:
3832                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_640_360_Width;
3833                     uiFrameHeight =
3834                         pC->EncodingHeight = M4ENCODER_640_360_Height;
3835                     break;
3836 
3837                 case M4VIDEOEDITING_k854_480:
3838                     uiFrameWidth =
3839                         pC->EncodingWidth = M4ENCODER_854_480_Width;
3840                     uiFrameHeight =
3841                         pC->EncodingHeight = M4ENCODER_854_480_Height;
3842                     break;
3843 
3844                 case M4VIDEOEDITING_k1280_720:
3845                     uiFrameWidth =
3846                         pC->EncodingWidth = M4ENCODER_1280_720_Width;
3847                     uiFrameHeight =
3848                         pC->EncodingHeight = M4ENCODER_1280_720_Height;
3849                     break;
3850 
3851                 case M4VIDEOEDITING_k1080_720:
3852                     uiFrameWidth =
3853                         pC->EncodingWidth = M4ENCODER_1080_720_Width;
3854                     uiFrameHeight =
3855                         pC->EncodingHeight = M4ENCODER_1080_720_Height;
3856                     break;
3857 
3858                 case M4VIDEOEDITING_k960_720:
3859                     uiFrameWidth =
3860                         pC->EncodingWidth = M4ENCODER_960_720_Width;
3861                     uiFrameHeight =
3862                         pC->EncodingHeight = M4ENCODER_960_720_Height;
3863                     break;
3864 
3865                 case M4VIDEOEDITING_k1920_1080:
3866                     uiFrameWidth =
3867                         pC->EncodingWidth = M4ENCODER_1920_1080_Width;
3868                     uiFrameHeight =
3869                         pC->EncodingHeight = M4ENCODER_1920_1080_Height;
3870                     break;
3871                     /* -CR Google */
3872                 default:
3873                     M4OSA_TRACE1_1(
3874                         "M4MCS_setOutputParams: Undefined output video frame size \
3875                         (%d), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE",
3876                         pParams->OutputVideoFrameSize);
3877                     return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE;
3878             }
3879         }
3880 
3881         /**
3882         * Compute video max au size and max chunck size.
3883         * We do it here because it depends on the frame size only, and
3884         * because we need it for the file size/video bitrate estimations */
3885         pC->uiVideoMaxAuSize =
3886             (M4OSA_UInt32)(1.5F *(M4OSA_Float)(uiFrameWidth * uiFrameHeight) \
3887             *M4MCS_VIDEO_MIN_COMPRESSION_RATIO);
3888         pC->uiVideoMaxChunckSize = (M4OSA_UInt32)(pC->uiVideoMaxAuSize       \
3889             *
3890             M4MCS_VIDEO_CHUNK_AU_SIZE_RATIO); /**< from max AU size to max Chunck size */
3891 
3892         if( 0 == pC->uiVideoMaxAuSize )
3893         {
3894             /* Size may be zero in case of null encoding with unrecognized stream */
3895             M4OSA_TRACE1_0("M4MCS_setOutputParams: video frame size is 0 returning\
3896                            M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE");
3897             return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE;
3898         }
3899 
3900 
3901         /**
3902         * Size check for H263 (only valid sizes are CIF, QCIF and SQCIF) */
3903 
3904         if( M4VIDEOEDITING_kH263 == pParams->OutputVideoFormat )
3905         {
3906             switch( pParams->OutputVideoFrameSize )
3907             {
3908                 case M4VIDEOEDITING_kSQCIF:
3909                 case M4VIDEOEDITING_kQCIF:
3910                 case M4VIDEOEDITING_kCIF:
3911                     /* OK */
3912                     break;
3913 
3914                 default:
3915                     M4OSA_TRACE1_0(
3916                         "M4MCS_setOutputParams():\
3917                         returning M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263");
3918                     return M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263;
3919             }
3920         }
3921 
3922         /**
3923         * Check Video Frame rate correctness */
3924         if( M4VIDEOEDITING_kNullVideo != pParams->OutputVideoFormat )
3925         {
3926             switch( pParams->OutputVideoFrameRate )
3927             {
3928                 case M4VIDEOEDITING_k5_FPS:
3929                     pC->EncodingVideoFramerate = M4ENCODER_k5_FPS;
3930                     break;
3931 
3932                 case M4VIDEOEDITING_k7_5_FPS:
3933                     pC->EncodingVideoFramerate = M4ENCODER_k7_5_FPS;
3934                     break;
3935 
3936                 case M4VIDEOEDITING_k10_FPS:
3937                     pC->EncodingVideoFramerate = M4ENCODER_k10_FPS;
3938                     break;
3939 
3940                 case M4VIDEOEDITING_k12_5_FPS:
3941                     pC->EncodingVideoFramerate = M4ENCODER_k12_5_FPS;
3942                     break;
3943 
3944                 case M4VIDEOEDITING_k15_FPS:
3945                     pC->EncodingVideoFramerate = M4ENCODER_k15_FPS;
3946                     break;
3947 
3948                 case M4VIDEOEDITING_k20_FPS:
3949                     pC->EncodingVideoFramerate = M4ENCODER_k20_FPS;
3950                     break;
3951 
3952                 case M4VIDEOEDITING_k25_FPS:
3953                     pC->EncodingVideoFramerate = M4ENCODER_k25_FPS;
3954                     break;
3955 
3956                 case M4VIDEOEDITING_k30_FPS:
3957                     pC->EncodingVideoFramerate = M4ENCODER_k30_FPS;
3958                     break;
3959 
3960                 default:
3961                     M4OSA_TRACE1_1(
3962                         "M4MCS_setOutputParams: Undefined output video frame rate\
3963                         (%d), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE",
3964                         pParams->OutputVideoFrameRate);
3965                     return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE;
3966             }
3967         }
3968 
3969         /**
3970         * Frame rate check for H263 (only dividers of 30 fps (29.97 actually)) */
3971         if( M4VIDEOEDITING_kH263 == pParams->OutputVideoFormat )
3972         {
3973             switch( pC->EncodingVideoFramerate )
3974             {
3975                 case M4ENCODER_k5_FPS:
3976                 case M4ENCODER_k7_5_FPS:
3977                 case M4ENCODER_k10_FPS:
3978                 case M4ENCODER_k15_FPS:
3979                 case M4ENCODER_k30_FPS:
3980                     /* OK */
3981                     break;
3982 
3983                 default:
3984                     M4OSA_TRACE1_0(
3985                         "M4MCS_setOutputParams():\
3986                         returning M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263");
3987                     return M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263;
3988             }
3989         }
3990     }
3991 
3992     /* Set audio parameters */
3993     if( pC->noaudio == M4OSA_FALSE )
3994     {
3995         /**
3996         * Check Audio Format correctness */
3997         switch( pParams->OutputAudioFormat )
3998         {
3999             case M4VIDEOEDITING_kAMR_NB:
4000 
4001                 err = M4MCS_setCurrentAudioEncoder(pContext,
4002                     pParams->OutputAudioFormat);
4003                 M4ERR_CHECK_RETURN(err);
4004 
4005                 pC->AudioEncParams.Format = M4ENCODER_kAMRNB;
4006                 pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
4007                 pC->AudioEncParams.ChannelNum = M4ENCODER_kMono;
4008                 pC->AudioEncParams.SpecifParam.AmrSID = M4ENCODER_kAmrNoSID;
4009                 break;
4010 
4011             case M4VIDEOEDITING_kAAC:
4012 
4013                 err = M4MCS_setCurrentAudioEncoder(pContext,
4014                     pParams->OutputAudioFormat);
4015                 M4ERR_CHECK_RETURN(err);
4016 
4017                 pC->AudioEncParams.Format = M4ENCODER_kAAC;
4018                 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
4019 
4020                 switch( pParams->OutputAudioSamplingFrequency )
4021                 {
4022                     case M4VIDEOEDITING_k8000_ASF:
4023                         pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
4024                         break;
4025 
4026                     case M4VIDEOEDITING_k16000_ASF:
4027                         pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
4028                         break;
4029 
4030                     case M4VIDEOEDITING_k22050_ASF:
4031                         pC->AudioEncParams.Frequency = M4ENCODER_k22050Hz;
4032                         break;
4033 
4034                     case M4VIDEOEDITING_k24000_ASF:
4035                         pC->AudioEncParams.Frequency = M4ENCODER_k24000Hz;
4036                         break;
4037 
4038                     case M4VIDEOEDITING_k32000_ASF:
4039                         pC->AudioEncParams.Frequency = M4ENCODER_k32000Hz;
4040                         break;
4041 
4042                     case M4VIDEOEDITING_k44100_ASF:
4043                         pC->AudioEncParams.Frequency = M4ENCODER_k44100Hz;
4044                         break;
4045 
4046                     case M4VIDEOEDITING_k48000_ASF:
4047                         pC->AudioEncParams.Frequency = M4ENCODER_k48000Hz;
4048                         break;
4049 
4050                     case M4VIDEOEDITING_k11025_ASF:
4051                     case M4VIDEOEDITING_k12000_ASF:
4052                     case M4VIDEOEDITING_kDefault_ASF:
4053                         break;
4054                 }
4055                     pC->AudioEncParams.ChannelNum =
4056                         (pParams->bAudioMono == M4OSA_TRUE) ? \
4057                         M4ENCODER_kMono : M4ENCODER_kStereo;
4058                     pC->AudioEncParams.SpecifParam.AacParam.Regulation =
4059                         M4ENCODER_kAacRegulNone; //M4ENCODER_kAacBitReservoir
4060                     /* unused */
4061                     pC->AudioEncParams.SpecifParam.AacParam.bIS = M4OSA_FALSE;
4062                     pC->AudioEncParams.SpecifParam.AacParam.bMS = M4OSA_FALSE;
4063                     pC->AudioEncParams.SpecifParam.AacParam.bPNS = M4OSA_FALSE;
4064                     pC->AudioEncParams.SpecifParam.AacParam.bTNS = M4OSA_FALSE;
4065                     /* TODO change into highspeed asap */
4066                     pC->AudioEncParams.SpecifParam.AacParam.bHighSpeed =
4067                         M4OSA_FALSE;
4068                     break;
4069 
4070                     /*FlB 26.02.2009: add mp3 as mcs output format, add mp3 encoder*/
4071                 case M4VIDEOEDITING_kMP3:
4072                     err = M4MCS_setCurrentAudioEncoder(pContext,
4073                         pParams->OutputAudioFormat);
4074                     M4ERR_CHECK_RETURN(err);
4075 
4076                     pC->AudioEncParams.Format = M4ENCODER_kMP3;
4077                     pC->AudioEncParams.ChannelNum =
4078                         (pParams->bAudioMono == M4OSA_TRUE) ? \
4079                         M4ENCODER_kMono : M4ENCODER_kStereo;
4080 
4081                     pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
4082 
4083                     switch( pParams->OutputAudioSamplingFrequency )
4084                     {
4085                         case M4VIDEOEDITING_k8000_ASF:
4086                             pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
4087                             break;
4088 
4089                         case M4VIDEOEDITING_k11025_ASF:
4090                             pC->AudioEncParams.Frequency = M4ENCODER_k11025Hz;
4091                             break;
4092 
4093                         case M4VIDEOEDITING_k12000_ASF:
4094                             pC->AudioEncParams.Frequency = M4ENCODER_k12000Hz;
4095                             break;
4096 
4097                         case M4VIDEOEDITING_k16000_ASF:
4098                             pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
4099                             break;
4100 
4101                         case M4VIDEOEDITING_k22050_ASF:
4102                             pC->AudioEncParams.Frequency = M4ENCODER_k22050Hz;
4103                             break;
4104 
4105                         case M4VIDEOEDITING_k24000_ASF:
4106                             pC->AudioEncParams.Frequency = M4ENCODER_k24000Hz;
4107                             break;
4108 
4109                         case M4VIDEOEDITING_k32000_ASF:
4110                             pC->AudioEncParams.Frequency = M4ENCODER_k32000Hz;
4111                             break;
4112 
4113                         case M4VIDEOEDITING_k44100_ASF:
4114                             pC->AudioEncParams.Frequency = M4ENCODER_k44100Hz;
4115                             break;
4116 
4117                         case M4VIDEOEDITING_k48000_ASF:
4118                             pC->AudioEncParams.Frequency = M4ENCODER_k48000Hz;
4119                             break;
4120 
4121                         case M4VIDEOEDITING_kDefault_ASF:
4122                             break;
4123                     }
4124 
4125                     break;
4126 
4127                 case M4VIDEOEDITING_kNullAudio:
4128                     if( pParams->pEffects == M4OSA_NULL || pParams->nbEffects == 0 )
4129                     {
4130                         /* no encoder needed */
4131                         pC->AudioEncParams.Format = M4ENCODER_kAudioNULL;
4132                         pC->AudioEncParams.Frequency =
4133                             pC->pReaderAudioStream->m_samplingFrequency;
4134                         pC->AudioEncParams.ChannelNum =
4135                             (pC->pReaderAudioStream->m_nbChannels == 1) ? \
4136                             M4ENCODER_kMono : M4ENCODER_kStereo;
4137                     }
4138                     else
4139                     {
4140                         pC->AudioEncParams.Frequency =
4141                             pC->pReaderAudioStream->m_samplingFrequency;
4142                         pC->AudioEncParams.ChannelNum =
4143                             (pC->pReaderAudioStream->m_nbChannels == 1) ? \
4144                             M4ENCODER_kMono : M4ENCODER_kStereo;
4145 
4146                         switch( pC->InputFileProperties.AudioStreamType )
4147                         {
4148                             case M4VIDEOEDITING_kAMR_NB:
4149                                 M4OSA_TRACE3_0(
4150                                     "M4MCS_setOutputParams calling \
4151                                     M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, AMR");
4152                                 err = M4MCS_setCurrentAudioEncoder(pContext,
4153                                     pC->InputFileProperties.AudioStreamType);
4154                                 M4ERR_CHECK_RETURN(err);
4155 
4156                                 pC->AudioEncParams.Format = M4ENCODER_kAMRNB;
4157                                 pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
4158                                 pC->AudioEncParams.ChannelNum = M4ENCODER_kMono;
4159 
4160                                 if( pC->pReaderAudioStream->m_samplingFrequency
4161                                     != 8000 )
4162                                 {
4163                                     pC->AudioEncParams.Format = M4ENCODER_kAMRNB;
4164                                 }
4165                                 pC->AudioEncParams.SpecifParam.AmrSID =
4166                                     M4ENCODER_kAmrNoSID;
4167                                 break;
4168 
4169                             case M4VIDEOEDITING_kAAC:
4170                                 M4OSA_TRACE3_0(
4171                                     "M4MCS_setOutputParams calling \
4172                                     M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, AAC");
4173                                 err = M4MCS_setCurrentAudioEncoder(pContext,
4174                                     pC->InputFileProperties.AudioStreamType);
4175                                 M4ERR_CHECK_RETURN(err);
4176 
4177                                 pC->AudioEncParams.Format = M4ENCODER_kAAC;
4178                                 pC->AudioEncParams.SpecifParam.AacParam.Regulation =
4179                                     M4ENCODER_kAacRegulNone; //M4ENCODER_kAacBitReservoir
4180                                 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
4181                                 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
4182 
4183                                 switch( pC->pReaderAudioStream->
4184                                     m_samplingFrequency )
4185                                 {
4186                                 case 16000:
4187                                     pC->AudioEncParams.Frequency =
4188                                         M4ENCODER_k16000Hz;
4189                                     break;
4190 
4191                                 case 22050:
4192                                     pC->AudioEncParams.Frequency =
4193                                         M4ENCODER_k22050Hz;
4194                                     break;
4195 
4196                                 case 24000:
4197                                     pC->AudioEncParams.Frequency =
4198                                         M4ENCODER_k24000Hz;
4199                                     break;
4200 
4201                                 case 32000:
4202                                     pC->AudioEncParams.Frequency =
4203                                         M4ENCODER_k32000Hz;
4204                                     break;
4205 
4206                                 case 44100:
4207                                     pC->AudioEncParams.Frequency =
4208                                         M4ENCODER_k44100Hz;
4209                                     break;
4210 
4211                                 case 48000:
4212                                     pC->AudioEncParams.Frequency =
4213                                         M4ENCODER_k48000Hz;
4214                                     break;
4215 
4216                                 default:
4217                                     pC->AudioEncParams.Format = M4ENCODER_kAAC;
4218                                     break;
4219                             }
4220                             /* unused */
4221                             pC->AudioEncParams.SpecifParam.AacParam.bIS =
4222                                 M4OSA_FALSE;
4223                             pC->AudioEncParams.SpecifParam.AacParam.bMS =
4224                                 M4OSA_FALSE;
4225                             pC->AudioEncParams.SpecifParam.AacParam.bPNS =
4226                                 M4OSA_FALSE;
4227                             pC->AudioEncParams.SpecifParam.AacParam.bTNS =
4228                                 M4OSA_FALSE;
4229                             /* TODO change into highspeed asap */
4230                             pC->AudioEncParams.SpecifParam.AacParam.bHighSpeed =
4231                                 M4OSA_FALSE;
4232                             break;
4233 
4234                         case M4VIDEOEDITING_kMP3:
4235                             M4OSA_TRACE3_0(
4236                                 "M4MCS_setOutputParams calling\
4237                                 M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, MP3");
4238                             err = M4MCS_setCurrentAudioEncoder(pContext,
4239                                 pC->InputFileProperties.AudioStreamType);
4240                             M4ERR_CHECK_RETURN(err);
4241 
4242                             pC->AudioEncParams.Format = M4ENCODER_kMP3;
4243                             pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
4244 
4245                             switch( pC->pReaderAudioStream->
4246                                 m_samplingFrequency )
4247                             {
4248                                 case 8000:
4249                                     pC->AudioEncParams.Frequency =
4250                                         M4ENCODER_k8000Hz;
4251                                     break;
4252 
4253                                 case 16000:
4254                                     pC->AudioEncParams.Frequency =
4255                                         M4ENCODER_k16000Hz;
4256                                     break;
4257 
4258                                 case 22050:
4259                                     pC->AudioEncParams.Frequency =
4260                                         M4ENCODER_k22050Hz;
4261                                     break;
4262 
4263                                 case 24000:
4264                                     pC->AudioEncParams.Frequency =
4265                                         M4ENCODER_k24000Hz;
4266                                     break;
4267 
4268                                 case 32000:
4269                                     pC->AudioEncParams.Frequency =
4270                                         M4ENCODER_k32000Hz;
4271                                     break;
4272 
4273                                 case 44100:
4274                                     pC->AudioEncParams.Frequency =
4275                                         M4ENCODER_k44100Hz;
4276                                     break;
4277 
4278                                 case 48000:
4279                                     pC->AudioEncParams.Frequency =
4280                                         M4ENCODER_k48000Hz;
4281                                     break;
4282 
4283                                 default:
4284                                     pC->AudioEncParams.Format = M4ENCODER_kMP3;
4285                                     break;
4286                             }
4287                             break;
4288 
4289                         case M4VIDEOEDITING_kEVRC:
4290                         case M4VIDEOEDITING_kUnsupportedAudio:
4291                         default:
4292                             M4OSA_TRACE1_1(
4293                                 "M4MCS_setOutputParams: Output audio format (%d) is\
4294                                 incompatible with audio effects, returning \
4295                                 M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT",
4296                                 pC->InputFileProperties.AudioStreamType);
4297                             return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT;
4298                         }
4299                     }
4300                     break;
4301                     /* EVRC
4302                     //            case M4VIDEOEDITING_kEVRC:
4303                     //
4304                     //                err = M4MCS_setCurrentAudioEncoder(pContext, pParams->\
4305                     //                    OutputAudioFormat);
4306                     //                M4ERR_CHECK_RETURN(err);
4307                     //
4308                     //                pC->AudioEncParams.Format = M4ENCODER_kEVRC;
4309                     //                pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
4310                     //                pC->AudioEncParams.ChannelNum = M4ENCODER_kMono;
4311                     //                break; */
4312 
4313                 default:
4314                     M4OSA_TRACE1_1("M4MCS_setOutputParams: Undefined output audio format (%d),\
4315                                    returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT",
4316                                    pParams->OutputAudioFormat);
4317                     return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT;
4318         }
4319     }
4320 
4321     if( pParams->pOutputPCMfile != M4OSA_NULL )
4322     {
4323         pC->pOutputPCMfile = pParams->pOutputPCMfile;
4324 
4325         /* Open output PCM file */
4326         pC->pOsaFileWritPtr->openWrite(&(pC->pOutputPCMfile),
4327             pParams->pOutputPCMfile, M4OSA_kFileWrite);
4328     }
4329     else
4330     {
4331         pC->pOutputPCMfile = M4OSA_NULL;
4332     }
4333 
4334     /*Store media rendering parameter into the internal context*/
4335     pC->MediaRendering = pParams->MediaRendering;
4336 
4337     /* Add audio effects*/
4338     /*Copy MCS effects structure into internal context*/
4339     if( pParams->nbEffects > 0 )
4340     {
4341         M4OSA_UInt32 j = 0;
4342         pC->nbEffects = pParams->nbEffects;
4343         pC->pEffects = (M4MCS_EffectSettings *)M4OSA_32bitAlignedMalloc(pC->nbEffects \
4344             *sizeof(M4MCS_EffectSettings), M4MCS,
4345             (M4OSA_Char *)"Allocation of effects list");
4346 
4347         if( pC->pEffects == M4OSA_NULL )
4348         {
4349             M4OSA_TRACE1_0("M4MCS_setOutputParams(): allocation error");
4350             return M4ERR_ALLOC;
4351         }
4352 
4353         for ( j = 0; j < pC->nbEffects; j++ )
4354         {
4355             /* Copy effect to "local" structure */
4356             memcpy((void *) &(pC->pEffects[j]),
4357                 (void *) &(pParams->pEffects[j]),
4358                 sizeof(M4MCS_EffectSettings));
4359 
4360             switch( pC->pEffects[j].AudioEffectType )
4361             {
4362                 case M4MCS_kAudioEffectType_None:
4363                     M4OSA_TRACE3_1(
4364                         "M4MCS_setOutputParams(): effect type %i is None", j);
4365                     pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL;
4366                     pC->pEffects[j].ExtAudioEffectFct = M4OSA_NULL;
4367                     break;
4368 
4369                 case M4MCS_kAudioEffectType_FadeIn:
4370                     M4OSA_TRACE3_1(
4371                         "M4MCS_setOutputParams(): effect type %i is FadeIn", j);
4372                     pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL;
4373                     pC->pEffects[j].ExtAudioEffectFct =
4374                         M4MCS_editAudioEffectFct_FadeIn;
4375                     break;
4376 
4377                 case M4MCS_kAudioEffectType_FadeOut:
4378                     M4OSA_TRACE3_1(
4379                         "M4MCS_setOutputParams(): effect type %i is FadeOut",
4380                         j);
4381                     pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL;
4382                     pC->pEffects[j].ExtAudioEffectFct =
4383                         M4MCS_editAudioEffectFct_FadeOut;
4384                     break;
4385 
4386                 case M4MCS_kAudioEffectType_External:
4387                     M4OSA_TRACE3_1(
4388                         "M4MCS_setOutputParams(): effect type %i is External",
4389                         j);
4390 
4391                     if( pParams->pEffects != M4OSA_NULL )
4392                     {
4393                         if( pParams->pEffects[j].ExtAudioEffectFct
4394                             == M4OSA_NULL )
4395                         {
4396                             M4OSA_TRACE1_1("M4MCS_setOutputParams(): no external effect function\
4397                                            associated to external effect number %i", j);
4398                             return M4ERR_PARAMETER;
4399                         }
4400                         pC->pEffects[j].pExtAudioEffectFctCtxt =
4401                             pParams->pEffects[j].pExtAudioEffectFctCtxt;
4402 
4403                         pC->pEffects[j].ExtAudioEffectFct =
4404                             pParams->pEffects[j].ExtAudioEffectFct;
4405                     }
4406 
4407                     break;
4408 
4409                 default:
4410                     M4OSA_TRACE1_0(
4411                         "M4MCS_setOutputParams(): effect type not recognized");
4412                     return M4ERR_PARAMETER;
4413             }
4414         }
4415     }
4416     else
4417     {
4418         pC->nbEffects = 0;
4419         pC->pEffects = M4OSA_NULL;
4420     }
4421 
4422     /**
4423     * Update state automaton */
4424     pC->State = M4MCS_kState_SET;
4425 
4426     /**
4427     * Return with no error */
4428     M4OSA_TRACE3_0("M4MCS_setOutputParams(): returning M4NO_ERROR");
4429     return M4NO_ERROR;
4430 }
4431 
4432 /**
4433  ******************************************************************************
4434  * M4OSA_ERR M4MCS_setEncodingParams(M4MCS_Context pContext, M4MCS_EncodingParams* pRates)
4435  * @brief   Set the values of the encoding parameters
4436  * @note    Must be called before M4MCS_checkParamsAndStart().
4437  * @param   pContext           (IN) MCS context
4438  * @param   pRates             (IN) Transcoding parameters
4439  * @return  M4NO_ERROR:         No error
4440  * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
4441  * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
4442  * @return  M4MCS_ERR_AUDIOBITRATE_TOO_HIGH: Audio bitrate too high (we limit to 96 kbps)
4443  * @return  M4MCS_ERR_AUDIOBITRATE_TOO_LOW: Audio bitrate is too low (16 kbps min for aac, 12.2
4444  *                                            for amr, 8 for mp3)
4445  * @return  M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: Begin cut and End cut are equals
4446  * @return  M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION: Begin cut time is larger than the input clip
4447  *                                                     duration
4448  * @return  M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT: End cut time is smaller than begin cut time
4449  * @return  M4MCS_ERR_MAXFILESIZE_TOO_SMALL: Not enough space to store whole output file at given
4450  *                                             bitrates
4451  * @return  M4MCS_ERR_VIDEOBITRATE_TOO_HIGH: Video bitrate too high (we limit to 800 kbps)
4452  * @return  M4MCS_ERR_VIDEOBITRATE_TOO_LOW:  Video bitrate too low
4453  ******************************************************************************
4454  */
M4MCS_setEncodingParams(M4MCS_Context pContext,M4MCS_EncodingParams * pRates)4455 M4OSA_ERR M4MCS_setEncodingParams( M4MCS_Context pContext,
4456                                   M4MCS_EncodingParams *pRates )
4457 {
4458     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
4459     M4OSA_UInt32 j = 0;
4460 
4461     M4OSA_TRACE2_2(
4462         "M4MCS_setEncodingParams called with pContext=0x%x, pRates=0x%x",
4463         pContext, pRates);
4464 
4465     /**
4466     * Check input parameters */
4467     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
4468         "M4MCS_setEncodingParams: pContext is M4OSA_NULL");
4469     M4OSA_DEBUG_IF2((M4OSA_NULL == pRates), M4ERR_PARAMETER,
4470         "M4MCS_setEncodingParams: pRates is M4OSA_NULL");
4471 
4472 #ifdef M4MCS_SUPPORT_STILL_PICTURE
4473 
4474     if( pC->m_bIsStillPicture )
4475     {
4476         /**
4477         * Call the corresponding still picture MCS function*/
4478         return M4MCS_stillPicSetEncodingParams(pC, pRates);
4479     }
4480 
4481 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
4482 
4483     /**
4484     * Check state automaton */
4485 
4486     if( M4MCS_kState_SET != pC->State )
4487     {
4488         M4OSA_TRACE1_1(
4489             "M4MCS_setEncodingParams(): Wrong State (%d), returning M4ERR_STATE",
4490             pC->State);
4491         return M4ERR_STATE;
4492     }
4493 
4494     /* Set given values */
4495     pC->uiVideoBitrate = pRates->OutputVideoBitrate;
4496     pC->uiAudioBitrate = pRates->OutputAudioBitrate;
4497     pC->uiBeginCutTime = pRates->BeginCutTime;
4498     pC->uiEndCutTime = pRates->EndCutTime;
4499     pC->uiMaxFileSize = pRates->OutputFileSize;
4500 
4501     /**
4502     * Check begin cut time validity */
4503     if( pC->uiBeginCutTime >= pC->InputFileProperties.uiClipDuration )
4504     {
4505         M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin cut larger than duration (%d>%d),\
4506                        returning M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION",
4507                        pC->uiBeginCutTime, pC->InputFileProperties.uiClipDuration);
4508         return M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION;
4509     }
4510 
4511     /**
4512     * If end cut time is too large, we set it to the clip duration */
4513     if( pC->uiEndCutTime > pC->InputFileProperties.uiClipDuration )
4514     {
4515         pC->uiEndCutTime = pC->InputFileProperties.uiClipDuration;
4516     }
4517 
4518     /**
4519     * Check end cut time validity */
4520     if( pC->uiEndCutTime > 0 )
4521     {
4522         if( pC->uiEndCutTime < pC->uiBeginCutTime )
4523         {
4524             M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin cut greater than end cut (%d,%d), \
4525                            returning M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT",
4526                            pC->uiBeginCutTime, pC->uiEndCutTime);
4527             return M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT;
4528         }
4529 
4530         if( pC->uiEndCutTime == pC->uiBeginCutTime )
4531         {
4532             M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin and End cuts are equal (%d,%d),\
4533                            returning M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT",
4534                            pC->uiBeginCutTime, pC->uiEndCutTime);
4535             return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
4536         }
4537     }
4538 
4539     /**
4540     * FlB 2009.03.04: check audio effects start time and duration validity*/
4541     for ( j = 0; j < pC->nbEffects; j++ )
4542     {
4543         M4OSA_UInt32 outputEndCut = pC->uiEndCutTime;
4544 
4545         if( pC->uiEndCutTime == 0 )
4546         {
4547             outputEndCut = pC->InputFileProperties.uiClipDuration;
4548         }
4549 
4550         if( pC->pEffects[j].uiStartTime > (outputEndCut - pC->uiBeginCutTime) )
4551         {
4552             M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Effects start time is larger than\
4553                            duration (%d,%d), returning M4ERR_PARAMETER",
4554                            pC->pEffects[j].uiStartTime,
4555                            (pC->uiEndCutTime - pC->uiBeginCutTime));
4556             return M4ERR_PARAMETER;
4557         }
4558 
4559         if( pC->pEffects[j].uiStartTime + pC->pEffects[j].uiDuration > \
4560             (outputEndCut - pC->uiBeginCutTime) )
4561         {
4562             /* Re-adjust the effect duration until the end of the output clip*/
4563             pC->pEffects[j].uiDuration = (outputEndCut - pC->uiBeginCutTime) - \
4564                 pC->pEffects[j].uiStartTime;
4565         }
4566     }
4567 
4568     /* Check audio bitrate consistency */
4569     if( ( pC->noaudio == M4OSA_FALSE)
4570         && (pC->AudioEncParams.Format != M4ENCODER_kAudioNULL) )
4571     {
4572         if( pC->uiAudioBitrate != M4VIDEOEDITING_kUndefinedBitrate )
4573         {
4574             if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB )
4575             {
4576                 if( pC->uiAudioBitrate > M4VIDEOEDITING_k12_2_KBPS )
4577                     return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
4578 
4579                 if( pC->uiAudioBitrate < M4VIDEOEDITING_k12_2_KBPS )
4580                     return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4581             }
4582             //EVRC
4583             //            else if(pC->AudioEncParams.Format == M4ENCODER_kEVRC)
4584             //            {
4585             //                if(pC->uiAudioBitrate > M4VIDEOEDITING_k9_2_KBPS)
4586             //                    return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
4587             //                if(pC->uiAudioBitrate < M4VIDEOEDITING_k9_2_KBPS)
4588             //                     return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4589             //            }
4590             /*FlB 26.02.2009: add mp3 as mcs output format, add mp3 encoder*/
4591             else if( pC->AudioEncParams.Format == M4ENCODER_kMP3 )
4592             {
4593                 if( pC->AudioEncParams.Frequency >= M4ENCODER_k32000Hz )
4594                 {
4595                     /*Mpeg layer 1*/
4596                     if( pC->uiAudioBitrate > 320000 )
4597                         return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
4598 
4599                     if( pC->uiAudioBitrate < 32000 )
4600                         return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4601                 }
4602                 else if( pC->AudioEncParams.Frequency >= M4ENCODER_k16000Hz )
4603                 {
4604                     /*Mpeg layer 2*/
4605                     if( pC->uiAudioBitrate > 160000 )
4606                         return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
4607 
4608                     if( ( pC->uiAudioBitrate < 8000
4609                         && pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
4610                         || (pC->uiAudioBitrate < 16000
4611                         && pC->AudioEncParams.ChannelNum
4612                         == M4ENCODER_kStereo) )
4613                         return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4614                 }
4615                 else if( pC->AudioEncParams.Frequency == M4ENCODER_k8000Hz
4616                     || pC->AudioEncParams.Frequency == M4ENCODER_k11025Hz
4617                     || pC->AudioEncParams.Frequency == M4ENCODER_k12000Hz )
4618                 {
4619                     /*Mpeg layer 2.5*/
4620                     if( pC->uiAudioBitrate > 64000 )
4621                         return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
4622 
4623                     if( ( pC->uiAudioBitrate < 8000
4624                         && pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
4625                         || (pC->uiAudioBitrate < 16000
4626                         && pC->AudioEncParams.ChannelNum
4627                         == M4ENCODER_kStereo) )
4628                         return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4629                 }
4630                 else
4631                 {
4632                     M4OSA_TRACE1_1("M4MCS_setEncodingParams: MP3 audio sampling frequency error\
4633                                    (%d)", pC->AudioEncParams.Frequency);
4634                     return M4ERR_PARAMETER;
4635                 }
4636             }
4637             else
4638             {
4639                 if( pC->uiAudioBitrate > M4VIDEOEDITING_k192_KBPS )
4640                     return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
4641 
4642                 if( pC->AudioEncParams.ChannelNum == M4ENCODER_kMono )
4643                 {
4644                     if( pC->uiAudioBitrate < M4VIDEOEDITING_k16_KBPS )
4645                         return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4646                 }
4647                 else
4648                 {
4649                     if( pC->uiAudioBitrate < M4VIDEOEDITING_k32_KBPS )
4650                         return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
4651                 }
4652             }
4653         }
4654     }
4655     else
4656     {
4657         /* NULL audio : copy input file bitrate */
4658         pC->uiAudioBitrate = pC->InputFileProperties.uiAudioBitrate;
4659     }
4660 
4661     /* Check video bitrate consistency */
4662     if( ( pC->novideo == M4OSA_FALSE)
4663         && (pC->EncodingVideoFormat != M4ENCODER_kNULL) )
4664     {
4665         if( pC->uiVideoBitrate != M4VIDEOEDITING_kUndefinedBitrate )
4666         {
4667             if( pC->uiVideoBitrate > M4VIDEOEDITING_k8_MBPS )
4668                 return M4MCS_ERR_VIDEOBITRATE_TOO_HIGH;
4669 
4670             if( pC->uiVideoBitrate < M4VIDEOEDITING_k16_KBPS )
4671                 return M4MCS_ERR_VIDEOBITRATE_TOO_LOW;
4672         }
4673     }
4674     else
4675     {
4676         /* NULL video : copy input file bitrate */
4677         pC->uiVideoBitrate = pC->InputFileProperties.uiVideoBitrate;
4678     }
4679 
4680     if( pRates->OutputVideoTimescale <= 30000
4681         && pRates->OutputVideoTimescale > 0 )
4682     {
4683         pC->outputVideoTimescale = pRates->OutputVideoTimescale;
4684     }
4685 
4686     /* Check file size */
4687     return M4MCS_intCheckMaxFileSize(pC);
4688 }
4689 
4690 /**
4691  ******************************************************************************
4692  * M4OSA_ERR M4MCS_getExtendedEncodingParams(M4MCS_Context pContext, M4MCS_EncodingParams* pRates)
4693  * @brief   Get the extended values of the encoding parameters
4694  * @note    Could be called after M4MCS_setEncodingParams.
4695  * @param   pContext           (IN) MCS context
4696  * @param   pRates             (OUT) Transcoding parameters
4697  * @return  M4NO_ERROR:         No error
4698  * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
4699  * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
4700  * @return  M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: Encoding settings would produce a null duration
4701  *                                             clip = encoding is impossible
4702  ******************************************************************************
4703  */
M4MCS_getExtendedEncodingParams(M4MCS_Context pContext,M4MCS_EncodingParams * pRates)4704 M4OSA_ERR M4MCS_getExtendedEncodingParams( M4MCS_Context pContext,
4705                                           M4MCS_EncodingParams *pRates )
4706 {
4707     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
4708 
4709     M4OSA_Int32 minaudiobitrate;
4710     M4OSA_Int32 minvideobitrate;
4711     M4OSA_Int32 maxcombinedbitrate;
4712 
4713     M4OSA_Int32 calcbitrate;
4714 
4715     M4OSA_UInt32 maxduration;
4716     M4OSA_UInt32 calcduration;
4717 
4718     M4OSA_Bool fixed_audio = M4OSA_FALSE;
4719     M4OSA_Bool fixed_video = M4OSA_FALSE;
4720 
4721 #ifdef M4MCS_SUPPORT_STILL_PICTURE
4722 
4723     if( pC->m_bIsStillPicture )
4724     {
4725         /**
4726         * Call the corresponding still picture MCS function*/
4727         return M4MCS_stillPicGetExtendedEncodingParams(pC, pRates);
4728     }
4729 
4730 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
4731 
4732     pRates->OutputVideoBitrate =
4733         M4MCS_intGetNearestBitrate(pC->uiVideoBitrate, 0);
4734     pRates->OutputAudioBitrate =
4735         M4MCS_intGetNearestBitrate(pC->uiAudioBitrate, 0);
4736     pRates->BeginCutTime = pC->uiBeginCutTime;
4737     pRates->EndCutTime = pC->uiEndCutTime;
4738     pRates->OutputFileSize = pC->uiMaxFileSize;
4739 
4740     /**
4741     * Check state automaton */
4742     if( M4MCS_kState_SET != pC->State )
4743     {
4744         M4OSA_TRACE1_1("M4MCS_getExtendedEncodingParams(): Wrong State (%d),\
4745                        returning M4ERR_STATE", pC->State);
4746         return M4ERR_STATE;
4747     }
4748 
4749     /* Compute min audio bitrate */
4750     if( pC->noaudio )
4751     {
4752         fixed_audio = M4OSA_TRUE;
4753         pRates->OutputAudioBitrate = 0;
4754         minaudiobitrate = 0;
4755     }
4756     else if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
4757     {
4758         fixed_audio = M4OSA_TRUE;
4759         pRates->OutputAudioBitrate = pC->InputFileProperties.uiAudioBitrate;
4760         minaudiobitrate = pC->InputFileProperties.uiAudioBitrate;
4761     }
4762     else
4763     {
4764         if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB )
4765         {
4766             fixed_audio = M4OSA_TRUE;
4767             pRates->OutputAudioBitrate = M4VIDEOEDITING_k12_2_KBPS;
4768             minaudiobitrate = M4VIDEOEDITING_k12_2_KBPS;
4769         }
4770         //EVRC
4771         //        if(pC->AudioEncParams.Format == M4ENCODER_kEVRC)
4772         //        {
4773         //            fixed_audio = M4OSA_TRUE;
4774         //            pRates->OutputAudioBitrate = M4VIDEOEDITING_k9_2_KBPS;
4775         //            minaudiobitrate = M4VIDEOEDITING_k9_2_KBPS;
4776         //        }
4777         /*FlB 26.02.2009: add mp3 as mcs output format*/
4778         else if( pC->AudioEncParams.Format == M4ENCODER_kMP3 )
4779         {
4780             minaudiobitrate =
4781                 M4VIDEOEDITING_k32_KBPS; /*Default min audio bitrate for MPEG layer 1,
4782                                              for both mono and stereo channels*/
4783         }
4784         else
4785         {
4786             minaudiobitrate = (pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
4787                 ? M4VIDEOEDITING_k16_KBPS : M4VIDEOEDITING_k32_KBPS;
4788         }
4789     }
4790 
4791     /* Check audio bitrate is in the correct range */
4792     if( fixed_audio == M4OSA_FALSE )
4793     {
4794         if( ( pC->uiAudioBitrate > 0)
4795             && (pRates->OutputAudioBitrate < minaudiobitrate) )
4796         {
4797             pRates->OutputAudioBitrate = minaudiobitrate;
4798         }
4799 
4800         if( pRates->OutputAudioBitrate > M4VIDEOEDITING_k96_KBPS )
4801         {
4802             pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS;
4803         }
4804     }
4805 
4806     /* Compute min video bitrate */
4807     if( pC->novideo )
4808     {
4809         fixed_video = M4OSA_TRUE;
4810         pRates->OutputVideoBitrate = 0;
4811         minvideobitrate = 0;
4812     }
4813     else if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
4814     {
4815         fixed_video = M4OSA_TRUE;
4816         pRates->OutputVideoBitrate = pC->InputFileProperties.uiVideoBitrate;
4817         minvideobitrate = pC->InputFileProperties.uiVideoBitrate;
4818     }
4819     else
4820     {
4821         minvideobitrate = M4VIDEOEDITING_k16_KBPS;
4822     }
4823 
4824     /* Check video bitrate is in the correct range */
4825     if( fixed_video == M4OSA_FALSE )
4826     {
4827         if( ( pC->uiVideoBitrate > 0)
4828             && (pRates->OutputVideoBitrate < minvideobitrate) )
4829         {
4830             pRates->OutputVideoBitrate = minvideobitrate;
4831         }
4832         /*+ New Encoder bitrates */
4833         if( pRates->OutputVideoBitrate > M4VIDEOEDITING_k8_MBPS )
4834         {
4835             pRates->OutputVideoBitrate = M4VIDEOEDITING_k8_MBPS;
4836         }
4837         /*- New Encoder bitrates */
4838     }
4839 
4840     /* Check cut times are in correct range */
4841     if( ( pRates->BeginCutTime >= pC->InputFileProperties.uiClipDuration)
4842         || (( pRates->BeginCutTime >= pRates->EndCutTime)
4843         && (pRates->EndCutTime > 0)) )
4844     {
4845         pRates->BeginCutTime = 0;
4846         pRates->EndCutTime = 0;
4847     }
4848 
4849     if( pRates->EndCutTime == 0 )
4850         calcduration =
4851         pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime;
4852     else
4853         calcduration = pRates->EndCutTime - pRates->BeginCutTime;
4854 
4855     /* priority 1 : max file size */
4856     if( pRates->OutputFileSize == 0 )
4857     {
4858         /* we can put maximum values for all undefined parameters */
4859         if( pRates->EndCutTime == 0 )
4860         {
4861             pRates->EndCutTime = pC->InputFileProperties.uiClipDuration;
4862         }
4863 
4864         if( ( pRates->OutputAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate)
4865             && (fixed_audio == M4OSA_FALSE) )
4866         {
4867             pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS;
4868         }
4869 
4870         if( ( pRates->OutputVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate)
4871             && (fixed_video == M4OSA_FALSE) )
4872         {
4873             /*+ New Encoder bitrates */
4874             pRates->OutputVideoBitrate = M4VIDEOEDITING_k8_MBPS;
4875             /*- New Encoder bitrates */
4876         }
4877     }
4878     else
4879     {
4880         /* compute max duration */
4881         maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
4882             / M4MCS_MOOV_OVER_FILESIZE_RATIO
4883             / (minvideobitrate + minaudiobitrate) * 8000.0);
4884 
4885         if( maxduration
4886             + pRates->BeginCutTime > pC->InputFileProperties.uiClipDuration )
4887         {
4888             maxduration =
4889                 pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime;
4890         }
4891 
4892         /* priority 2 : cut times */
4893         if( ( pRates->BeginCutTime > 0) || (pRates->EndCutTime > 0) )
4894         {
4895             if( calcduration > maxduration )
4896             {
4897                 calcduration = maxduration;
4898             }
4899 
4900             if( calcduration == 0 )
4901             {
4902                 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
4903             }
4904 
4905             maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize
4906                 / M4MCS_MOOV_OVER_FILESIZE_RATIO / (calcduration / 8000.0));
4907 
4908             /* audio and video bitrates */
4909             if( ( pRates->OutputAudioBitrate
4910                 == M4VIDEOEDITING_kUndefinedBitrate)
4911                 && (pRates->OutputVideoBitrate
4912                 == M4VIDEOEDITING_kUndefinedBitrate) )
4913             {
4914                 /* set audio = 1/3 and video = 2/3 */
4915                 if( fixed_audio == M4OSA_FALSE )
4916                 {
4917                     if( pC->novideo )
4918                         pRates->OutputAudioBitrate =
4919                         M4MCS_intGetNearestBitrate(maxcombinedbitrate, 0);
4920                     else
4921                         pRates->OutputAudioBitrate =
4922                         M4MCS_intGetNearestBitrate(maxcombinedbitrate / 3,
4923                         0);
4924 
4925                     if( pRates->OutputAudioBitrate < minaudiobitrate )
4926                         pRates->OutputAudioBitrate = minaudiobitrate;
4927 
4928                     if( pRates->OutputAudioBitrate > M4VIDEOEDITING_k96_KBPS )
4929                         pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS;
4930                 }
4931 
4932                 if( fixed_video == M4OSA_FALSE )
4933                 {
4934                     pRates->OutputVideoBitrate =
4935                         M4MCS_intGetNearestBitrate(maxcombinedbitrate
4936                         - pRates->OutputAudioBitrate, 0);
4937 
4938                     if( pRates->OutputVideoBitrate < minvideobitrate )
4939                         pRates->OutputVideoBitrate = minvideobitrate;
4940 
4941                     if( pRates->OutputVideoBitrate > M4VIDEOEDITING_k8_MBPS )
4942                         pRates->OutputVideoBitrate =
4943                         M4VIDEOEDITING_k8_MBPS; /*+ New Encoder
4944                                                 bitrates */
4945                 }
4946             }
4947             else
4948             {
4949                 /* priority 3 : audio bitrate */
4950                 if( pRates->OutputAudioBitrate
4951                     != M4VIDEOEDITING_kUndefinedBitrate )
4952                 {
4953                     while( ( fixed_audio == M4OSA_FALSE)
4954                         && (pRates->OutputAudioBitrate >= minaudiobitrate)
4955                         && (pRates->OutputAudioBitrate
4956                         + minvideobitrate > maxcombinedbitrate) )
4957                     {
4958                         pRates->OutputAudioBitrate =
4959                             M4MCS_intGetNearestBitrate(
4960                             pRates->OutputAudioBitrate, -1);
4961                     }
4962 
4963                     if( ( fixed_audio == M4OSA_FALSE)
4964                         && (pRates->OutputAudioBitrate < minaudiobitrate) )
4965                     {
4966                         pRates->OutputAudioBitrate = minaudiobitrate;
4967                     }
4968 
4969                     calcbitrate = M4MCS_intGetNearestBitrate(
4970                                     maxcombinedbitrate
4971                                     - pRates->OutputAudioBitrate, 0);
4972 
4973                     if( calcbitrate < minvideobitrate )
4974                         calcbitrate = minvideobitrate;
4975 
4976                     if( calcbitrate > M4VIDEOEDITING_k8_MBPS )
4977                         calcbitrate = M4VIDEOEDITING_k8_MBPS;
4978 
4979                     if( ( fixed_video == M4OSA_FALSE)
4980                         && (( pRates->OutputVideoBitrate
4981                         == M4VIDEOEDITING_kUndefinedBitrate)
4982                         || (pRates->OutputVideoBitrate > calcbitrate)) )
4983                     {
4984                         pRates->OutputVideoBitrate = calcbitrate;
4985                     }
4986                 }
4987                 else
4988                 {
4989                     /* priority 4 : video bitrate */
4990                     if( pRates->OutputVideoBitrate
4991                         != M4VIDEOEDITING_kUndefinedBitrate )
4992                     {
4993                         while( ( fixed_video == M4OSA_FALSE)
4994                             && (pRates->OutputVideoBitrate >= minvideobitrate)
4995                             && (pRates->OutputVideoBitrate
4996                             + minaudiobitrate > maxcombinedbitrate) )
4997                         {
4998                             pRates->OutputVideoBitrate =
4999                                 M4MCS_intGetNearestBitrate(
5000                                 pRates->OutputVideoBitrate, -1);
5001                         }
5002 
5003                         if( ( fixed_video == M4OSA_FALSE)
5004                             && (pRates->OutputVideoBitrate < minvideobitrate) )
5005                         {
5006                             pRates->OutputVideoBitrate = minvideobitrate;
5007                         }
5008 
5009                         calcbitrate =
5010                             M4MCS_intGetNearestBitrate(maxcombinedbitrate
5011                             - pRates->OutputVideoBitrate, 0);
5012 
5013                         if( calcbitrate < minaudiobitrate )
5014                             calcbitrate = minaudiobitrate;
5015 
5016                         if( calcbitrate > M4VIDEOEDITING_k96_KBPS )
5017                             calcbitrate = M4VIDEOEDITING_k96_KBPS;
5018 
5019                         if( ( fixed_audio == M4OSA_FALSE)
5020                             && (( pRates->OutputAudioBitrate
5021                             == M4VIDEOEDITING_kUndefinedBitrate)
5022                             || (pRates->OutputAudioBitrate > calcbitrate)) )
5023                         {
5024                             pRates->OutputAudioBitrate = calcbitrate;
5025                         }
5026                     }
5027                 }
5028             }
5029         }
5030         else
5031         {
5032             /* priority 3 : audio bitrate */
5033             if( pRates->OutputAudioBitrate != M4VIDEOEDITING_kUndefinedBitrate )
5034             {
5035                 /* priority 4 : video bitrate */
5036                 if( pRates->OutputVideoBitrate
5037                     != M4VIDEOEDITING_kUndefinedBitrate )
5038                 {
5039                     /* compute max duration */
5040                     maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
5041                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
5042                         / (pRates->OutputVideoBitrate
5043                         + pRates->OutputAudioBitrate) * 8000.0);
5044 
5045                     if( maxduration + pRates->BeginCutTime
5046                         > pC->InputFileProperties.uiClipDuration )
5047                     {
5048                         maxduration = pC->InputFileProperties.uiClipDuration
5049                             - pRates->BeginCutTime;
5050                     }
5051 
5052                     if( calcduration > maxduration )
5053                     {
5054                         calcduration = maxduration;
5055                     }
5056 
5057                     if( calcduration == 0 )
5058                     {
5059                         return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
5060                     }
5061                 }
5062                 else
5063                 {
5064                     /* start with min video bitrate */
5065                     pRates->OutputVideoBitrate = minvideobitrate;
5066 
5067                     /* compute max duration */
5068                     maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
5069                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
5070                         / (pRates->OutputVideoBitrate
5071                         + pRates->OutputAudioBitrate) * 8000.0);
5072 
5073                     if( maxduration + pRates->BeginCutTime
5074                         > pC->InputFileProperties.uiClipDuration )
5075                     {
5076                         maxduration = pC->InputFileProperties.uiClipDuration
5077                             - pRates->BeginCutTime;
5078                     }
5079 
5080                     if( calcduration > maxduration )
5081                     {
5082                         calcduration = maxduration;
5083                     }
5084 
5085                     if( calcduration == 0 )
5086                     {
5087                         return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
5088                     }
5089 
5090                     /* search max possible video bitrate */
5091                     maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize
5092                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
5093                         / (calcduration / 8000.0));
5094 
5095                     while( ( fixed_video == M4OSA_FALSE)
5096                         && (pRates->OutputVideoBitrate
5097                         < M4VIDEOEDITING_k8_MBPS) ) /*+ New Encoder bitrates */
5098                     {
5099                         calcbitrate = M4MCS_intGetNearestBitrate(
5100                             pRates->OutputVideoBitrate, +1);
5101 
5102                         if( calcbitrate
5103                             + pRates->OutputAudioBitrate <= maxcombinedbitrate )
5104                             pRates->OutputVideoBitrate = calcbitrate;
5105                         else
5106                             break;
5107                     }
5108                 }
5109             }
5110             else
5111             {
5112                 /* priority 4 : video bitrate */
5113                 if( pRates->OutputVideoBitrate
5114                     != M4VIDEOEDITING_kUndefinedBitrate )
5115                 {
5116                     /* start with min audio bitrate */
5117                     pRates->OutputAudioBitrate = minaudiobitrate;
5118 
5119                     /* compute max duration */
5120                     maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
5121                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
5122                         / (pRates->OutputVideoBitrate
5123                         + pRates->OutputAudioBitrate) * 8000.0);
5124 
5125                     if( maxduration + pRates->BeginCutTime
5126                         > pC->InputFileProperties.uiClipDuration )
5127                     {
5128                         maxduration = pC->InputFileProperties.uiClipDuration
5129                             - pRates->BeginCutTime;
5130                     }
5131 
5132                     if( calcduration > maxduration )
5133                     {
5134                         calcduration = maxduration;
5135                     }
5136 
5137                     if( calcduration == 0 )
5138                     {
5139                         return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
5140                     }
5141 
5142                     /* search max possible audio bitrate */
5143                     maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize
5144                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
5145                         / (calcduration / 8000.0));
5146 
5147                     while( ( fixed_audio == M4OSA_FALSE)
5148                         && (pRates->OutputAudioBitrate
5149                         < M4VIDEOEDITING_k96_KBPS) )
5150                     {
5151                         calcbitrate = M4MCS_intGetNearestBitrate(
5152                             pRates->OutputAudioBitrate, +1);
5153 
5154                         if( calcbitrate
5155                             + pRates->OutputVideoBitrate <= maxcombinedbitrate )
5156                             pRates->OutputAudioBitrate = calcbitrate;
5157                         else
5158                             break;
5159                     }
5160                 }
5161                 else
5162                 {
5163                     /* compute max duration */
5164                     maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
5165                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
5166                         / (minvideobitrate + minaudiobitrate) * 8000.0);
5167 
5168                     if( maxduration + pRates->BeginCutTime
5169                         > pC->InputFileProperties.uiClipDuration )
5170                     {
5171                         maxduration = pC->InputFileProperties.uiClipDuration
5172                             - pRates->BeginCutTime;
5173                     }
5174 
5175                     if( calcduration > maxduration )
5176                     {
5177                         calcduration = maxduration;
5178                     }
5179 
5180                     if( calcduration == 0 )
5181                     {
5182                         return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
5183                     }
5184 
5185                     /* set audio = 1/3 and video = 2/3 */
5186                     maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize
5187                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
5188                         / (calcduration / 8000.0));
5189 
5190                     if( fixed_audio == M4OSA_FALSE )
5191                     {
5192                         if( pC->novideo )
5193                             pRates->OutputAudioBitrate =
5194                             M4MCS_intGetNearestBitrate(maxcombinedbitrate,
5195                             0);
5196                         else
5197                             pRates->OutputAudioBitrate =
5198                             M4MCS_intGetNearestBitrate(maxcombinedbitrate
5199                             / 3, 0);
5200 
5201                         if( pRates->OutputAudioBitrate < minaudiobitrate )
5202                             pRates->OutputAudioBitrate = minaudiobitrate;
5203 
5204                         if( pRates->OutputAudioBitrate
5205                         > M4VIDEOEDITING_k96_KBPS )
5206                         pRates->OutputAudioBitrate =
5207                         M4VIDEOEDITING_k96_KBPS;
5208                     }
5209 
5210                     if( fixed_video == M4OSA_FALSE )
5211                     {
5212                         pRates->OutputVideoBitrate =
5213                             M4MCS_intGetNearestBitrate(maxcombinedbitrate
5214                             - pRates->OutputAudioBitrate, 0);
5215 
5216                         if( pRates->OutputVideoBitrate < minvideobitrate )
5217                             pRates->OutputVideoBitrate = minvideobitrate;
5218 
5219                         if( pRates->OutputVideoBitrate
5220                         > M4VIDEOEDITING_k8_MBPS )
5221                         pRates->OutputVideoBitrate =
5222                         M4VIDEOEDITING_k8_MBPS; /*+ New Encoder
5223                                                 bitrates */
5224                     }
5225                 }
5226             }
5227         }
5228     }
5229 
5230     /* recompute max duration with final bitrates */
5231     if( pRates->OutputFileSize > 0 )
5232     {
5233         maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
5234             / M4MCS_MOOV_OVER_FILESIZE_RATIO
5235             / (pRates->OutputVideoBitrate + pRates->OutputAudioBitrate)
5236             * 8000.0);
5237     }
5238     else
5239     {
5240         maxduration = pC->InputFileProperties.uiClipDuration;
5241     }
5242 
5243     if( maxduration
5244         + pRates->BeginCutTime > pC->InputFileProperties.uiClipDuration )
5245     {
5246         maxduration =
5247             pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime;
5248     }
5249 
5250     if( pRates->EndCutTime == 0 )
5251     {
5252         pRates->EndCutTime = pRates->BeginCutTime + maxduration;
5253     }
5254     else
5255     {
5256         calcduration = pRates->EndCutTime - pRates->BeginCutTime;
5257 
5258         if( calcduration > maxduration )
5259         {
5260             pRates->EndCutTime = pRates->BeginCutTime + maxduration;
5261         }
5262     }
5263 
5264     /* Should never happen : constraints are too strong */
5265     if( pRates->EndCutTime == pRates->BeginCutTime )
5266     {
5267         return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
5268     }
5269 
5270     /* estimated resulting file size */
5271     pRates->OutputFileSize = (M4OSA_UInt32)(M4MCS_MOOV_OVER_FILESIZE_RATIO
5272         * (pRates->OutputVideoBitrate + pRates->OutputAudioBitrate)
5273         * (( pRates->EndCutTime - pRates->BeginCutTime) / 8000.0));
5274 
5275     return M4NO_ERROR;
5276 }
5277 
5278 /**
5279  ******************************************************************************
5280  * M4OSA_ERR M4MCS_checkParamsAndStart(M4MCS_Context pContext)
5281  * @brief   Check parameters to start
5282  * @note
5283  * @param   pContext           (IN) MCS context
5284  * @return  M4NO_ERROR:         No error
5285  * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
5286  * @return  M4ERR_STATE:        MCS is not in an appropriate state for
5287  *                              this function to be called
5288  * @return  M4MCS_ERR_AUDIOBITRATE_TOO_HIGH:
5289  *                              Audio bitrate too high (we limit to 96 kbps)
5290  * @return  M4MCS_ERR_AUDIOBITRATE_TOO_LOW:
5291  *                              Audio bitrate is too low (16 kbps min for aac,
5292  *                              12.2 for amr, 8 for mp3)
5293  * @return  M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT:
5294  *                              Begin cut and End cut are equals
5295  * @return  M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION:
5296  *                              Begin cut time is larger than the input
5297  *                              clip duration
5298  * @return  M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT:
5299  *                              End cut time is smaller than begin cut time
5300  * @return  M4MCS_ERR_MAXFILESIZE_TOO_SMALL:
5301  *                              Not enough space to store whole output
5302  *                              file at given bitrates
5303  * @return  M4MCS_ERR_VIDEOBITRATE_TOO_HIGH:
5304  *                              Video bitrate too high (we limit to 800 kbps)
5305  * @return  M4MCS_ERR_VIDEOBITRATE_TOO_LOW:
5306  *                              Video bitrate too low
5307  ******************************************************************************
5308  */
M4MCS_checkParamsAndStart(M4MCS_Context pContext)5309 M4OSA_ERR M4MCS_checkParamsAndStart( M4MCS_Context pContext )
5310 {
5311     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
5312     M4MCS_EncodingParams VerifyRates;
5313     M4OSA_ERR err;
5314 
5315     /**
5316     * Check input parameters */
5317     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
5318         "M4MCS_checkParamsAndStart: pContext is M4OSA_NULL");
5319 
5320 #ifdef M4MCS_SUPPORT_STILL_PICTURE
5321 
5322     if( pC->m_bIsStillPicture )
5323     {
5324         /**
5325         * Call the corresponding still picture MCS function*/
5326         return M4MCS_stillPicCheckParamsAndStart(pC);
5327     }
5328 
5329 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
5330 
5331     /**
5332     * Check state automaton */
5333 
5334     if( M4MCS_kState_SET != pC->State )
5335     {
5336         M4OSA_TRACE1_1(
5337             "M4MCS_checkParamsAndStart(): Wrong State (%d), returning M4ERR_STATE",
5338             pC->State);
5339         return M4ERR_STATE;
5340     }
5341 
5342     /* Audio bitrate should not stay undefined at this point */
5343     if( ( pC->noaudio == M4OSA_FALSE)
5344         && (pC->AudioEncParams.Format != M4ENCODER_kAudioNULL)
5345         && (pC->uiAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate) )
5346     {
5347         M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : undefined audio bitrate");
5348         return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
5349     }
5350 
5351     /* Video bitrate should not stay undefined at this point */
5352     if( ( pC->novideo == M4OSA_FALSE)
5353         && (pC->EncodingVideoFormat != M4ENCODER_kNULL)
5354         && (pC->uiVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate) )
5355     {
5356         M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : undefined video bitrate");
5357         return M4MCS_ERR_VIDEOBITRATE_TOO_LOW;
5358     }
5359 
5360     /* Set end cut time if necessary (not an error) */
5361     if( pC->uiEndCutTime == 0 )
5362     {
5363         pC->uiEndCutTime = pC->InputFileProperties.uiClipDuration;
5364     }
5365 
5366     /* Force a re-set to check validity of parameters */
5367     VerifyRates.OutputVideoBitrate = pC->uiVideoBitrate;
5368     VerifyRates.OutputAudioBitrate = pC->uiAudioBitrate;
5369     VerifyRates.BeginCutTime = pC->uiBeginCutTime;
5370     VerifyRates.EndCutTime = pC->uiEndCutTime;
5371     VerifyRates.OutputFileSize = pC->uiMaxFileSize;
5372     VerifyRates.OutputVideoTimescale = pC->outputVideoTimescale;
5373 
5374     err = M4MCS_setEncodingParams(pContext, &VerifyRates);
5375 
5376     /**
5377     * Check parameters consistency */
5378     if( err != M4NO_ERROR )
5379     {
5380         M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : invalid parameter found");
5381         return err;
5382     }
5383 
5384     /**
5385     * All is OK : update state automaton */
5386     pC->uiEncVideoBitrate = pC->uiVideoBitrate;
5387     pC->AudioEncParams.Bitrate = pC->uiAudioBitrate;
5388 
5389 #ifdef M4MCS_WITH_FAST_OPEN
5390     /**
5391     * Remake the open if it was done in fast mode */
5392 
5393     if( M4OSA_TRUE == pC->bFileOpenedInFastMode )
5394     {
5395         /* Close the file opened in fast mode */
5396         M4MCS_intCleanUp_ReadersDecoders(pC);
5397 
5398         pC->State = M4MCS_kState_CREATED;
5399 
5400         /* Reopen it in normal mode */
5401         err = M4MCS_open(pContext, pC->pInputFile, pC->InputFileType,
5402             pC->pOutputFile, pC->pTemporaryFile);
5403 
5404         if( err != M4NO_ERROR )
5405         {
5406             M4OSA_TRACE1_1(
5407                 "M4MCS_checkParamsAndStart : M4MCS_Open returns 0x%x", err);
5408             return err;
5409         }
5410     }
5411 
5412 #endif /* M4MCS_WITH_FAST_OPEN */
5413 
5414     pC->State = M4MCS_kState_READY;
5415 
5416     return M4NO_ERROR;
5417 }
5418 
5419 /**
5420  ******************************************************************************
5421  * M4OSA_ERR M4MCS_intStepSet(M4MCS_InternalContext* pC)
5422  ******************************************************************************
5423  */
M4MCS_intStepSet(M4MCS_InternalContext * pC)5424 static M4OSA_ERR M4MCS_intStepSet( M4MCS_InternalContext *pC )
5425 {
5426     M4OSA_ERR err;
5427     M4ENCODER_Header *encHeader;
5428 
5429     /**
5430     * Prepare the video decoder */
5431     err = M4MCS_intPrepareVideoDecoder(pC);
5432 
5433     if( M4NO_ERROR != err )
5434     {
5435         M4OSA_TRACE1_1(
5436             "M4MCS_intStepSet(): M4MCS_intPrepareVideoDecoder() returns 0x%x",
5437             err);
5438         return err;
5439     }
5440 
5441     if( ( pC->InputFileProperties.VideoStreamType == M4VIDEOEDITING_kH264)
5442         && (pC->EncodingVideoFormat == M4ENCODER_kNULL) )
5443     {
5444         pC->bH264Trim = M4OSA_TRUE;
5445     }
5446 
5447     /**
5448     * Prepare the video encoder */
5449     err = M4MCS_intPrepareVideoEncoder(pC);
5450 
5451     if( M4NO_ERROR != err )
5452     {
5453         M4OSA_TRACE1_1(
5454             "M4MCS_intStepSet(): M4MCS_intPrepareVideoEncoder() returns 0x%x",
5455             err);
5456         return err;
5457     }
5458 
5459     if( ( pC->uiBeginCutTime != 0)
5460         && (pC->InputFileProperties.VideoStreamType == M4VIDEOEDITING_kH264)
5461         && (pC->EncodingVideoFormat == M4ENCODER_kNULL) )
5462     {
5463 
5464         err = pC->pVideoEncoderGlobalFcts->pFctSetOption(pC->pViEncCtxt,
5465             M4ENCODER_kOptionID_H264ProcessNALUContext,
5466             (M4OSA_DataOption)pC->m_pInstance);
5467 
5468         if( err != M4NO_ERROR )
5469         {
5470             M4OSA_TRACE1_1("M4MCS_intStetSet :pFctSetOption failed  (err 0x%x)",
5471                 err);
5472             return err;
5473         }
5474 
5475         err = pC->pVideoEncoderGlobalFcts->pFctSetOption(pC->pViEncCtxt,
5476             M4ENCODER_kOptionID_SetH264ProcessNALUfctsPtr,
5477             (M4OSA_DataOption) &H264MCS_ProcessEncodedNALU);
5478 
5479         if( err != M4NO_ERROR )
5480         {
5481             M4OSA_TRACE1_1("M4MCS_intStetSet :pFctSetOption failed  (err 0x%x)",
5482                 err);
5483             return err;
5484         }
5485 
5486         err = pC->pVideoEncoderGlobalFcts->pFctGetOption(pC->pViEncCtxt,
5487             M4ENCODER_kOptionID_EncoderHeader,
5488             (M4OSA_DataOption) &encHeader);
5489 
5490         if( ( M4NO_ERROR != err) || (M4OSA_NULL == encHeader->pBuf) )
5491         {
5492             M4OSA_TRACE1_1(
5493                 "M4MCS_close: failed to get the encoder header (err 0x%x)",
5494                 err);
5495             /**< no return here, we still have stuff to deallocate after close, even if it fails.*/
5496         }
5497         else
5498         {
5499             // Handle DSI first bits
5500 #define SPS_START_POS 6
5501 
5502             pC->m_pInstance->m_encoderSPSSize =
5503                 ( encHeader->pBuf[SPS_START_POS] << 8)
5504                 + encHeader->pBuf[SPS_START_POS + 1];
5505             pC->m_pInstance->m_pEncoderSPS =
5506                 (M4OSA_UInt8 *)(encHeader->pBuf) + SPS_START_POS + 2;
5507 
5508             pC->m_pInstance->m_encoderPPSSize =
5509                 ( encHeader->pBuf[SPS_START_POS + 3
5510                 + pC->m_pInstance->m_encoderSPSSize] << 8)
5511                 + encHeader->pBuf[SPS_START_POS + 4
5512                 + pC->m_pInstance->m_encoderSPSSize];
5513             pC->m_pInstance->m_pEncoderPPS = (M4OSA_UInt8 *)encHeader->pBuf + SPS_START_POS + 5
5514                 + pC->m_pInstance->m_encoderSPSSize;
5515 
5516             /* Check the DSI integrity */
5517             if( encHeader->Size != (pC->m_pInstance->m_encoderSPSSize
5518                 + pC->m_pInstance->m_encoderPPSSize + 5 + SPS_START_POS) )
5519             {
5520                 M4OSA_TRACE1_3(
5521                     "!!! M4MCS_intStepSet ERROR : invalid SPS / PPS %d %d %d",
5522                     encHeader->Size, pC->m_pInstance->m_encoderSPSSize,
5523                     pC->m_pInstance->m_encoderPPSSize);
5524                 return M4ERR_PARAMETER;
5525             }
5526         }
5527     }
5528 
5529     /**
5530     * Prepare audio processing */
5531     err = M4MCS_intPrepareAudioProcessing(pC);
5532 
5533     if( M4NO_ERROR != err )
5534     {
5535         M4OSA_TRACE1_1(
5536             "M4MCS_intStepSet(): M4MCS_intPrepareAudioProcessing() returns 0x%x",
5537             err);
5538         return err;
5539     }
5540 
5541     /**
5542     * Prepare the writer */
5543     err = M4MCS_intPrepareWriter(pC);
5544 
5545     if( M4NO_ERROR != err )
5546     {
5547         M4OSA_TRACE1_1(
5548             "M4MCS_intStepSet(): M4MCS_intPrepareWriter() returns 0x%x", err);
5549         return err;
5550     }
5551 
5552     /**
5553     * Jump the audio stream to the begin cut time (all AUs are RAP)
5554     * Must be done after the 3gpp writer init, because it may write the first
5555     * audio AU in some cases */
5556     err = M4MCS_intPrepareAudioBeginCut(pC);
5557 
5558     if( M4NO_ERROR != err )
5559     {
5560         M4OSA_TRACE1_1(
5561             "M4MCS_intStepSet(): M4MCS_intPrepareAudioBeginCut() returns 0x%x",
5562             err);
5563         return err;
5564     }
5565 
5566     /**
5567     * Update state automaton */
5568     if( 0 == pC->uiBeginCutTime )
5569     {
5570         pC->dViDecStartingCts = 0.0;
5571         /**
5572         * No begin cut, do the encoding */
5573         pC->State = M4MCS_kState_PROCESSING;
5574     }
5575     else
5576     {
5577         /**
5578         * Remember that we must start the decode/encode process at the begin cut time */
5579         pC->dViDecStartingCts = (M4OSA_Double)pC->uiBeginCutTime;
5580 
5581         /**
5582         * Jumping */
5583         pC->State = M4MCS_kState_BEGINVIDEOJUMP;
5584     }
5585 
5586     /**
5587     * Return with no error */
5588     M4OSA_TRACE3_0("M4MCS_intStepSet(): returning M4NO_ERROR");
5589     return M4NO_ERROR;
5590 }
5591 
5592 /**
5593  ******************************************************************************
5594  * M4OSA_ERR M4MCS_intPrepareVideoDecoder(M4MCS_InternalContext* pC);
5595  * @brief    Prepare the video decoder.
5596  * @param    pC          (IN) MCS private context
5597  * @return   M4NO_ERROR  No error
5598  * @return   M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED
5599  * @return   Any error returned by an underlaying module
5600  ******************************************************************************
5601  */
M4MCS_intPrepareVideoDecoder(M4MCS_InternalContext * pC)5602 static M4OSA_ERR M4MCS_intPrepareVideoDecoder( M4MCS_InternalContext *pC )
5603 {
5604     M4OSA_ERR err;
5605     M4OSA_Void *decoderUserData;
5606     M4DECODER_OutputFilter FilterOption;
5607 
5608     if( pC->novideo )
5609         return M4NO_ERROR;
5610 
5611     /**
5612     * Create the decoder, if it has not been created yet (to get video properties for example) */
5613     if( M4OSA_NULL == pC->pViDecCtxt )
5614     {
5615 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
5616 
5617         decoderUserData = pC->m_pCurrentVideoDecoderUserData;
5618 
5619 #else
5620 
5621         decoderUserData = M4OSA_NULL;
5622 
5623 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS ? */
5624 
5625         err = pC->m_pVideoDecoder->m_pFctCreate(&pC->pViDecCtxt,
5626             &pC->pReaderVideoStream->m_basicProperties, pC->m_pReader,
5627             pC->m_pReaderDataIt, &pC->ReaderVideoAU, decoderUserData);
5628 
5629         if( (M4OSA_UInt32)(M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED) == err )
5630         {
5631             /**
5632             * Our decoder is not compatible with H263 profile other than 0.
5633             * So it returns this internal error code.
5634             * We translate it to our own error code */
5635             M4OSA_TRACE1_0("M4MCS_intPrepareVideoDecoder:\
5636                            returning M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED");
5637             return M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED;
5638         }
5639         else if( M4NO_ERROR != err )
5640         {
5641             M4OSA_TRACE1_1("M4MCS_intPrepareVideoDecoder:\
5642                            m_pVideoDecoder->m_pFctCreate returns 0x%x", err);
5643             return err;
5644         }
5645 
5646         if( M4VIDEOEDITING_kH264 == pC->InputFileProperties.VideoStreamType )
5647         {
5648             FilterOption.m_pFilterFunction =
5649                 (M4OSA_Void *) &M4VIFI_ResizeBilinearYUV420toYUV420;
5650             FilterOption.m_pFilterUserData = M4OSA_NULL;
5651             err = pC->m_pVideoDecoder->m_pFctSetOption(pC->pViDecCtxt,
5652                 M4DECODER_kOptionID_OutputFilter,
5653                 (M4OSA_DataOption) &FilterOption);
5654 
5655             if( M4NO_ERROR != err )
5656             {
5657                 M4OSA_TRACE1_1("M4MCS_intPrepareVideoDecoder:\
5658                                m_pVideoDecoder->m_pFctSetOption returns 0x%x", err);
5659                 return err;
5660             }
5661         }
5662     }
5663 
5664     /**
5665     * Return with no error */
5666     M4OSA_TRACE3_0("M4MCS_intPrepareVideoDecoder(): returning M4NO_ERROR");
5667     return M4NO_ERROR;
5668 }
5669 
5670 /**
5671  ******************************************************************************
5672  * M4OSA_ERR M4MCS_intPrepareVideoEncoder(M4MCS_InternalContext* pC);
5673  * @brief    Prepare the video encoder.
5674  * @param    pC          (IN) MCS private context
5675  * @return   M4NO_ERROR  No error
5676  * @return   Any error returned by an underlaying module
5677  ******************************************************************************
5678  */
M4MCS_intPrepareVideoEncoder(M4MCS_InternalContext * pC)5679 static M4OSA_ERR M4MCS_intPrepareVideoEncoder( M4MCS_InternalContext *pC )
5680 {
5681     M4OSA_ERR err;
5682     M4ENCODER_AdvancedParams EncParams; /**< Encoder advanced parameters */
5683     M4ENCODER_Params EncParams1;
5684     M4OSA_Double dFrameRate;            /**< tmp variable */
5685 
5686     if( pC->novideo )
5687         return M4NO_ERROR;
5688 
5689     if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
5690     {
5691         /* Approximative cts increment */
5692         pC->dCtsIncrement = 1000.0 / pC->pReaderVideoStream->m_averageFrameRate;
5693 
5694         if( pC->uiBeginCutTime == 0 )
5695         {
5696             M4OSA_TRACE3_0(
5697                 "M4MCS_intPrepareVideoEncoder(): Null encoding, do nothing.");
5698             return M4NO_ERROR;
5699         }
5700         else
5701         {
5702             M4OSA_TRACE3_0(
5703                 "M4MCS_intPrepareVideoEncoder(): Null encoding, I-frame defaults.");
5704 
5705             /* Set useful parameters to encode the first I-frame */
5706             EncParams.InputFormat = M4ENCODER_kIYUV420;
5707             EncParams.videoProfile = pC->encodingVideoProfile;
5708             EncParams.videoLevel= pC->encodingVideoLevel;
5709 
5710             switch( pC->InputFileProperties.VideoStreamType )
5711             {
5712                 case M4VIDEOEDITING_kH263:
5713                     EncParams.Format = M4ENCODER_kH263;
5714                     break;
5715 
5716                 case M4VIDEOEDITING_kMPEG4:
5717                     EncParams.Format = M4ENCODER_kMPEG4;
5718                     break;
5719 
5720                 case M4VIDEOEDITING_kH264:
5721                     EncParams.Format = M4ENCODER_kH264;
5722                     break;
5723 
5724                 default:
5725                     M4OSA_TRACE1_1("M4MCS_intPrepareVideoEncoder: unknown encoding video format\
5726                                    (%d), returning M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED",
5727                                    pC->InputFileProperties.VideoStreamType);
5728                     return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
5729             }
5730 
5731             EncParams.FrameWidth = pC->EncodingWidth;
5732             EncParams.FrameHeight = pC->EncodingHeight;
5733             EncParams.Bitrate = pC->uiEncVideoBitrate;
5734             EncParams.bInternalRegulation =
5735                 M4OSA_FALSE; /* do not constrain the I-frame */
5736             EncParams.FrameRate = pC->EncodingVideoFramerate;
5737 
5738             /* Other encoding settings (quite all dummy...) */
5739             EncParams.uiHorizontalSearchRange = 0;    /* use default */
5740             EncParams.uiVerticalSearchRange = 0;      /* use default */
5741             EncParams.bErrorResilience = M4OSA_FALSE; /* no error resilience */
5742             EncParams.uiIVopPeriod = 0;               /* use default */
5743             EncParams.uiMotionEstimationTools =
5744                 0; /* M4V_MOTION_EST_TOOLS_ALL */
5745             EncParams.bAcPrediction = M4OSA_TRUE;     /* use AC prediction */
5746             EncParams.uiStartingQuantizerValue = 5;   /* initial QP = 5 */
5747             EncParams.bDataPartitioning =
5748                 M4OSA_FALSE; /* no data partitioning */
5749 
5750             /* Rate factor */
5751             EncParams.uiTimeScale = pC->InputFileProperties.uiVideoTimeScale;
5752             EncParams.uiRateFactor = 1;
5753         }
5754     }
5755     else
5756     {
5757         M4OSA_TRACE3_0(
5758             "M4MCS_intPrepareVideoEncoder(): Normal encoding, set full config.");
5759 
5760         /**
5761         * Set encoder shell parameters according to MCS settings */
5762         EncParams.Format = pC->EncodingVideoFormat;
5763         EncParams.InputFormat = M4ENCODER_kIYUV420;
5764         EncParams.videoProfile = pC->encodingVideoProfile;
5765         EncParams.videoLevel= pC->encodingVideoLevel;
5766 
5767         /**
5768         * Video frame size */
5769         EncParams.FrameWidth = pC->EncodingWidth;
5770         EncParams.FrameHeight = pC->EncodingHeight;
5771 
5772         /**
5773         * Video bitrate has been previously computed */
5774         EncParams.Bitrate = pC->uiEncVideoBitrate;
5775 
5776         /**
5777         * MCS use the "true" core internal bitrate regulation */
5778         EncParams.bInternalRegulation = M4OSA_TRUE;
5779 
5780         /**
5781         * Other encoder settings */
5782 
5783         EncParams.uiHorizontalSearchRange = 0;    /* use default */
5784         EncParams.uiVerticalSearchRange = 0;      /* use default */
5785         EncParams.bErrorResilience = M4OSA_FALSE; /* no error resilience */
5786         EncParams.uiIVopPeriod = 0;               /* use default */
5787         EncParams.uiMotionEstimationTools =
5788             0; /* M4V_MOTION_EST_TOOLS_ALL */
5789         EncParams.bAcPrediction = M4OSA_TRUE;     /* use AC prediction */
5790         EncParams.uiStartingQuantizerValue = 10;  /* initial QP = 10 */
5791         EncParams.bDataPartitioning =
5792             M4OSA_FALSE; /* no data partitioning */
5793 
5794 
5795         /**
5796         * Video encoder frame rate and rate factor */
5797         EncParams.FrameRate = pC->EncodingVideoFramerate;
5798         EncParams.uiTimeScale = pC->outputVideoTimescale;
5799 
5800         switch( pC->EncodingVideoFramerate )
5801         {
5802             case M4ENCODER_k5_FPS:
5803                 dFrameRate = 5.0;
5804                 break;
5805 
5806             case M4ENCODER_k7_5_FPS:
5807                 dFrameRate = 7.5;
5808                 break;
5809 
5810             case M4ENCODER_k10_FPS:
5811                 dFrameRate = 10.0;
5812                 break;
5813 
5814             case M4ENCODER_k12_5_FPS:
5815                 dFrameRate = 12.5;
5816                 break;
5817 
5818             case M4ENCODER_k15_FPS:
5819                 dFrameRate = 15.0;
5820                 break;
5821 
5822             case M4ENCODER_k20_FPS: /**< MPEG-4 only */
5823                 dFrameRate = 20.0;
5824                 break;
5825 
5826             case M4ENCODER_k25_FPS: /**< MPEG-4 only */
5827                 dFrameRate = 25.0;
5828                 break;
5829 
5830             case M4ENCODER_k30_FPS:
5831                 dFrameRate = 30.0;
5832                 break;
5833 
5834             default:
5835                 M4OSA_TRACE1_1(
5836                     "M4MCS_intPrepareVideoEncoder: unknown encoding video frame rate\
5837                     (0x%x), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE",
5838                     pC->EncodingVideoFramerate);
5839                 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE;
5840         }
5841 
5842         /**
5843         * Compute the number of milliseconds between two frames */
5844         if( M4ENCODER_kH263 == EncParams.Format )
5845         {
5846             pC->dCtsIncrement = 1001.0 / dFrameRate;
5847         }
5848         else /**< MPEG4 or H.264 */
5849         {
5850             pC->dCtsIncrement = 1000.0 / dFrameRate;
5851         }
5852     }
5853 
5854     /**
5855      * Limit the video bitrate according to encoder profile
5856      * and level */
5857     err = M4MCS_intLimitBitratePerCodecProfileLevel(&EncParams);
5858     if (M4NO_ERROR != err) {
5859         M4OSA_TRACE1_1(
5860             "M4MCS_intPrepareVideoEncoder: limit bitrate returned err \
5861              0x%x", err);
5862         return err;
5863     }
5864 
5865     /**
5866     * Create video encoder */
5867     err = pC->pVideoEncoderGlobalFcts->pFctInit(&pC->pViEncCtxt,
5868         pC->pWriterDataFcts, \
5869         M4MCS_intApplyVPP, pC, pC->pCurrentVideoEncoderExternalAPI, \
5870         pC->pCurrentVideoEncoderUserData);
5871 
5872     /**< We put the MCS context in place of the VPP context */
5873     if( M4NO_ERROR != err )
5874     {
5875         M4OSA_TRACE1_1(
5876             "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctInit returns 0x%x",
5877             err);
5878         return err;
5879     }
5880 
5881     pC->encoderState = M4MCS_kEncoderClosed;
5882 
5883     if( M4OSA_TRUE == pC->bH264Trim )
5884         //if((M4ENCODER_kNULL == pC->EncodingVideoFormat)
5885         //    && (M4VIDEOEDITING_kH264 == pC->InputFileProperties.VideoStreamType))
5886     {
5887         EncParams1.InputFormat = EncParams.InputFormat;
5888         //EncParams1.InputFrameWidth = EncParams.InputFrameWidth;
5889         //EncParams1.InputFrameHeight = EncParams.InputFrameHeight;
5890         EncParams1.FrameWidth = EncParams.FrameWidth;
5891         EncParams1.FrameHeight = EncParams.FrameHeight;
5892         EncParams1.videoProfile= EncParams.videoProfile;
5893         EncParams1.videoLevel= EncParams.videoLevel;
5894         EncParams1.Bitrate = EncParams.Bitrate;
5895         EncParams1.FrameRate = EncParams.FrameRate;
5896         EncParams1.Format = M4ENCODER_kH264; //EncParams.Format;
5897         M4OSA_TRACE1_2("mcs encoder open profile :%d, level %d",
5898             EncParams1.videoProfile, EncParams1.videoLevel);
5899         err = pC->pVideoEncoderGlobalFcts->pFctOpen(pC->pViEncCtxt,
5900             &pC->WriterVideoAU, &EncParams1);
5901     }
5902     else
5903     {
5904         M4OSA_TRACE1_2("mcs encoder open Adv profile :%d, level %d",
5905             EncParams.videoProfile, EncParams.videoLevel);
5906         err = pC->pVideoEncoderGlobalFcts->pFctOpen(pC->pViEncCtxt,
5907             &pC->WriterVideoAU, &EncParams);
5908     }
5909 
5910     if( M4NO_ERROR != err )
5911     {
5912         M4OSA_TRACE1_1(
5913             "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctOpen returns 0x%x",
5914             err);
5915         return err;
5916     }
5917 
5918     pC->encoderState = M4MCS_kEncoderStopped;
5919 
5920     if( M4OSA_NULL != pC->pVideoEncoderGlobalFcts->pFctStart )
5921     {
5922         err = pC->pVideoEncoderGlobalFcts->pFctStart(pC->pViEncCtxt);
5923 
5924         if( M4NO_ERROR != err )
5925         {
5926             M4OSA_TRACE1_1(
5927                 "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctStart returns 0x%x",
5928                 err);
5929             return err;
5930         }
5931     }
5932 
5933     pC->encoderState = M4MCS_kEncoderRunning;
5934 
5935     /******************************/
5936     /* Video resize management    */
5937     /******************************/
5938     /**
5939     * Compare video input size and video output size to check if resize is needed */
5940     if( ( (M4OSA_UInt32)EncParams.FrameWidth
5941         != pC->pReaderVideoStream->m_videoWidth)
5942         || ((M4OSA_UInt32)EncParams.FrameHeight
5943         != pC->pReaderVideoStream->m_videoHeight) )
5944     {
5945         /**
5946         * Allocate the intermediate video plane that will receive the decoded image before
5947          resizing */
5948         pC->pPreResizeFrame =
5949             (M4VIFI_ImagePlane *)M4OSA_32bitAlignedMalloc(3 * sizeof(M4VIFI_ImagePlane),
5950             M4MCS, (M4OSA_Char *)"m_pPreResizeFrame");
5951 
5952         if( M4OSA_NULL == pC->pPreResizeFrame )
5953         {
5954             M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder():\
5955                            unable to allocate m_pPreResizeFrame, returning M4ERR_ALLOC");
5956             return M4ERR_ALLOC;
5957         }
5958 
5959         pC->pPreResizeFrame[0].pac_data = M4OSA_NULL;
5960         pC->pPreResizeFrame[1].pac_data = M4OSA_NULL;
5961         pC->pPreResizeFrame[2].pac_data = M4OSA_NULL;
5962 
5963         /**
5964         * Allocate the Y plane */
5965         pC->pPreResizeFrame[0].u_topleft = 0;
5966         pC->pPreResizeFrame[0].u_width = pC->pReaderVideoStream->
5967             m_videoWidth; /**< input width */
5968         pC->pPreResizeFrame[0].u_height = pC->pReaderVideoStream->
5969             m_videoHeight; /**< input height */
5970         pC->pPreResizeFrame[0].u_stride = pC->
5971             pPreResizeFrame[0].u_width; /**< simple case: stride equals width */
5972 
5973         pC->pPreResizeFrame[0].pac_data =
5974             (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[0].u_stride \
5975             *pC->pPreResizeFrame[0].u_height, M4MCS,
5976             (M4OSA_Char *)"m_pPreResizeFrame[0].pac_data");
5977 
5978         if( M4OSA_NULL == pC->pPreResizeFrame[0].pac_data )
5979         {
5980             M4OSA_TRACE1_0(
5981                 "M4MCS_intPrepareVideoEncoder():\
5982                      unable to allocate m_pPreResizeFrame[0].pac_data, returning M4ERR_ALLOC");
5983             return M4ERR_ALLOC;
5984         }
5985 
5986         /**
5987         * Allocate the U plane */
5988         pC->pPreResizeFrame[1].u_topleft = 0;
5989         pC->pPreResizeFrame[1].u_width = pC->pPreResizeFrame[0].u_width
5990             >> 1; /**< U width is half the Y width */
5991         pC->pPreResizeFrame[1].u_height = pC->pPreResizeFrame[0].u_height
5992             >> 1; /**< U height is half the Y height */
5993         pC->pPreResizeFrame[1].u_stride = pC->
5994             pPreResizeFrame[1].u_width; /**< simple case: stride equals width */
5995 
5996         pC->pPreResizeFrame[1].pac_data =
5997             (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[1].u_stride \
5998             *pC->pPreResizeFrame[1].u_height, M4MCS,
5999             (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data");
6000 
6001         if( M4OSA_NULL == pC->pPreResizeFrame[1].pac_data )
6002         {
6003             M4OSA_TRACE1_0(
6004                 "M4MCS_intPrepareVideoEncoder():\
6005                  unable to allocate m_pPreResizeFrame[1].pac_data, returning M4ERR_ALLOC");
6006             return M4ERR_ALLOC;
6007         }
6008 
6009         /**
6010         * Allocate the V plane */
6011         pC->pPreResizeFrame[2].u_topleft = 0;
6012         pC->pPreResizeFrame[2].u_width = pC->
6013             pPreResizeFrame[1].u_width; /**< V width equals U width */
6014         pC->pPreResizeFrame[2].u_height = pC->
6015             pPreResizeFrame[1].u_height; /**< V height equals U height */
6016         pC->pPreResizeFrame[2].u_stride = pC->
6017             pPreResizeFrame[2].u_width; /**< simple case: stride equals width */
6018 
6019         pC->pPreResizeFrame[2].pac_data =
6020             (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[2].u_stride \
6021             *pC->pPreResizeFrame[2].u_height, M4MCS,
6022             (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data");
6023 
6024         if( M4OSA_NULL == pC->pPreResizeFrame[2].pac_data )
6025         {
6026             M4OSA_TRACE1_0(
6027                 "M4MCS_intPrepareVideoEncoder():\
6028                  unable to allocate m_pPreResizeFrame[2].pac_data, returning M4ERR_ALLOC");
6029             return M4ERR_ALLOC;
6030         }
6031     }
6032 
6033     /**
6034     * Return with no error */
6035     M4OSA_TRACE3_0("M4MCS_intPrepareVideoEncoder(): returning M4NO_ERROR");
6036     return M4NO_ERROR;
6037 }
6038 
6039 /**
6040  ******************************************************************************
6041  * M4OSA_ERR M4MCS_intPrepareAudioProcessing(M4MCS_InternalContext* pC);
6042  * @brief    Prepare the AAC decoder, the SRC and the AMR-NB encoder and the MP3 encoder.
6043  * @param    pC          (IN) MCS private context
6044  * @return   M4NO_ERROR  No error
6045  * @return   Any error returned by an underlaying module
6046  ******************************************************************************
6047  */
M4MCS_intPrepareAudioProcessing(M4MCS_InternalContext * pC)6048 static M4OSA_ERR M4MCS_intPrepareAudioProcessing( M4MCS_InternalContext *pC )
6049 {
6050     M4OSA_ERR err;
6051 
6052     SSRC_ReturnStatus_en
6053         ReturnStatus; /* Function return status                       */
6054     LVM_INT16 NrSamplesMin =
6055         0; /* Minimal number of samples on the input or on the output */
6056     LVM_INT32 ScratchSize; /* The size of the scratch memory               */
6057     LVM_INT16
6058         *pInputInScratch; /* Pointer to input in the scratch buffer       */
6059     LVM_INT16
6060         *pOutputInScratch; /* Pointer to the output in the scratch buffer  */
6061     SSRC_Params_t ssrcParams;          /* Memory for init parameters                    */
6062 
6063 #ifdef MCS_DUMP_PCM_TO_FILE
6064 
6065     file_au_reader = fopen("mcs_ReaderOutput.raw", "wb");
6066     file_pcm_decoder = fopen("mcs_DecoderOutput.pcm", "wb");
6067     file_pcm_encoder = fopen("mcs_EncoderInput.pcm", "wb");
6068 
6069 #endif
6070 
6071     if( pC->noaudio )
6072         return M4NO_ERROR;
6073 
6074     if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
6075     {
6076         M4OSA_TRACE3_0(
6077             "M4MCS_intPrepareAudioProcessing(): Null encoding, do nothing.");
6078         return M4NO_ERROR;
6079     }
6080 
6081     /* ________________________________ */
6082     /*|                                |*/
6083     /*| Create and "start" the decoder |*/
6084     /*|________________________________|*/
6085 
6086     if( M4OSA_NULL == pC->m_pAudioDecoder )
6087     {
6088         M4OSA_TRACE1_0(
6089             "M4MCS_intPrepareAudioProcessing(): Fails to initiate the audio decoder.");
6090         return M4MCS_ERR_AUDIO_CONVERSION_FAILED;
6091     }
6092 
6093     if( M4OSA_NULL == pC->pAudioDecCtxt )
6094     {
6095         err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(&pC->pAudioDecCtxt,
6096             pC->pReaderAudioStream, pC->m_pCurrentAudioDecoderUserData);
6097 
6098         if( M4NO_ERROR != err )
6099         {
6100             M4OSA_TRACE1_1(
6101                 "M4MCS_intPrepareVideoDecoder: m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x",
6102                 err);
6103             return err;
6104         }
6105     }
6106 
6107     if( M4VIDEOEDITING_kAMR_NB == pC->InputFileProperties.AudioStreamType ) {
6108         /* AMR DECODER CONFIGURATION */
6109 
6110         /* nothing specific to do */
6111     }
6112     else if( M4VIDEOEDITING_kEVRC == pC->InputFileProperties.AudioStreamType ) {
6113         /* EVRC DECODER CONFIGURATION */
6114 
6115         /* nothing specific to do */
6116     }
6117     else if( M4VIDEOEDITING_kMP3 == pC->InputFileProperties.AudioStreamType ) {
6118         /* MP3 DECODER CONFIGURATION */
6119 
6120         /* nothing specific to do */
6121     }
6122     else
6123     {
6124         /* AAC DECODER CONFIGURATION */
6125         M4_AacDecoderConfig AacDecParam;
6126 
6127         AacDecParam.m_AACDecoderProfile = AAC_kAAC;
6128         AacDecParam.m_DownSamplingMode = AAC_kDS_OFF;
6129 
6130         if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB )
6131         {
6132             AacDecParam.m_OutputMode = AAC_kMono;
6133         }
6134         else
6135         {
6136             /* For this version, we encode only in AAC */
6137             if( M4ENCODER_kMono == pC->AudioEncParams.ChannelNum )
6138             {
6139                 AacDecParam.m_OutputMode = AAC_kMono;
6140             }
6141             else
6142             {
6143                 AacDecParam.m_OutputMode = AAC_kStereo;
6144             }
6145         }
6146 
6147         pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
6148             M4AD_kOptionID_UserParam, (M4OSA_DataOption) &AacDecParam);
6149     }
6150 
6151     pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
6152            M4AD_kOptionID_3gpReaderInterface, (M4OSA_DataOption) pC->m_pReaderDataIt);
6153 
6154     pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
6155            M4AD_kOptionID_AudioAU, (M4OSA_DataOption) &pC->ReaderAudioAU);
6156 
6157     if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL )
6158     {
6159         /* Not implemented in all decoders */
6160         err = pC->m_pAudioDecoder->m_pFctStartAudioDec(pC->pAudioDecCtxt);
6161 
6162         if( M4NO_ERROR != err )
6163         {
6164             M4OSA_TRACE1_1(
6165                 "M4MCS_intPrepareVideoDecoder: m_pAudioDecoder->m_pFctStartAudioDec returns 0x%x",
6166                 err);
6167             return err;
6168         }
6169     }
6170 
6171     /**
6172     * Allocate output buffer for the audio decoder */
6173     pC->InputFileProperties.uiDecodedPcmSize =
6174         pC->pReaderAudioStream->m_byteFrameLength
6175         * pC->pReaderAudioStream->m_byteSampleSize
6176         * pC->pReaderAudioStream->m_nbChannels;
6177 
6178     if( pC->InputFileProperties.uiDecodedPcmSize > 0 )
6179     {
6180         pC->AudioDecBufferOut.m_bufferSize =
6181             pC->InputFileProperties.uiDecodedPcmSize;
6182         pC->AudioDecBufferOut.m_dataAddress =
6183             (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->AudioDecBufferOut.m_bufferSize \
6184             *sizeof(short), M4MCS, (M4OSA_Char *)"AudioDecBufferOut.m_bufferSize");
6185     }
6186 
6187     if( M4OSA_NULL == pC->AudioDecBufferOut.m_dataAddress )
6188     {
6189         M4OSA_TRACE1_0(
6190             "M4MCS_intPrepareVideoDecoder():\
6191              unable to allocate AudioDecBufferOut.m_dataAddress, returning M4ERR_ALLOC");
6192         return M4ERR_ALLOC;
6193     }
6194 
6195     /* _________________________ */
6196     /*|                         |*/
6197     /*| Set the SSRC parameters |*/
6198     /*|_________________________|*/
6199 
6200     switch( pC->pReaderAudioStream->m_samplingFrequency )
6201     {
6202         case 8000:
6203             ssrcParams.SSRC_Fs_In = LVM_FS_8000;
6204             break;
6205 
6206         case 11025:
6207             ssrcParams.SSRC_Fs_In = LVM_FS_11025;
6208             break;
6209 
6210         case 12000:
6211             ssrcParams.SSRC_Fs_In = LVM_FS_12000;
6212             break;
6213 
6214         case 16000:
6215             ssrcParams.SSRC_Fs_In = LVM_FS_16000;
6216             break;
6217 
6218         case 22050:
6219             ssrcParams.SSRC_Fs_In = LVM_FS_22050;
6220             break;
6221 
6222         case 24000:
6223             ssrcParams.SSRC_Fs_In = LVM_FS_24000;
6224             break;
6225 
6226         case 32000:
6227             ssrcParams.SSRC_Fs_In = LVM_FS_32000;
6228             break;
6229 
6230         case 44100:
6231             ssrcParams.SSRC_Fs_In = LVM_FS_44100;
6232             break;
6233 
6234         case 48000:
6235             ssrcParams.SSRC_Fs_In = LVM_FS_48000;
6236             break;
6237 
6238         default:
6239             M4OSA_TRACE1_1(
6240                 "M4MCS_intPrepareVideoDecoder: invalid input AAC sampling frequency (%d Hz),\
6241                  returning M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY",
6242                 pC->pReaderAudioStream->m_samplingFrequency);
6243             return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY;
6244     }
6245 
6246     if( 1 == pC->pReaderAudioStream->m_nbChannels )
6247     {
6248         ssrcParams.SSRC_NrOfChannels = LVM_MONO;
6249     }
6250     else
6251     {
6252         ssrcParams.SSRC_NrOfChannels = LVM_STEREO;
6253     }
6254 
6255     /*FlB 26.02.2009: add mp3 as output format*/
6256     if( pC->AudioEncParams.Format == M4ENCODER_kAAC
6257         || pC->AudioEncParams.Format == M4ENCODER_kMP3 )
6258     {
6259         switch( pC->AudioEncParams.Frequency )
6260         {
6261             case M4ENCODER_k8000Hz:
6262                 ssrcParams.SSRC_Fs_Out = LVM_FS_8000;
6263                 break;
6264 
6265             case M4ENCODER_k11025Hz:
6266                 ssrcParams.SSRC_Fs_Out = LVM_FS_11025;
6267                 break;
6268 
6269             case M4ENCODER_k12000Hz:
6270                 ssrcParams.SSRC_Fs_Out = LVM_FS_12000;
6271                 break;
6272 
6273             case M4ENCODER_k16000Hz:
6274                 ssrcParams.SSRC_Fs_Out = LVM_FS_16000;
6275                 break;
6276 
6277             case M4ENCODER_k22050Hz:
6278                 ssrcParams.SSRC_Fs_Out = LVM_FS_22050;
6279                 break;
6280 
6281             case M4ENCODER_k24000Hz:
6282                 ssrcParams.SSRC_Fs_Out = LVM_FS_24000;
6283                 break;
6284 
6285             case M4ENCODER_k32000Hz:
6286                 ssrcParams.SSRC_Fs_Out = LVM_FS_32000;
6287                 break;
6288 
6289             case M4ENCODER_k44100Hz:
6290                 ssrcParams.SSRC_Fs_Out = LVM_FS_44100;
6291                 break;
6292 
6293             case M4ENCODER_k48000Hz:
6294                 ssrcParams.SSRC_Fs_Out = LVM_FS_48000;
6295                 break;
6296 
6297             default:
6298                 M4OSA_TRACE1_1(
6299                     "M4MCS_intPrepareAudioProcessing: invalid output AAC sampling frequency \
6300                     (%d Hz), returning M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY",
6301                     pC->AudioEncParams.Frequency);
6302                 return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY;
6303                 break;
6304         }
6305     }
6306     else
6307     {
6308         ssrcParams.SSRC_Fs_Out = LVM_FS_8000;
6309     }
6310 
6311 
6312 
6313     ReturnStatus = 0;
6314 
6315     switch( ssrcParams.SSRC_Fs_In )
6316     {
6317         case LVM_FS_8000:
6318             ssrcParams.NrSamplesIn = 320;
6319             break;
6320 
6321         case LVM_FS_11025:
6322             ssrcParams.NrSamplesIn = 441;
6323             break;
6324 
6325         case LVM_FS_12000:
6326             ssrcParams.NrSamplesIn = 480;
6327             break;
6328 
6329         case LVM_FS_16000:
6330             ssrcParams.NrSamplesIn = 640;
6331             break;
6332 
6333         case LVM_FS_22050:
6334             ssrcParams.NrSamplesIn = 882;
6335             break;
6336 
6337         case LVM_FS_24000:
6338             ssrcParams.NrSamplesIn = 960;
6339             break;
6340 
6341         case LVM_FS_32000:
6342             ssrcParams.NrSamplesIn = 1280;
6343             break;
6344 
6345         case LVM_FS_44100:
6346             ssrcParams.NrSamplesIn = 1764;
6347             break;
6348 
6349         case LVM_FS_48000:
6350             ssrcParams.NrSamplesIn = 1920;
6351             break;
6352 
6353         default:
6354             ReturnStatus = -1;
6355             break;
6356     }
6357 
6358     switch( ssrcParams.SSRC_Fs_Out )
6359     {
6360         case LVM_FS_8000:
6361             ssrcParams.NrSamplesOut = 320;
6362             break;
6363 
6364         case LVM_FS_11025:
6365             ssrcParams.NrSamplesOut = 441;
6366             break;
6367 
6368         case LVM_FS_12000:
6369             ssrcParams.NrSamplesOut = 480;
6370             break;
6371 
6372         case LVM_FS_16000:
6373             ssrcParams.NrSamplesOut = 640;
6374             break;
6375 
6376         case LVM_FS_22050:
6377             ssrcParams.NrSamplesOut = 882;
6378             break;
6379 
6380         case LVM_FS_24000:
6381             ssrcParams.NrSamplesOut = 960;
6382             break;
6383 
6384         case LVM_FS_32000:
6385             ssrcParams.NrSamplesOut = 1280;
6386             break;
6387 
6388         case LVM_FS_44100:
6389             ssrcParams.NrSamplesOut = 1764;
6390             break;
6391 
6392         case LVM_FS_48000:
6393             ssrcParams.NrSamplesOut = 1920;
6394             break;
6395 
6396         default:
6397             ReturnStatus = -1;
6398             break;
6399     }
6400 
6401 
6402 
6403     if( ReturnStatus != SSRC_OK )
6404     {
6405         M4OSA_TRACE1_1(
6406             "M4MCS_intPrepareAudioProcessing:\
6407              Error code %d returned by the SSRC_GetNrSamples function",
6408             ReturnStatus);
6409         return M4MCS_ERR_AUDIO_CONVERSION_FAILED;
6410     }
6411 
6412     NrSamplesMin =
6413         (LVM_INT16)((ssrcParams.NrSamplesIn > ssrcParams.NrSamplesOut)
6414         ? ssrcParams.NrSamplesOut : ssrcParams.NrSamplesIn);
6415 
6416     while( NrSamplesMin < M4MCS_SSRC_MINBLOCKSIZE )
6417     { /* Don't take blocks smaller that the minimal block size */
6418         ssrcParams.NrSamplesIn = (LVM_INT16)(ssrcParams.NrSamplesIn << 1);
6419         ssrcParams.NrSamplesOut = (LVM_INT16)(ssrcParams.NrSamplesOut << 1);
6420         NrSamplesMin = (LVM_INT16)(NrSamplesMin << 1);
6421     }
6422 
6423 
6424     pC->iSsrcNbSamplIn = (LVM_INT16)(
6425         ssrcParams.
6426         NrSamplesIn); /* multiplication by NrOfChannels is done below */
6427     pC->iSsrcNbSamplOut = (LVM_INT16)(ssrcParams.NrSamplesOut);
6428 
6429     /**
6430     * Allocate buffer for the input of the SSRC */
6431     pC->pSsrcBufferIn =
6432         (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->iSsrcNbSamplIn * sizeof(short) \
6433         *pC->pReaderAudioStream->m_nbChannels, M4MCS,
6434         (M4OSA_Char *)"pSsrcBufferIn");
6435 
6436     if( M4OSA_NULL == pC->pSsrcBufferIn )
6437     {
6438         M4OSA_TRACE1_0(
6439             "M4MCS_intPrepareVideoDecoder():\
6440              unable to allocate pSsrcBufferIn, returning M4ERR_ALLOC");
6441         return M4ERR_ALLOC;
6442     }
6443     pC->pPosInSsrcBufferIn = (M4OSA_MemAddr8)pC->pSsrcBufferIn;
6444 
6445     /**
6446     * Allocate buffer for the output of the SSRC */
6447     pC->pSsrcBufferOut =
6448         (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->iSsrcNbSamplOut * sizeof(short) \
6449         *pC->pReaderAudioStream->m_nbChannels, M4MCS,
6450         (M4OSA_Char *)"pSsrcBufferOut");
6451 
6452     if( M4OSA_NULL == pC->pSsrcBufferOut )
6453     {
6454         M4OSA_TRACE1_0(
6455             "M4MCS_intPrepareVideoDecoder():\
6456              unable to allocate pSsrcBufferOut, returning M4ERR_ALLOC");
6457         return M4ERR_ALLOC;
6458     }
6459 
6460 
6461     pC->pLVAudioResampler = LVAudioResamplerCreate(
6462         16, /*gInputParams.lvBTChannelCount*/
6463         (M4OSA_Int16)pC->InputFileProperties.uiNbChannels/*ssrcParams.SSRC_NrOfChannels*/,
6464         (M4OSA_Int32)(pC->AudioEncParams.Frequency)/*ssrcParams.SSRC_Fs_Out*/, 1);
6465 
6466      if( M4OSA_NULL == pC->pLVAudioResampler)
6467      {
6468          return M4ERR_ALLOC;
6469      }
6470 
6471     LVAudiosetSampleRate(pC->pLVAudioResampler,
6472         /*gInputParams.lvInSampleRate*/
6473         /*pC->pAddedClipCtxt->pSettings->ClipProperties.uiSamplingFrequency*/
6474         pC->InputFileProperties.uiSamplingFrequency/*ssrcParams.SSRC_Fs_In*/);
6475 
6476     LVAudiosetVolume(pC->pLVAudioResampler, (M4OSA_Int16)(0x1000 /* 0x7fff */),
6477         (M4OSA_Int16)(0x1000/*0x7fff*/));
6478 
6479 
6480     /* ________________________ */
6481     /*|                        |*/
6482     /*| Init the audio encoder |*/
6483     /*|________________________|*/
6484 
6485     /* Initialise the audio encoder */
6486 
6487     err = pC->pAudioEncoderGlobalFcts->pFctInit(&pC->pAudioEncCtxt,
6488         pC->pCurrentAudioEncoderUserData);
6489 
6490     if( M4NO_ERROR != err )
6491     {
6492         M4OSA_TRACE1_1(
6493             "M4MCS_intPrepareAudioProcessing: pAudioEncoderGlobalFcts->pFctInit returns 0x%x",
6494             err);
6495         return err;
6496     }
6497 
6498     /* Open the audio encoder */
6499     err = pC->pAudioEncoderGlobalFcts->pFctOpen(pC->pAudioEncCtxt,
6500         &pC->AudioEncParams, &pC->pAudioEncDSI,
6501         M4OSA_NULL /* no grabbing */);
6502 
6503     if( M4NO_ERROR != err )
6504     {
6505         M4OSA_TRACE1_1(
6506             "M4MCS_intPrepareAudioProcessing: pAudioEncoderGlobalFcts->pFctOpen returns 0x%x",
6507             err);
6508         return err;
6509     }
6510 
6511     /* Allocate the input buffer for the audio encoder */
6512     switch( pC->AudioEncParams.Format )
6513     {
6514         case M4ENCODER_kAMRNB:
6515             pC->audioEncoderGranularity = M4MCS_PCM_AMR_GRANULARITY_SAMPLES;
6516             break;
6517 
6518         case M4ENCODER_kAAC:
6519             pC->audioEncoderGranularity = M4MCS_PCM_AAC_GRANULARITY_SAMPLES;
6520             break;
6521 
6522             /*FlB 26.02.2009: add mp3 as output format*/
6523         case M4ENCODER_kMP3:
6524             pC->audioEncoderGranularity = M4MCS_PCM_MP3_GRANULARITY_SAMPLES;
6525             break;
6526 
6527          default:
6528          break;
6529     }
6530 
6531     if( M4ENCODER_kMono == pC->AudioEncParams.ChannelNum )
6532         pC->audioEncoderGranularity *= sizeof(short);
6533     else
6534         pC->audioEncoderGranularity *= sizeof(short) * 2;
6535 
6536     pC->pPosInAudioEncoderBuffer = M4OSA_NULL;
6537     pC->pAudioEncoderBuffer =
6538         (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->audioEncoderGranularity, M4MCS,
6539         (M4OSA_Char *)"pC->pAudioEncoderBuffer");
6540 
6541     /**
6542     * Return with no error */
6543     M4OSA_TRACE3_0("M4MCS_intPrepareAudioProcessing(): returning M4NO_ERROR");
6544     return M4NO_ERROR;
6545 }
6546 
6547 /**
6548  ******************************************************************************
6549  * M4OSA_ERR M4MCS_intPrepareWriter(M4MCS_InternalContext* pC);
6550  * @brief    Prepare the writer.
6551  * @param    pC          (IN) MCS private context
6552  * @return   M4NO_ERROR  No error
6553  * @return   Any error returned by an underlaying module
6554  ******************************************************************************
6555  */
M4MCS_intPrepareWriter(M4MCS_InternalContext * pC)6556 static M4OSA_ERR M4MCS_intPrepareWriter( M4MCS_InternalContext *pC )
6557 {
6558     M4OSA_ERR err;
6559     M4OSA_UInt32 uiVersion; /**< To write component version in 3gp writer */
6560     M4OSA_MemAddr8 pDSI = M4OSA_NULL; /**< To create the Decoder Specific Info */
6561     M4SYS_StreamIDValue optionValue; /**< For the setoption calls */
6562     M4OSA_UInt32 TargetedFileSize;
6563     M4OSA_Bool bMULPPSSPS = M4OSA_FALSE;
6564 
6565     /**
6566     * Init the writer */
6567     err = pC->pWriterGlobalFcts->pFctOpen(&pC->pWriterContext, pC->pOutputFile,
6568         pC->pOsaFileWritPtr, pC->pTemporaryFile, pC->pOsaFileReadPtr);
6569 
6570     if( M4NO_ERROR != err )
6571     {
6572         M4OSA_TRACE1_1(
6573             "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctOpen returns 0x%x",
6574             err);
6575         return err;
6576     }
6577 
6578     /**
6579     * Link to the writer context in the writer interface */
6580     pC->pWriterDataFcts->pWriterContext = pC->pWriterContext;
6581 
6582     /**
6583     * Set the product description string in the written file */
6584     err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
6585         M4WRITER_kEmbeddedString, (M4OSA_DataOption)"NXP-SW : MCS    ");
6586 
6587     if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
6588         != err) ) /* this option may not be implemented by some writers */
6589     {
6590         M4OSA_TRACE1_1(
6591             "M4MCS_intPrepareWriter:\
6592              pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedString) returns 0x%x",
6593             err);
6594         return err;
6595     }
6596 
6597     /**
6598     * Set the product version in the written file */
6599     uiVersion =
6600         M4VIDEOEDITING_VERSION_MAJOR * 100 + M4VIDEOEDITING_VERSION_MINOR * 10
6601         + M4VIDEOEDITING_VERSION_REVISION;
6602     err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
6603         M4WRITER_kEmbeddedVersion, (M4OSA_DataOption) &uiVersion);
6604 
6605     if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
6606         != err) ) /* this option may not be implemented by some writers */
6607     {
6608         M4OSA_TRACE1_1(
6609             "M4MCS_intPrepareWriter: \
6610             pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedVersion) returns 0x%x",
6611             err);
6612         return err;
6613     }
6614 
6615     /**
6616     * If there is a video input, allocate and fill the video stream structures for the writer */
6617     if( pC->novideo == M4OSA_FALSE )
6618     {
6619         /**
6620         * Fill Video properties structure for the AddStream method */
6621         pC->WriterVideoStreamInfo.height = pC->EncodingHeight;
6622         pC->WriterVideoStreamInfo.width = pC->EncodingWidth;
6623         pC->WriterVideoStreamInfo.fps =
6624             0; /**< Not used by the shell/core writer */
6625         pC->WriterVideoStreamInfo.Header.pBuf =
6626             M4OSA_NULL; /**< Will be updated later */
6627         pC->WriterVideoStreamInfo.Header.Size = 0; /**< Will be updated later */
6628 
6629         /**
6630         * Fill Video stream description structure for the AddStream method */
6631         switch( pC->EncodingVideoFormat )
6632         {
6633             case M4ENCODER_kMPEG4:
6634                 pC->WriterVideoStream.streamType = M4SYS_kMPEG_4;
6635                 break;
6636 
6637             case M4ENCODER_kH263:
6638                 pC->WriterVideoStream.streamType = M4SYS_kH263;
6639                 break;
6640 
6641             case M4ENCODER_kH264:
6642                 pC->WriterVideoStream.streamType = M4SYS_kH264;
6643                 break;
6644 
6645             case M4ENCODER_kNULL:
6646                 switch( pC->InputFileProperties.VideoStreamType )
6647                 {
6648                     case M4VIDEOEDITING_kMPEG4:
6649                         pC->WriterVideoStream.streamType = M4SYS_kMPEG_4;
6650                         break;
6651 
6652                     case M4VIDEOEDITING_kH263:
6653                         pC->WriterVideoStream.streamType = M4SYS_kH263;
6654                         break;
6655 
6656                     case M4VIDEOEDITING_kH264:
6657                         pC->WriterVideoStream.streamType = M4SYS_kH264;
6658                         break;
6659 
6660                     default:
6661                         M4OSA_TRACE1_1(
6662                             "M4MCS_intPrepareWriter: case input=M4ENCODER_kNULL, \
6663                             unknown format (0x%x),\
6664                              returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT",
6665                             pC->EncodingVideoFormat);
6666                         return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT;
6667                 }
6668                 break;
6669 
6670             default: /**< It should never happen, already tested */
6671                 M4OSA_TRACE1_1(
6672                     "M4MCS_intPrepareWriter: unknown format (0x%x),\
6673                      returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT",
6674                     pC->EncodingVideoFormat);
6675                 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT;
6676         }
6677 
6678         /**
6679         * Video bitrate value will be the real value */
6680         pC->WriterVideoStream.averageBitrate =
6681             (M4OSA_Int32)pC->uiEncVideoBitrate;
6682         pC->WriterVideoStream.maxBitrate = (M4OSA_Int32)pC->uiEncVideoBitrate;
6683 
6684         /**
6685         * most other parameters are "dummy" */
6686         pC->WriterVideoStream.streamID = M4MCS_WRITER_VIDEO_STREAM_ID;
6687         pC->WriterVideoStream.timeScale =
6688             0; /**< Not used by the shell/core writer */
6689         pC->WriterVideoStream.profileLevel =
6690             0; /**< Not used by the shell/core writer */
6691         pC->WriterVideoStream.duration =
6692             0; /**< Not used by the shell/core writer */
6693         pC->WriterVideoStream.decoderSpecificInfoSize =
6694             sizeof(M4WRITER_StreamVideoInfos);
6695         pC->WriterVideoStream.decoderSpecificInfo =
6696             (M4OSA_MemAddr32) &(pC->WriterVideoStreamInfo);
6697 
6698         /**
6699         * Update Encoder Header properties for Video stream if needed */
6700         if( M4ENCODER_kH263 == pC->EncodingVideoFormat )
6701         {
6702             /**
6703             * Creates the H263 DSI */
6704             pC->WriterVideoStreamInfo.Header.Size =
6705                 7; /**< H263 output DSI is always 7 bytes */
6706             pDSI = (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(7, M4MCS, (M4OSA_Char
6707                 *)"pC->WriterVideoStreamInfo.Header.pBuf (DSI H263)");
6708 
6709             if( M4OSA_NULL == pDSI )
6710             {
6711                 M4OSA_TRACE1_0("M4MCS_intPrepareWriter(): unable to allocate pDSI (H263),\
6712                                returning M4ERR_ALLOC");
6713                 return M4ERR_ALLOC;
6714             }
6715 
6716             /**
6717             * Vendor is NXP Software: N, X, P, S. */
6718             pDSI[0] = 'N';
6719             pDSI[1] = 'X';
6720             pDSI[2] = 'P';
6721             pDSI[3] = 'S';
6722 
6723             /**
6724             * Decoder version is 0 */
6725             pDSI[4] = 0;
6726 
6727             /**
6728             * Level is the sixth byte of the DSI. */
6729             switch( pC->EncodingWidth )
6730             {
6731                 case M4ENCODER_SQCIF_Width:
6732                 case M4ENCODER_QCIF_Width:
6733                     if( ( pC->uiEncVideoBitrate <= M4ENCODER_k64_KBPS)
6734                         && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) )
6735                     {
6736                         pDSI[5] = 10;
6737                     }
6738                     else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS)
6739                         && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) )
6740                     {
6741                         pDSI[5] = 45;
6742                     }
6743                     else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS)
6744                         && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
6745                     {
6746                         pDSI[5] = 20;
6747                     }
6748                     else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k384_KBPS)
6749                         && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
6750                     {
6751                         pDSI[5] = 30;
6752                     }
6753                     else if( ( pC->uiEncVideoBitrate
6754                         <= M4ENCODER_k800_KBPS/*2048*/)
6755                         && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
6756                     {
6757                         pDSI[5] = 40;
6758                     }
6759                     break;
6760 
6761                 case M4ENCODER_CIF_Width:
6762                     if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS)
6763                         && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) )
6764                     {
6765                         pDSI[5] = 20;
6766                     }
6767                     else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k384_KBPS)
6768                         && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
6769                     {
6770                         pDSI[5] = 30;
6771                     }
6772                     else if( ( pC->uiEncVideoBitrate
6773                         <= M4ENCODER_k800_KBPS/*2048*/)
6774                         && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
6775                     {
6776                         pDSI[5] = 40;
6777                     }
6778                     break;
6779 
6780                     default:
6781                     break;
6782             }
6783 
6784             /**
6785             * Profile is the seventh byte of the DSI. */
6786             pDSI[6] = 0;
6787 
6788             pC->WriterVideoStreamInfo.Header.pBuf = pDSI;
6789         }
6790         else if( M4ENCODER_kNULL == pC->EncodingVideoFormat )
6791         {
6792             /* If we copy the stream from the input, we copy its DSI */
6793 
6794             pC->WriterVideoStreamInfo.Header.Size = pC->pReaderVideoStream->
6795                 m_basicProperties.m_decoderSpecificInfoSize;
6796             pC->WriterVideoStreamInfo.Header.pBuf =
6797                 (M4OSA_MemAddr8)pC->pReaderVideoStream->
6798                 m_basicProperties.m_pDecoderSpecificInfo;
6799 
6800         }
6801         /* otherwise (MPEG4), the DSI will be recovered from the encoder later on. */
6802 
6803         /*+CRLV6775 - H.264 Trimming  */
6804         if( pC->bH264Trim == M4OSA_TRUE )
6805         {
6806             bMULPPSSPS = M4OSA_TRUE;
6807             err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
6808                 (M4OSA_UInt32)M4WRITER_kMUL_PPS_SPS,
6809                 (M4OSA_DataOption) &bMULPPSSPS);
6810 
6811             if( ( M4NO_ERROR != err)
6812                 && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
6813                 != err) ) /* this option may not be implemented by some writers */
6814             {
6815                 M4OSA_TRACE1_1(
6816                     "M4MCS_intPrepareWriter:\
6817                      pWriterGlobalFcts->pFctSetOption(M4WRITER_kMUL_PPS_SPS) returns 0x%x",
6818                     err);
6819                 return err;
6820             }
6821         }
6822         /*-CRLV6775 - H.264 Trimming  */
6823         /**
6824         * Add the video stream */
6825         err = pC->pWriterGlobalFcts->pFctAddStream(pC->pWriterContext,
6826             &pC->WriterVideoStream);
6827 
6828         if( M4NO_ERROR != err )
6829         {
6830             M4OSA_TRACE1_1(
6831                 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctAddStream(video) returns 0x%x!",
6832                 err);
6833             return err;
6834         }
6835 
6836         /**
6837         * Update AU properties for video stream */
6838         pC->WriterVideoAU.stream = &(pC->WriterVideoStream);
6839         pC->WriterVideoAU.dataAddress = M4OSA_NULL;
6840         pC->WriterVideoAU.size = 0;
6841         pC->WriterVideoAU.CTS = 0; /** Reset time */
6842         pC->WriterVideoAU.DTS = 0;
6843         pC->WriterVideoAU.attribute = AU_RAP;
6844         pC->WriterVideoAU.nbFrag = 0; /** No fragment */
6845         pC->WriterVideoAU.frag = M4OSA_NULL;
6846 
6847         /**
6848         * Set the writer max video AU size */
6849         optionValue.streamID = M4MCS_WRITER_VIDEO_STREAM_ID;
6850         optionValue.value = pC->uiVideoMaxAuSize;
6851         err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
6852             (M4OSA_UInt32)M4WRITER_kMaxAUSize,
6853             (M4OSA_DataOption) &optionValue);
6854 
6855         if( M4NO_ERROR != err )
6856         {
6857             M4OSA_TRACE1_1(
6858                 "M4MCS_intPrepareWriter: \
6859                 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!",
6860                 err);
6861             return err;
6862         }
6863 
6864         /**
6865         * Set the writer max video chunk size */
6866         optionValue.value = pC->uiVideoMaxChunckSize;
6867         err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
6868             (M4OSA_UInt32)M4WRITER_kMaxChunckSize,
6869             (M4OSA_DataOption) &optionValue);
6870 
6871         if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
6872             != err) ) /* this option may not be implemented by some writers */
6873         {
6874             M4OSA_TRACE1_1(
6875                 "M4MCS_intPrepareWriter:\
6876                  pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!",
6877                 err);
6878             return err;
6879         }
6880     }
6881 
6882     /**
6883     * If there is an audio input, allocate and fill the audio stream structures for the writer */
6884     if( pC->noaudio == M4OSA_FALSE )
6885     {
6886         M4WRITER_StreamAudioInfos streamAudioInfo;
6887 
6888         streamAudioInfo.nbSamplesPerSec = 0; /**< unused by our shell writer */
6889         streamAudioInfo.nbBitsPerSample = 0; /**< unused by our shell writer */
6890         streamAudioInfo.nbChannels = 1;      /**< unused by our shell writer */
6891 
6892         pC->WriterAudioStream.averageBitrate =
6893             0; /**< It is not used by the shell, the DSI is taken into account instead */
6894         pC->WriterAudioStream.maxBitrate =
6895             0; /**< Not used by the shell/core writer */
6896 
6897         /**
6898         * Fill Audio stream description structure for the AddStream method */
6899         switch( pC->AudioEncParams.Format )
6900         {
6901             case M4ENCODER_kAMRNB:
6902                 pC->WriterAudioStream.streamType = M4SYS_kAMR;
6903                 break;
6904 
6905             case M4ENCODER_kAAC:
6906                 pC->WriterAudioStream.streamType = M4SYS_kAAC;
6907                 pC->WriterAudioStream.averageBitrate =
6908                     pC->AudioEncParams.Bitrate;
6909                 pC->WriterAudioStream.maxBitrate = pC->AudioEncParams.Bitrate;
6910                 break;
6911 
6912                 /*FlB 26.02.2009: add mp3 as output format*/
6913             case M4ENCODER_kMP3:
6914                 pC->WriterAudioStream.streamType = M4SYS_kMP3;
6915                 break;
6916 
6917             case M4ENCODER_kAudioNULL:
6918                 switch( pC->InputFileProperties.AudioStreamType )
6919                 {
6920                 case M4VIDEOEDITING_kAMR_NB:
6921                     pC->WriterAudioStream.streamType = M4SYS_kAMR;
6922                     break;
6923                     /*FlB 26.02.2009: add mp3 as output format*/
6924                 case M4VIDEOEDITING_kMP3:
6925                     pC->WriterAudioStream.streamType = M4SYS_kMP3;
6926                     break;
6927 
6928                 case M4VIDEOEDITING_kAAC:
6929                 case M4VIDEOEDITING_kAACplus:
6930                 case M4VIDEOEDITING_keAACplus:
6931                     pC->WriterAudioStream.streamType = M4SYS_kAAC;
6932                     pC->WriterAudioStream.averageBitrate =
6933                         pC->AudioEncParams.Bitrate;
6934                     pC->WriterAudioStream.maxBitrate =
6935                         pC->AudioEncParams.Bitrate;
6936                     break;
6937 
6938                 case M4VIDEOEDITING_kEVRC:
6939                     pC->WriterAudioStream.streamType = M4SYS_kEVRC;
6940                     break;
6941 
6942                 case M4VIDEOEDITING_kNoneAudio:
6943                 case M4VIDEOEDITING_kPCM:
6944                 case M4VIDEOEDITING_kNullAudio:
6945                 case M4VIDEOEDITING_kUnsupportedAudio:
6946                     break;
6947                 }
6948                 break;
6949 
6950             default: /**< It should never happen, already tested */
6951                 M4OSA_TRACE1_1(
6952                     "M4MCS_intPrepareWriter: \
6953                     unknown format (0x%x), returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT",
6954                     pC->AudioEncParams.Format);
6955                 return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT;
6956         }
6957 
6958         /**
6959         * MCS produces only AMR-NB output */
6960         pC->WriterAudioStream.streamID = M4MCS_WRITER_AUDIO_STREAM_ID;
6961         pC->WriterAudioStream.duration =
6962             0; /**< Not used by the shell/core writer */
6963         pC->WriterAudioStream.profileLevel =
6964             0; /**< Not used by the shell/core writer */
6965         pC->WriterAudioStream.timeScale = pC->AudioEncParams.Frequency;
6966 
6967         if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
6968         {
6969             /* If we copy the stream from the input, we copy its DSI */
6970             streamAudioInfo.Header.Size = pC->pReaderAudioStream->
6971                 m_basicProperties.m_decoderSpecificInfoSize;
6972             streamAudioInfo.Header.pBuf =
6973                 (M4OSA_MemAddr8)pC->pReaderAudioStream->
6974                 m_basicProperties.m_pDecoderSpecificInfo;
6975         }
6976         else
6977         {
6978             if( pC->pAudioEncDSI.pInfo != M4OSA_NULL )
6979             {
6980                 /* Use the DSI given by the encoder open() */
6981                 streamAudioInfo.Header.Size = pC->pAudioEncDSI.infoSize;
6982                 streamAudioInfo.Header.pBuf = pC->pAudioEncDSI.pInfo;
6983             }
6984             else
6985             {
6986                 /* Writer will put a default Philips DSI */
6987                 streamAudioInfo.Header.Size = 0;
6988                 streamAudioInfo.Header.pBuf = M4OSA_NULL;
6989             }
6990         }
6991 
6992         /**
6993         * Our writer shell interface is a little tricky: we put M4WRITER_StreamAudioInfos
6994          in the DSI pointer... */
6995         pC->WriterAudioStream.decoderSpecificInfo =
6996             (M4OSA_MemAddr32) &streamAudioInfo;
6997 
6998         /**
6999         * Add the audio stream to the writer */
7000         err = pC->pWriterGlobalFcts->pFctAddStream(pC->pWriterContext,
7001             &pC->WriterAudioStream);
7002 
7003         if( M4NO_ERROR != err )
7004         {
7005             M4OSA_TRACE1_1(
7006                 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctAddStream(audio) returns 0x%x",
7007                 err);
7008             return err;
7009         }
7010 
7011         /**
7012         * Link the AU and the stream */
7013         pC->WriterAudioAU.stream = &(pC->WriterAudioStream);
7014         pC->WriterAudioAU.dataAddress = M4OSA_NULL;
7015         pC->WriterAudioAU.size = 0;
7016         pC->WriterAudioAU.CTS = 0; /** Reset time */
7017         pC->WriterAudioAU.DTS = 0;
7018         pC->WriterAudioAU.attribute = 0;
7019         pC->WriterAudioAU.nbFrag = 0; /** No fragment */
7020         pC->WriterAudioAU.frag = M4OSA_NULL;
7021 
7022         /**
7023         * Set the writer audio max AU size */
7024         /* As max bitrate is now 320kbps instead of 128kbps, max AU
7025          * size has to be increased adapt the max AU size according to the stream type and the
7026          * channels numbers*/
7027         /* After tests, a margin of 3 is taken (2 was not enough and raises to memory overwrite)
7028          */
7029         //pC->uiAudioMaxAuSize = M4MCS_AUDIO_MAX_AU_SIZE;
7030         switch( pC->WriterAudioStream.streamType )
7031         {
7032             case M4SYS_kAMR:
7033                 pC->uiAudioMaxAuSize = M4MCS_PCM_AMR_GRANULARITY_SAMPLES
7034                     * (( pC->InputFileProperties.uiNbChannels
7035                     * sizeof(short)) + 3);
7036                 break;
7037 
7038             case M4SYS_kMP3:
7039                 pC->uiAudioMaxAuSize = M4MCS_PCM_MP3_GRANULARITY_SAMPLES
7040                     * (( pC->InputFileProperties.uiNbChannels
7041                     * sizeof(short)) + 3);
7042                 break;
7043 
7044             case M4SYS_kAAC:
7045                 pC->uiAudioMaxAuSize = M4MCS_PCM_AAC_GRANULARITY_SAMPLES
7046                     * (( pC->InputFileProperties.uiNbChannels
7047                     * sizeof(short)) + 3);
7048                 break;
7049                 /*case M4SYS_kEVRC:
7050                 pC->uiAudioMaxAuSize = M4MCS_PCM_EVRC_GRANULARITY_SAMPLES*
7051                 ((pC->InputFileProperties.uiNbChannels * sizeof(short))+3);
7052                 break;*/
7053             default: /**< It should never happen, already tested */
7054                 M4OSA_TRACE1_1(
7055                     "M4MCS_intPrepareWriter: unknown format (0x%x),\
7056                      returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT",
7057                     pC->WriterAudioStream.streamType);
7058                 return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT;
7059         }
7060 
7061         optionValue.streamID = M4MCS_WRITER_AUDIO_STREAM_ID;
7062         optionValue.value = pC->uiAudioMaxAuSize;
7063         err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
7064             (M4OSA_UInt32)M4WRITER_kMaxAUSize,
7065             (M4OSA_DataOption) &optionValue);
7066 
7067         if( M4NO_ERROR != err )
7068         {
7069             M4OSA_TRACE1_1(
7070                 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption(audio,\
7071                 M4WRITER_kMaxAUSize) returns 0x%x",
7072                 err);
7073             return err;
7074         }
7075 
7076         optionValue.value = M4MCS_AUDIO_MAX_CHUNK_SIZE;
7077         err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
7078             (M4OSA_UInt32)M4WRITER_kMaxChunckSize,
7079             (M4OSA_DataOption) &optionValue);
7080 
7081         if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
7082             != err) ) /* this option may not be implemented by some writers */
7083         {
7084             M4OSA_TRACE1_1(
7085                 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption(audio,\
7086                 M4WRITER_kMaxChunckSize) returns 0x%x",
7087                 err);
7088             return err;
7089         }
7090     }
7091 
7092     /*
7093     * Set the limitation size of the writer */
7094     TargetedFileSize = pC->uiMaxFileSize;
7095     /* add 1 kB margin */
7096     if( TargetedFileSize > 8192 )
7097         TargetedFileSize -= 1024;
7098 
7099     err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
7100         (M4OSA_UInt32)M4WRITER_kMaxFileSize,
7101         (M4OSA_DataOption) &TargetedFileSize);
7102 
7103     if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
7104         != err) ) /* this option may not be implemented by some writers */
7105     {
7106         M4OSA_TRACE1_1(
7107             "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption\
7108             (M4WRITER_kMaxFileSize) returns 0x%x!",
7109             err);
7110         return err;
7111     }
7112 
7113     /**
7114     * Close the stream registering in order to be ready to write data */
7115     err = pC->pWriterGlobalFcts->pFctStartWriting(pC->pWriterContext);
7116 
7117     if( M4NO_ERROR != err )
7118     {
7119         M4OSA_TRACE1_1(
7120             "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctStartWriting returns 0x%x",
7121             err);
7122         return err;
7123     }
7124 
7125     /**
7126     * Return with no error */
7127     M4OSA_TRACE3_0("M4MCS_intPrepareWriter(): returning M4NO_ERROR");
7128     return M4NO_ERROR;
7129 }
7130 
7131 /**
7132  ******************************************************************************
7133  * M4OSA_ERR M4MCS_intPrepareAudioBeginCut(M4MCS_InternalContext* pC);
7134  * @brief    DO the audio begin cut.
7135  * @param    pC          (IN) MCS private context
7136  * @return   M4NO_ERROR  No error
7137  * @return   Any error returned by an underlaying module
7138  ******************************************************************************
7139  */
M4MCS_intPrepareAudioBeginCut(M4MCS_InternalContext * pC)7140 static M4OSA_ERR M4MCS_intPrepareAudioBeginCut( M4MCS_InternalContext *pC )
7141 {
7142     M4OSA_ERR err;
7143     M4OSA_Int32 iCts;
7144     M4OSA_UInt32 uiFrameSize;
7145 
7146     if( pC->noaudio )
7147         return M4NO_ERROR;
7148 
7149     /**
7150     * Check if an audio begin cut is needed */
7151     if( ( M4OSA_NULL == pC->pReaderAudioStream) || (0 == pC->uiBeginCutTime) )
7152     {
7153         /**
7154         * Return with no error */
7155         M4OSA_TRACE3_0(
7156             "M4MCS_intPrepareAudioBeginCut(): returning M4NO_ERROR (a)");
7157         return M4NO_ERROR;
7158     }
7159 
7160     /**
7161     * Jump at the begin cut time */
7162     iCts = pC->uiBeginCutTime;
7163     err = pC->m_pReader->m_pFctJump(pC->pReaderContext,
7164         (M4_StreamHandler *)pC->pReaderAudioStream, &iCts);
7165 
7166     if( M4NO_ERROR != err )
7167     {
7168         M4OSA_TRACE1_1(
7169             "M4MCS_intPrepareAudioBeginCut: m_pFctJump(Audio) returns 0x%x!",
7170             err);
7171         return err;
7172     }
7173 
7174     /**
7175     * Remember audio begin cut offset */
7176     pC->iAudioCtsOffset = iCts;
7177 
7178     /**
7179     * AMR-NB & EVRC: there may be many frames per AU.
7180     * In that case we need to slice the first AU to keep the 20 ms cut precision */
7181     if( ( M4DA_StreamTypeAudioAmrNarrowBand
7182         == pC->pReaderAudioStream->m_basicProperties.m_streamType)
7183         || (M4DA_StreamTypeAudioEvrc
7184         == pC->pReaderAudioStream->m_basicProperties.m_streamType) )
7185     {
7186         /**
7187         * If the next frame CTS is lower than the begin cut time,
7188         * we must read the AU and parse its frames to reach the
7189         * nearest to the begin cut */
7190         if( ( iCts + 20) < (M4OSA_Int32)pC->uiBeginCutTime )
7191         {
7192             /**
7193             * Read the first audio AU after the jump */
7194             err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
7195                 (M4_StreamHandler *)pC->pReaderAudioStream,
7196                 &pC->ReaderAudioAU);
7197 
7198             if( M4WAR_NO_MORE_AU == err )
7199             {
7200                 M4OSA_TRACE1_0(
7201                     "M4MCS_intPrepareAudioBeginCut(): m_pReaderDataIt->m_pFctGetNextAu(audio)\
7202                      returns M4WAR_NO_MORE_AU! Returning M4NO_ERROR");
7203                 return
7204                     M4NO_ERROR; /**< no fatal error here, we should be able to pursue */
7205             }
7206             else if( M4NO_ERROR != err )
7207             {
7208                 M4OSA_TRACE1_1(
7209                     "M4MCS_intPrepareAudioBeginCut(): m_pReaderDataIt->m_pFctGetNextAu(Audio)\
7210                      returns 0x%x",
7211                     err);
7212                 return err;
7213             }
7214 
7215             /**
7216             * While the next AU has a lower CTS than the begin cut time, we advance to
7217             the next frame */
7218             while( ( iCts + 20) <= (M4OSA_Int32)pC->uiBeginCutTime )
7219             {
7220                 /**
7221                 * Get the size of the frame */
7222                 switch( pC->pReaderAudioStream->m_basicProperties.m_streamType )
7223                 {
7224                     case M4DA_StreamTypeAudioAmrNarrowBand:
7225                         uiFrameSize = M4MCS_intGetFrameSize_AMRNB(
7226                             pC->ReaderAudioAU.m_dataAddress);
7227                         break;
7228 
7229                     case M4DA_StreamTypeAudioEvrc:
7230                         uiFrameSize = M4MCS_intGetFrameSize_EVRC(
7231                             pC->ReaderAudioAU.m_dataAddress);
7232                         break;
7233 
7234                     default:
7235                         uiFrameSize = 0;
7236                         break;
7237                 }
7238 
7239                 if( 0 == uiFrameSize )
7240                 {
7241                     /**
7242                     * Corrupted frame! We get out of this mess!
7243                     * We don't want to crash here... */
7244                     M4OSA_TRACE1_0(
7245                         "M4MCS_intPrepareAudioBeginCut(): \
7246                         M4MCS_intGetFrameSize_xxx returns 0! Returning M4NO_ERROR");
7247                     return
7248                         M4NO_ERROR; /**< no fatal error here, we should be able to pursue */
7249                 }
7250 
7251                 /**
7252                 * Go to the next frame */
7253                 pC->ReaderAudioAU.m_dataAddress += uiFrameSize;
7254                 pC->ReaderAudioAU.m_size -= uiFrameSize;
7255 
7256                 /**
7257                 * Get the CTS of the next frame */
7258                 iCts += 20; /**< AMR, EVRC frame duration is always 20 ms */
7259                 pC->ReaderAudioAU.m_CTS = iCts;
7260                 pC->ReaderAudioAU.m_DTS = iCts;
7261             }
7262 
7263             /**
7264             * Update the audio begin cut offset */
7265             pC->iAudioCtsOffset = iCts;
7266         }
7267     }
7268 
7269     /**
7270     * Return with no error */
7271     M4OSA_TRACE3_0("M4MCS_intPrepareAudioBeginCut(): returning M4NO_ERROR");
7272     return M4NO_ERROR;
7273 }
7274 
7275 /**
7276  ******************************************************************************
7277  * M4OSA_ERR M4MCS_intStepEncoding(M4MCS_InternalContext* pC, M4OSA_UInt8* pProgress)
7278  ******************************************************************************
7279  */
M4MCS_intStepEncoding(M4MCS_InternalContext * pC,M4OSA_UInt8 * pProgress)7280 static M4OSA_ERR M4MCS_intStepEncoding( M4MCS_InternalContext *pC,
7281                                        M4OSA_UInt8 *pProgress )
7282 {
7283     M4OSA_ERR err;
7284     M4OSA_UInt32 uiAudioStepCount = 0;
7285 
7286     /* ---------- VIDEO TRANSCODING ---------- */
7287 
7288     if( ( pC->novideo == M4OSA_FALSE) && (M4MCS_kStreamState_STARTED
7289         == pC->VideoState) ) /**< If the video encoding is going on */
7290     {
7291         if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
7292         {
7293             err = M4MCS_intVideoNullEncoding(pC);
7294         }
7295         else
7296         {
7297             err = M4MCS_intVideoTranscoding(pC);
7298         }
7299 
7300         /**
7301         * No more space, quit properly */
7302         if( M4WAR_WRITER_STOP_REQ == err )
7303         {
7304             *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->dViDecCurrentCts
7305                 - pC->uiBeginCutTime) * 100)
7306                 / (pC->uiEndCutTime - pC->uiBeginCutTime));
7307 
7308             pC->State = M4MCS_kState_FINISHED;
7309 
7310             /* bad file produced on very short 3gp file */
7311             if( pC->dViDecCurrentCts - pC->uiBeginCutTime == 0 )
7312             {
7313                 /* Nothing has been encoded -> bad produced file -> error returned */
7314                 M4OSA_TRACE2_0(
7315                     "M4MCS_intStepEncoding(): video transcoding returns\
7316                      M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL");
7317                 return M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL;
7318             }
7319             else
7320             {
7321 #ifndef M4MCS_AUDIOONLY
7322                 /* clean AIR context needed to keep media aspect ratio*/
7323 
7324                 if( M4OSA_NULL != pC->m_air_context )
7325                 {
7326                     err = M4AIR_cleanUp(pC->m_air_context);
7327 
7328                     if( err != M4NO_ERROR )
7329                     {
7330                         M4OSA_TRACE1_1(
7331                             "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x",
7332                             err);
7333                         return err;
7334                     }
7335                     pC->m_air_context = M4OSA_NULL;
7336                 }
7337 
7338 #endif /*M4MCS_AUDIOONLY*/
7339 
7340                 M4OSA_TRACE2_0(
7341                     "M4MCS_intStepEncoding(): video transcoding returns M4MCS_ERR_NOMORE_SPACE");
7342                 return M4MCS_ERR_NOMORE_SPACE;
7343             }
7344         }
7345 
7346         /**< The input plane is null because the input image will be obtained by the
7347         VPP filter from the context */
7348         if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) )
7349         {
7350             M4OSA_TRACE1_1(
7351                 "M4MCS_intStepEncoding(): video transcoding returns 0x%x!",
7352                 err);
7353             return err;
7354         }
7355     }
7356 
7357     /* ---------- AUDIO TRANSCODING ---------- */
7358 
7359     if( ( pC->noaudio == M4OSA_FALSE) && (M4MCS_kStreamState_STARTED
7360         == pC->AudioState) ) /**< If there is an audio stream */
7361     {
7362         while(
7363             /**< If the video encoding is running, encode audio until we reach video time */
7364             ( ( pC->novideo == M4OSA_FALSE)
7365             && (M4MCS_kStreamState_STARTED == pC->VideoState)
7366             && (pC->ReaderAudioAU.m_CTS
7367             + pC->m_audioAUDuration < pC->ReaderVideoAU.m_CTS)) ||
7368             /**< If the video encoding is not running, perform 1 step of audio encoding */
7369             (( M4MCS_kStreamState_STARTED == pC->AudioState)
7370             && (uiAudioStepCount < 1)) )
7371         {
7372             uiAudioStepCount++;
7373 
7374             /**< check if an adio effect has to be applied*/
7375             err = M4MCS_intCheckAudioEffects(pC);
7376 
7377             if( M4NO_ERROR != err )
7378             {
7379                 M4OSA_TRACE1_1(
7380                     "M4MCS_intStepEncoding(): M4MCS_intCheckAudioEffects returns err: 0x%x",
7381                     err);
7382                 return err;
7383             }
7384 
7385             if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
7386             {
7387                 err = M4MCS_intAudioNullEncoding(pC);
7388             }
7389             else /**< Audio transcoding */
7390             {
7391                 err = M4MCS_intAudioTranscoding(pC);
7392             }
7393 
7394             /**
7395             * No more space, quit properly */
7396             if( M4WAR_WRITER_STOP_REQ == err )
7397             {
7398                 *pProgress =
7399                     (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS
7400                     - pC->uiBeginCutTime) * 100)
7401                     / (pC->uiEndCutTime - pC->uiBeginCutTime));
7402 
7403                 pC->State = M4MCS_kState_FINISHED;
7404 
7405                 /* bad file produced on very short 3gp file */
7406                 if( pC->ReaderAudioAU.m_CTS - pC->uiBeginCutTime == 0 )
7407                 {
7408                     /* Nothing has been encoded -> bad produced file -> error returned */
7409                     M4OSA_TRACE2_0(
7410                         "M4MCS_intStepEncoding():\
7411                          audio transcoding returns M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL");
7412                     return M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL;
7413                 }
7414                 else
7415                 {
7416 #ifndef M4MCS_AUDIOONLY
7417                     /* clean AIR context needed to keep media aspect ratio*/
7418 
7419                     if( M4OSA_NULL != pC->m_air_context )
7420                     {
7421                         err = M4AIR_cleanUp(pC->m_air_context);
7422 
7423                         if( err != M4NO_ERROR )
7424                         {
7425                             M4OSA_TRACE1_1(
7426                                 "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x",
7427                                 err);
7428                             return err;
7429                         }
7430                         pC->m_air_context = M4OSA_NULL;
7431                     }
7432 
7433 #endif /*M4MCS_AUDIOONLY*/
7434 
7435                     M4OSA_TRACE2_0(
7436                         "M4MCS_intStepEncoding(): \
7437                         audio transcoding returns M4MCS_ERR_NOMORE_SPACE");
7438                     return M4MCS_ERR_NOMORE_SPACE;
7439                 }
7440             }
7441 
7442             if( M4WAR_NO_MORE_AU == err )
7443             {
7444                 pC->AudioState = M4MCS_kStreamState_FINISHED;
7445                 M4OSA_TRACE3_0(
7446                     "M4MCS_intStepEncoding(): audio transcoding returns M4WAR_NO_MORE_AU");
7447                 break;
7448             }
7449             else if( M4NO_ERROR != err )
7450             {
7451                 M4OSA_TRACE1_1(
7452                     "M4MCS_intStepEncoding(): audio transcoding returns 0x%x",
7453                     err);
7454                 return err;
7455             }
7456 
7457             /**
7458             * Check for end cut */
7459             /* We absolutely want to have less or same audio duration as video ->
7460             (2*pC->m_audioAUDuration) */
7461             if( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS
7462                 + (2 *pC->m_audioAUDuration) > pC->uiEndCutTime )
7463             {
7464                 pC->AudioState = M4MCS_kStreamState_FINISHED;
7465                 break;
7466             }
7467         }
7468     }
7469 
7470     /* ---------- PROGRESS MANAGEMENT ---------- */
7471 
7472     /**
7473     * Compute progress */
7474     if( pC->novideo )
7475     {
7476         if( pC->ReaderAudioAU.m_CTS < pC->uiBeginCutTime )
7477         {
7478             *pProgress = 0;
7479         }
7480         else
7481         {
7482             *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS
7483                 - pC->uiBeginCutTime) * 100)
7484                 / (pC->uiEndCutTime - pC->uiBeginCutTime));
7485         }
7486         //printf(": %6.0f\b\b\b\b\b\b\b\b", pC->ReaderAudioAU.m_CTS);
7487 
7488     }
7489     else
7490     {
7491         if( pC->dViDecCurrentCts < pC->uiBeginCutTime )
7492         {
7493             *pProgress = 0;
7494         }
7495         else
7496         {
7497             *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->dViDecCurrentCts
7498                 - pC->uiBeginCutTime) * 100)
7499                 / (pC->uiEndCutTime - pC->uiBeginCutTime));
7500         }
7501         //printf(": %6.0f\b\b\b\b\b\b\b\b", pC->dViDecCurrentCts);
7502     }
7503 
7504     /**
7505     * Sanity check */
7506     if( *pProgress > 99 )
7507     {
7508         *pProgress = 99;
7509     }
7510 
7511     /**
7512     * Increment CTS for next step */
7513     if( pC->novideo == M4OSA_FALSE )
7514     {
7515         if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
7516         {
7517            pC->dViDecCurrentCts +=  1;
7518         }
7519         else
7520         {
7521             pC->dViDecCurrentCts += pC->dCtsIncrement;
7522         }
7523     }
7524 
7525     /**
7526     * The transcoding is finished when no stream is being encoded anymore */
7527     if( ( ( pC->novideo) || (M4MCS_kStreamState_FINISHED == pC->VideoState))
7528         && (( pC->noaudio) || (M4MCS_kStreamState_FINISHED == pC->AudioState)) )
7529     {
7530         /* the AIR part can only be used when video codecs are compiled*/
7531 #ifndef M4MCS_AUDIOONLY
7532         /* clean AIR context needed to keep media aspect ratio*/
7533 
7534         if( M4OSA_NULL != pC->m_air_context )
7535         {
7536             err = M4AIR_cleanUp(pC->m_air_context);
7537 
7538             if( err != M4NO_ERROR )
7539             {
7540                 M4OSA_TRACE1_1(
7541                     "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x",
7542                     err);
7543                 return err;
7544             }
7545             pC->m_air_context = M4OSA_NULL;
7546         }
7547 
7548 #endif /*M4MCS_AUDIOONLY*/
7549         /**/
7550 
7551         *pProgress = 100;
7552         pC->State = M4MCS_kState_FINISHED;
7553         M4OSA_TRACE2_0(
7554             "M4MCS_intStepEncoding(): transcoding finished, returning M4MCS_WAR_TRANSCODING_DONE");
7555         return M4MCS_WAR_TRANSCODING_DONE;
7556     }
7557 
7558     /**
7559     * Return with no error */
7560     M4OSA_TRACE3_0("M4MCS_intStepEncoding(): returning M4NO_ERROR");
7561     return M4NO_ERROR;
7562 }
7563 
7564 /**
7565  ******************************************************************************
7566  * M4OSA_ERR M4MCS_intStepBeginVideoJump(M4MCS_InternalContext* pC)
7567  ******************************************************************************
7568  */
M4MCS_intStepBeginVideoJump(M4MCS_InternalContext * pC)7569 static M4OSA_ERR M4MCS_intStepBeginVideoJump( M4MCS_InternalContext *pC )
7570 {
7571     M4OSA_ERR err;
7572     M4OSA_Int32 iCts;
7573 
7574     if( pC->novideo )
7575     {
7576         pC->State = M4MCS_kState_BEGINVIDEODECODE;
7577         return M4NO_ERROR;
7578     }
7579 
7580     /**
7581     * Jump to the previous RAP in the clip (first get the time, then jump) */
7582     iCts = (M4OSA_Int32)pC->dViDecStartingCts;
7583     err = pC->m_pReader->m_pFctGetPrevRapTime(pC->pReaderContext,
7584         (M4_StreamHandler *)pC->pReaderVideoStream, &iCts);
7585 
7586     if( M4WAR_READER_INFORMATION_NOT_PRESENT == err )
7587     {
7588         /* No RAP table, jump backward and predecode */
7589         iCts = (M4OSA_Int32)pC->dViDecStartingCts - M4MCS_NO_STSS_JUMP_POINT;
7590 
7591         if( iCts < 0 )
7592             iCts = 0;
7593     }
7594     else if( M4NO_ERROR != err )
7595     {
7596         M4OSA_TRACE1_1(
7597             "M4MCS_intStepBeginVideoJump: m_pFctGetPrevRapTime returns 0x%x!",
7598             err);
7599         return err;
7600     }
7601 
7602     /* + CRLV6775 -H.264 Trimming */
7603 
7604     if( M4OSA_TRUE == pC->bH264Trim )
7605     {
7606 
7607         // Save jump time for safety, this fix should be generic
7608 
7609         M4OSA_Int32 iCtsOri = iCts;
7610 
7611 
7612         err = pC->m_pReader->m_pFctJump(pC->pReaderContext,
7613             (M4_StreamHandler *)pC->pReaderVideoStream, &iCts);
7614 
7615         if( M4NO_ERROR != err )
7616         {
7617             M4OSA_TRACE1_1(
7618                 "M4MCS_intStepBeginVideoJump: m_pFctJump(V) returns 0x%x!",
7619                 err);
7620             return err;
7621         }
7622 
7623         if( pC->ReaderVideoAU1.m_structSize == 0 )
7624         {
7625             /**
7626             * Initializes an access Unit */
7627             err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
7628                 (M4_StreamHandler *)pC->pReaderVideoStream,
7629                 &pC->ReaderVideoAU1);
7630 
7631             if( M4NO_ERROR != err )
7632             {
7633                 M4OSA_TRACE1_1(
7634                     "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
7635                     err);
7636                 return err;
7637             }
7638             err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
7639                 (M4_StreamHandler *)pC->pReaderVideoStream,
7640                 &pC->ReaderVideoAU1);
7641 
7642             if( M4WAR_NO_MORE_AU == err )
7643             {
7644                 M4OSA_TRACE2_0(
7645                     "M4MCS_intVideoNullEncoding(): \
7646                     m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU");
7647                 /* The audio transcoding is finished */
7648                 pC->VideoState = M4MCS_kStreamState_FINISHED;
7649                 return err;
7650             }
7651             else if( M4NO_ERROR != err )
7652             {
7653                 M4OSA_TRACE1_1(
7654                     "M4MCS_intVideoNullEncoding():\
7655                      m_pReaderDataIt->m_pFctGetNextAu(video) returns 0x%x",
7656                     err);
7657                 return err;
7658             }
7659 
7660             pC->ReaderVideoAU1.m_structSize = 0;
7661         }
7662 
7663         err = H264MCS_ProcessSPS_PPS(pC->m_pInstance,
7664             (M4OSA_UInt8 *)pC->ReaderVideoAU1.m_dataAddress, pC->ReaderVideoAU1.m_size);
7665 
7666         if( M4NO_ERROR != err )
7667         {
7668             M4OSA_TRACE1_1(
7669                 "M4MCS_intStepBeginVideoJump: H264MCS_ProcessSPS_PPS returns 0x%x!",
7670                 err);
7671             return err;
7672         }
7673 
7674 
7675         // Restore jump time for safety, this fix should be generic
7676 
7677         iCts = iCtsOri;
7678 
7679 
7680     }
7681     /* - CRLV6775 -H.264 Trimming */
7682 
7683     /**
7684     * Decode one step */
7685     pC->dViDecCurrentCts = (M4OSA_Double)(iCts + pC->iVideoBeginDecIncr);
7686 
7687     /**
7688     * Be sure we don't decode too far */
7689     if( pC->dViDecCurrentCts > pC->dViDecStartingCts )
7690     {
7691         pC->dViDecCurrentCts = pC->dViDecStartingCts;
7692     }
7693 
7694     /**
7695     * Decode at least once with the bJump flag to true */
7696     M4OSA_TRACE3_1(
7697         "M4VSS3GPP_intClipDecodeVideoUpToCts: Decoding upTo CTS %.3f",
7698         pC->dViDecCurrentCts);
7699     pC->isRenderDup = M4OSA_FALSE;
7700     err =
7701         pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &pC->dViDecCurrentCts,
7702         M4OSA_TRUE, 0);
7703 
7704     if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err)
7705         && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) )
7706     {
7707         M4OSA_TRACE1_1(
7708             "M4MCS_intStepBeginVideoJump: m_pFctDecode returns 0x%x!", err);
7709         return err;
7710     }
7711 
7712     if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME )
7713     {
7714         M4OSA_TRACE2_0("Decoding output the same frame as before 1");
7715         pC->isRenderDup = M4OSA_TRUE;
7716     }
7717 
7718     /**
7719     * Increment decoding cts for the next step */
7720     pC->dViDecCurrentCts += (M4OSA_Double)pC->iVideoBeginDecIncr;
7721 
7722     /**
7723     * Update state automaton */
7724     if( pC->dViDecCurrentCts > pC->dViDecStartingCts )
7725     {
7726         /**
7727         * Be sure we don't decode too far */
7728         pC->dViDecCurrentCts = pC->dViDecStartingCts;
7729         pC->State = M4MCS_kState_PROCESSING;
7730     }
7731     else
7732     {
7733         pC->State = M4MCS_kState_BEGINVIDEODECODE;
7734     }
7735 
7736     /**
7737     * Return with no error */
7738     M4OSA_TRACE3_0("M4MCS_intStepBeginVideoJump(): returning M4NO_ERROR");
7739     return M4NO_ERROR;
7740 }
7741 
7742 /**
7743  ******************************************************************************
7744  * M4OSA_ERR M4MCS_intStepBeginVideoDecode(M4MCS_InternalContext* pC)
7745  ******************************************************************************
7746  */
M4MCS_intStepBeginVideoDecode(M4MCS_InternalContext * pC)7747 static M4OSA_ERR M4MCS_intStepBeginVideoDecode( M4MCS_InternalContext *pC )
7748 {
7749     M4OSA_ERR err;
7750     M4_MediaTime dDecTarget;
7751 
7752     if( pC->novideo )
7753     {
7754         pC->State = M4MCS_kState_PROCESSING;
7755         return M4NO_ERROR;
7756     }
7757 
7758     /**
7759     * Decode */
7760     dDecTarget = pC->dViDecCurrentCts;
7761     M4OSA_TRACE3_1("M4MCS_intStepBeginDecode: Decoding upTo CTS %.3f",
7762         pC->dViDecCurrentCts);
7763     pC->isRenderDup = M4OSA_FALSE;
7764     err = pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &dDecTarget,
7765         M4OSA_FALSE, 0);
7766 
7767     if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err)
7768         && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) )
7769     {
7770         M4OSA_TRACE1_1(
7771             "M4MCS_intStepBeginVideoDecode: m_pFctDecode returns 0x%x!", err);
7772         return err;
7773     }
7774 
7775     if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME )
7776     {
7777         M4OSA_TRACE2_0("Decoding output the same frame as before 2");
7778         pC->isRenderDup = M4OSA_TRUE;
7779     }
7780 
7781     /**
7782     * Increment decoding cts for the next step */
7783     pC->dViDecCurrentCts += (M4OSA_Double)pC->iVideoBeginDecIncr;
7784 
7785     /**
7786     * Update state automaton, if needed */
7787     if( ( (M4OSA_UInt32)pC->dViDecCurrentCts > pC->dViDecStartingCts)
7788         || (M4WAR_NO_MORE_AU == err) )
7789     {
7790         /**
7791         * Be sure we don't decode too far */
7792         pC->dViDecCurrentCts = (M4OSA_Double)pC->dViDecStartingCts;
7793         pC->State = M4MCS_kState_PROCESSING;
7794     }
7795 
7796     /**
7797     * Return with no error */
7798     M4OSA_TRACE3_0("M4MCS_intStepBeginVideoDecode(): returning M4NO_ERROR");
7799     return M4NO_ERROR;
7800 }
7801 
7802 /*****************************/
7803 /* define AMR silence frames */
7804 /*****************************/
7805 
7806 #define M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE 13
7807 #define M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_DURATION 160
7808 
7809 #ifdef M4VSS3GPP_SILENCE_FRAMES
7810 
7811 const M4OSA_UInt8 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048[
7812     M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE] =
7813     {
7814         0x04, 0xFF, 0x18, 0xC7, 0xF0, 0x0D, 0x04, 0x33, 0xFF, 0xE0, 0x00, 0x00, 0x00
7815     };
7816 #else
7817 
7818 extern
7819 const
7820 M4OSA_UInt8
7821 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048[M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE];
7822 
7823 #endif
7824 
7825 /*****************************/
7826 /* define AAC silence frames */
7827 /*****************************/
7828 
7829 #define M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE      4
7830 
7831 #ifdef M4VSS3GPP_SILENCE_FRAMES
7832 
7833 const M4OSA_UInt8 M4VSS3GPP_AAC_AU_SILENCE_MONO[
7834     M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE] =
7835     {
7836         0x00, 0xC8, 0x20, 0x07
7837     };
7838 #else
7839 
7840 extern const M4OSA_UInt8
7841 M4VSS3GPP_AAC_AU_SILENCE_MONO[M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE];
7842 
7843 #endif
7844 
7845 #define M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE        6
7846 
7847 #ifdef M4VSS3GPP_SILENCE_FRAMES
7848 
7849 const M4OSA_UInt8 M4VSS3GPP_AAC_AU_SILENCE_STEREO[
7850     M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE] =
7851     {
7852         0x21, 0x10, 0x03, 0x20, 0x54, 0x1C
7853     };
7854 #else
7855 
7856 extern const
7857 M4OSA_UInt8
7858 M4VSS3GPP_AAC_AU_SILENCE_STEREO[M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE];
7859 
7860 #endif
7861 
7862 /**
7863  ******************************************************************************
7864  * M4OSA_ERR M4MCS_intAudioNullEncoding(M4MCS_InternalContext* pC)
7865  * @return   M4NO_ERROR:         No error
7866  ******************************************************************************
7867  */
7868 
M4MCS_intAudioNullEncoding(M4MCS_InternalContext * pC)7869 static M4OSA_ERR M4MCS_intAudioNullEncoding( M4MCS_InternalContext *pC )
7870 {
7871     M4OSA_ERR err;
7872 
7873     if( pC->noaudio )
7874         return M4NO_ERROR;
7875 
7876     /* Check if all audio frame has been written (happens at begin cut) */
7877     if( pC->ReaderAudioAU.m_size == 0 )
7878     {
7879         /**
7880         * Initializes a new AU if needed */
7881         if( pC->ReaderAudioAU1.m_structSize == 0 )
7882         {
7883             /**
7884             * Initializes an access Unit */
7885             err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
7886                 (M4_StreamHandler *)pC->pReaderAudioStream,
7887                 &pC->ReaderAudioAU1);
7888 
7889             if( M4NO_ERROR != err )
7890             {
7891                 M4OSA_TRACE1_1(
7892                     "M4MCS_open(): m_pReader->m_pFctFillAuStruct(audio) returns 0x%x",
7893                     err);
7894                 return err;
7895             }
7896 
7897             pC->m_pDataAddress1 =
7898                 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderAudioAU1.m_maxsize,
7899                 M4MCS, (M4OSA_Char *)"Temporary AU1 buffer");
7900 
7901             if( pC->m_pDataAddress1 == M4OSA_NULL )
7902             {
7903                 M4OSA_TRACE1_0(
7904                     "M4MCS_intAudioNullEncoding(): allocation error");
7905                 return M4ERR_ALLOC;
7906             }
7907 
7908             err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
7909                 (M4_StreamHandler *)pC->pReaderAudioStream,
7910                 &pC->ReaderAudioAU1);
7911 
7912             if( M4WAR_NO_MORE_AU == err )
7913             {
7914                 M4OSA_TRACE2_0(
7915                     "M4MCS_intAudioNullEncoding():\
7916                      m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU");
7917                 /* The audio transcoding is finished */
7918                 pC->AudioState = M4MCS_kStreamState_FINISHED;
7919                 return err;
7920             }
7921             else if( M4NO_ERROR != err )
7922             {
7923                 M4OSA_TRACE1_1(
7924                     "M4MCS_intAudioNullEncoding(): \
7925                     m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x",
7926                     err);
7927                 return err;
7928             }
7929             /*FB 2009.04.02: PR surnxp#616: Crash in MCS while Audio AU copying ,
7930              constant memory reader case*/
7931             if( pC->ReaderAudioAU1.m_maxsize
7932         > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize )
7933             {
7934                 /* Constant memory reader case, we need to reallocate the temporary buffers */
7935                 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
7936                     *) &(pC->m_pDataAddress1), pC->ReaderAudioAU1.m_maxsize);
7937                 /* pC->m_pDataAddress1 and
7938                 pC->m_pDataAddress2 must be reallocated at the same time */
7939                 /* because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take
7940                  maximum value. Then the test "if(pC->ReaderAudioAU?.m_maxsize >
7941                   pC->pReaderAudioStream->m_basicProperties.m_maxAUSize)" is never true */
7942                 /* and the size of the second buffer is never changed. */
7943                 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
7944                     *) &(pC->m_pDataAddress2), pC->ReaderAudioAU1.m_maxsize);
7945                 /* pC->m_pDataAddress1 and
7946                 pC->m_pDataAddress2 must be reallocated at the same time */
7947                 /* Update stream properties */
7948                 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize =
7949                     pC->ReaderAudioAU1.m_maxsize;
7950             }
7951             /**/
7952             memcpy((void *)pC->m_pDataAddress1,
7953                 (void *)pC->ReaderAudioAU1.m_dataAddress,
7954                 pC->ReaderAudioAU1.m_size);
7955         }
7956 
7957         if( pC->ReaderAudioAU2.m_structSize == 0 )
7958         {
7959             /**
7960             * Initializes an access Unit */
7961             err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
7962                 (M4_StreamHandler *)pC->pReaderAudioStream,
7963                 &pC->ReaderAudioAU2);
7964 
7965             if( M4NO_ERROR != err )
7966             {
7967                 M4OSA_TRACE1_1(
7968                     "M4MCS_open(): m_pReader->m_pFctFillAuStruct(audio) returns 0x%x",
7969                     err);
7970                 return err;
7971             }
7972             pC->m_pDataAddress2 =
7973                 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderAudioAU2.m_maxsize,
7974                 M4MCS, (M4OSA_Char *)"Temporary AU buffer");
7975 
7976             if( pC->m_pDataAddress2 == M4OSA_NULL )
7977             {
7978                 M4OSA_TRACE1_0(
7979                     "M4MCS_intAudioNullEncoding(): allocation error");
7980                 return M4ERR_ALLOC;
7981             }
7982         }
7983         /**
7984         * Read the next audio AU in the input file */
7985         if( pC->ReaderAudioAU2.m_CTS > pC->ReaderAudioAU1.m_CTS )
7986         {
7987             memcpy((void *) &pC->ReaderAudioAU,
7988                 (void *) &pC->ReaderAudioAU2, sizeof(M4_AccessUnit));
7989             err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
7990                 (M4_StreamHandler *)pC->pReaderAudioStream,
7991                 &pC->ReaderAudioAU1);
7992 
7993             if( pC->ReaderAudioAU1.m_maxsize
7994                 > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize )
7995             {
7996                 /* Constant memory reader case, we need to reallocate the temporary buffers */
7997                 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
7998                     *) &(pC->m_pDataAddress1), pC->ReaderAudioAU1.m_maxsize);
7999                 /*   pC->m_pDataAddress1
8000                  * and pC->m_pDataAddress2 must be reallocated at the same time *
8001                  * because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take
8002                  * maximum value. Then the test "if(pC->ReaderAudioAU?.m_maxsize >
8003                  * pC->pReaderAudioStream->m_basicProperties.m_maxAUSize)" is never true *
8004                  * and the size of the second buffer is never changed.
8005                  */
8006                 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
8007                     *) &(pC->m_pDataAddress2), pC->ReaderAudioAU1.m_maxsize);
8008                 /* pC->m_pDataAddress1 and
8009                  * pC->m_pDataAddress2 must be reallocated at the same time
8010                  * Update stream properties
8011                  */
8012                 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize =
8013                     pC->ReaderAudioAU1.m_maxsize;
8014             }
8015             /**/
8016             memcpy((void *)pC->m_pDataAddress1,
8017                 (void *)pC->ReaderAudioAU1.m_dataAddress,
8018                 pC->ReaderAudioAU1.m_size);
8019             pC->m_audioAUDuration =
8020                 pC->ReaderAudioAU1.m_CTS - pC->ReaderAudioAU2.m_CTS;
8021             pC->ReaderAudioAU.m_dataAddress = pC->m_pDataAddress2;
8022         }
8023         else
8024         {
8025             memcpy((void *) &pC->ReaderAudioAU,
8026                 (void *) &pC->ReaderAudioAU1, sizeof(M4_AccessUnit));
8027             err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
8028                 (M4_StreamHandler *)pC->pReaderAudioStream,
8029                 &pC->ReaderAudioAU2);
8030             /* Crash in MCS while Audio AU copying ,
8031              * constant memory reader case
8032              */
8033             if( pC->ReaderAudioAU2.m_maxsize
8034                 > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize )
8035             {
8036                 /* Constant memory reader case, we need to reallocate the temporary buffers */
8037                 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
8038                     *) &(pC->m_pDataAddress2), pC->ReaderAudioAU2.m_maxsize);
8039                 /* pC->m_pDataAddress1 and
8040                  * pC->m_pDataAddress2 must be reallocated at the same time
8041                  * because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take maximum
8042                  * value. Then the test "if(pC->ReaderAudioAU?.m_maxsize > pC->pReaderAudioStream->
8043                  * m_basicProperties.m_maxAUSize)" is never true
8044                  * and the size of the second buffer is never changed.
8045                  */
8046                 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
8047                     *) &(pC->m_pDataAddress1), pC->ReaderAudioAU2.m_maxsize);
8048                 /* [ END ] 20091008  JFV PR fix surnxpsw#1071: pC->m_pDataAddress1 and
8049                  pC->m_pDataAddress2 must be reallocated at the same time */
8050                 /* Update stream properties */
8051                 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize =
8052                     pC->ReaderAudioAU2.m_maxsize;
8053             }
8054             /**/
8055             memcpy((void *)pC->m_pDataAddress2,
8056                 (void *)pC->ReaderAudioAU2.m_dataAddress,
8057                 pC->ReaderAudioAU2.m_size);
8058             pC->m_audioAUDuration =
8059                 pC->ReaderAudioAU2.m_CTS - pC->ReaderAudioAU1.m_CTS;
8060             pC->ReaderAudioAU.m_dataAddress = pC->m_pDataAddress1;
8061         }
8062 
8063         if( M4WAR_NO_MORE_AU == err )
8064         {
8065             M4OSA_TRACE2_0(
8066                 "M4MCS_intAudioNullEncoding(): \
8067                 m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU");
8068             /* The audio transcoding is finished */
8069             pC->AudioState = M4MCS_kStreamState_FINISHED;
8070             return err;
8071         }
8072         else if( M4NO_ERROR != err )
8073         {
8074             M4OSA_TRACE1_1(
8075                 "M4MCS_intAudioNullEncoding(): \
8076                 m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x",
8077                 err);
8078             return err;
8079         }
8080     }
8081 
8082     /**
8083     * Prepare the writer AU */
8084     err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext,
8085         M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
8086 
8087     if( M4NO_ERROR != err )
8088     {
8089         M4OSA_TRACE1_1(
8090             "M4MCS_intAudioNullEncoding(): pWriterDataFcts->pStartAU(Audio) returns 0x%x",
8091             err);
8092         return err;
8093     }
8094 
8095     if( pC->uiAudioAUCount
8096         == 0 ) /* If it is the first AU, we set it to silence
8097         (else, errors 0x3841, 0x3847 in our AAC decoder) */
8098     {
8099         if( pC->InputFileProperties.AudioStreamType == M4VIDEOEDITING_kAAC
8100             || pC->InputFileProperties.AudioStreamType
8101             == M4VIDEOEDITING_kAACplus
8102             || pC->InputFileProperties.AudioStreamType
8103             == M4VIDEOEDITING_keAACplus )
8104         {
8105             if( pC->InputFileProperties.uiNbChannels == 1 )
8106             {
8107                 pC->WriterAudioAU.size = M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE;
8108                 memcpy((void *)pC->WriterAudioAU.dataAddress,
8109                     (void *)M4VSS3GPP_AAC_AU_SILENCE_MONO,
8110                     pC->WriterAudioAU.size);
8111             }
8112             else if( pC->InputFileProperties.uiNbChannels == 2 )
8113             {
8114                 pC->WriterAudioAU.size = M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE;
8115                 memcpy((void *)pC->WriterAudioAU.dataAddress,
8116                     (void *)M4VSS3GPP_AAC_AU_SILENCE_STEREO,
8117                     pC->WriterAudioAU.size);
8118             }
8119             else
8120             {
8121                 /* Must never happen ...*/
8122                 M4OSA_TRACE1_0(
8123                     "M4MCS_intAudioNullEncoding: Bad number of channels in audio input");
8124                 return M4MCS_ERR_INVALID_INPUT_FILE;
8125             }
8126         }
8127         else if( pC->InputFileProperties.AudioStreamType
8128             == M4VIDEOEDITING_kAMR_NB )
8129         {
8130             pC->WriterAudioAU.size = M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE;
8131             memcpy((void *)pC->WriterAudioAU.dataAddress,
8132                 (void *)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048,
8133                 pC->WriterAudioAU.size);
8134             /* Some remaining AMR AU needs to be copied */
8135             if( pC->ReaderAudioAU.m_size != 0 )
8136             {
8137                 /* Update Writer AU */
8138                 pC->WriterAudioAU.size += pC->ReaderAudioAU.m_size;
8139                 memcpy((void *)(pC->WriterAudioAU.dataAddress
8140                     + M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE),
8141                     (void *)pC->ReaderAudioAU.m_dataAddress,
8142                     pC->ReaderAudioAU.m_size);
8143             }
8144         }
8145         else
8146         {
8147             /*MP3 case: copy the AU*/
8148             M4OSA_TRACE3_1(
8149                 "M4MCS_intAudioNullEncoding(): Copying audio AU: size=%d",
8150                 pC->ReaderAudioAU.m_size);
8151             memcpy((void *)pC->WriterAudioAU.dataAddress,
8152                 (void *)pC->ReaderAudioAU.m_dataAddress,
8153                 pC->ReaderAudioAU.m_size);
8154             pC->WriterAudioAU.size = pC->ReaderAudioAU.m_size;
8155         }
8156     }
8157     else
8158     {
8159         /**
8160         * Copy audio data from reader AU to writer AU */
8161         M4OSA_TRACE3_1(
8162             "M4MCS_intAudioNullEncoding(): Copying audio AU: size=%d",
8163             pC->ReaderAudioAU.m_size);
8164         memcpy((void *)pC->WriterAudioAU.dataAddress,
8165             (void *)pC->ReaderAudioAU.m_dataAddress,
8166             pC->ReaderAudioAU.m_size);
8167         pC->WriterAudioAU.size = pC->ReaderAudioAU.m_size;
8168     }
8169 
8170     /**
8171     * Convert CTS unit from milliseconds to timescale */
8172     pC->WriterAudioAU.CTS =
8173         (M4OSA_Time)((( pC->ReaderAudioAU.m_CTS - pC->iAudioCtsOffset)
8174         * (pC->WriterAudioStream.timeScale / 1000.0)));
8175 
8176     if( pC->InputFileProperties.AudioStreamType == M4VIDEOEDITING_kAMR_NB
8177         && pC->uiAudioAUCount == 0 )
8178     {
8179         pC->iAudioCtsOffset -=
8180             20; /* Duration of a silence AMR AU, to handle the duration of the added
8181                 silence frame */
8182     }
8183     pC->WriterAudioAU.nbFrag = 0;
8184     M4OSA_TRACE3_1("M4MCS_intAudioNullEncoding(): audio AU: CTS=%d ms",
8185         pC->WriterAudioAU.CTS);
8186 
8187     /**
8188     * Write it to the output file */
8189     pC->uiAudioAUCount++;
8190     err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext,
8191         M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
8192 
8193     if( M4NO_ERROR != err )
8194     {
8195         M4OSA_TRACE1_1(
8196             "M4MCS_intAudioNullEncoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x",
8197             err);
8198         return err;
8199     }
8200 
8201     /* All the audio has been written */
8202     pC->ReaderAudioAU.m_size = 0;
8203 
8204     /**
8205     * Return with no error */
8206     M4OSA_TRACE3_0("M4MCS_intAudioNullEncoding(): returning M4NO_ERROR");
8207     return M4NO_ERROR;
8208 }
8209 
8210 /**
8211  ******************************************************************************
8212  * @brief    Init Audio Transcoding
8213  * @return   M4NO_ERROR:         No error
8214  ******************************************************************************
8215  */
M4MCS_intAudioTranscoding(M4MCS_InternalContext * pC)8216 static M4OSA_ERR M4MCS_intAudioTranscoding( M4MCS_InternalContext *pC )
8217 {
8218     M4OSA_ERR err;                        /**< General error */
8219 
8220     M4OSA_UInt32
8221         uiBytesDec; /**< Nb of bytes available in the decoder OUT buffer */
8222     M4OSA_UInt32
8223         uiDecoder2Ssrc_NbBytes; /**< Nb of bytes copied into the ssrc IN buffer */
8224 
8225     int ssrcErr;                          /**< Error while ssrc processing */
8226     M4OSA_UInt32 uiSsrcInSize; /**< Size in bytes of ssrc intput buffer */
8227     M4OSA_UInt32
8228         uiSsrcInRoom; /**< Nb of bytes available in the ssrc IN buffer */
8229     M4OSA_MemAddr8
8230         pSsrcInput; /**< Pointer to the good buffer location for ssrc input */
8231     M4OSA_UInt32 uiSsrcOutSize; /**< Size in bytes of ssrc output buffer */
8232     M4OSA_UInt32
8233         uiBytesSsrc; /**< Nb of bytes available in the ssrc OUT buffer */
8234 
8235     M4OSA_UInt8
8236         needChannelConversion; /**< Flag to indicate if a stereo <-> mono conversion is needed */
8237     M4OSA_UInt32
8238         uiChannelConvertorCoeff; /**< Multiplicative coefficient if stereo
8239                                     <-> mono conversion is applied */
8240     M4OSA_MemAddr8 pChannelConvertorInput =
8241         M4OSA_NULL; /**< Pointer to the good buffer location for channel convertor input */
8242     M4OSA_UInt32 uiChannelConvertorNbSamples =
8243         0; /**< Nb of pcm samples to convert in channel convertor */
8244     M4OSA_MemAddr8 pChannelConvertorOutput =
8245         M4OSA_NULL; /**< Pointer to the good buffer location for channel convertor output */
8246 
8247     M4OSA_Time
8248         frameTimeDelta; /**< Duration of the encoded (then written) data */
8249     M4OSA_UInt32
8250         uiEncoderInRoom; /**< Nb of bytes available in the encoder IN buffer */
8251     M4OSA_UInt32
8252         uiSsrc2Encoder_NbBytes; /**< Nb of bytes copied from the ssrc OUT buffer */
8253     M4OSA_MemAddr8
8254         pEncoderInput; /**< Pointer to the good buffer location for encoder input */
8255     M4ENCODER_AudioBuffer pEncInBuffer;   /**< Encoder input buffer for api */
8256     M4ENCODER_AudioBuffer pEncOutBuffer;  /**< Encoder output buffer for api */
8257 
8258     M4OSA_Int16 *tempBuffOut = M4OSA_NULL;
8259     /*FlB 2009.03.04: apply audio effects if an effect is active*/
8260     M4OSA_Int8 *pActiveEffectNumber = &(pC->pActiveEffectNumber);
8261 
8262     uint32_t errCode = M4NO_ERROR;
8263 
8264     if( pC->noaudio )
8265         return M4NO_ERROR;
8266 
8267     /* _________________ */
8268     /*|                 |*/
8269     /*| READ AND DECODE |*/
8270     /*|_________________|*/
8271 
8272     /* Check if we have to empty the decoder out buffer first */
8273     if( M4OSA_NULL != pC->pPosInDecBufferOut )
8274     {
8275         goto m4mcs_intaudiotranscoding_feed_resampler;
8276     }
8277 
8278     err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt,
8279         M4OSA_NULL, &pC->AudioDecBufferOut, M4OSA_FALSE);
8280 
8281 
8282     if( M4NO_ERROR != err )
8283     {
8284         M4OSA_TRACE1_1(
8285             "M4MCS_intAudioTranscoding(): m_pAudioDecoder->m_pFctStepAudio returns 0x%x",
8286             err);
8287         return err;
8288     }
8289 
8290 #ifdef MCS_DUMP_PCM_TO_FILE
8291 
8292     fwrite(pC->AudioDecBufferOut.m_dataAddress,
8293         pC->AudioDecBufferOut.m_bufferSize, 1, file_pcm_decoder);
8294 
8295 #endif
8296 
8297     pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt,
8298            M4AD_kOptionID_GetAudioAUErrCode, (M4OSA_DataOption) &errCode);
8299 
8300     if ( M4WAR_NO_MORE_AU == errCode ) {
8301         pC->AudioState = M4MCS_kStreamState_FINISHED;
8302             M4OSA_TRACE2_0(
8303                 "M4MCS_intAudioTranscoding():\
8304                  m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU");
8305             return errCode;
8306    }
8307 
8308     /* Set the current position in the decoder out buffer */
8309     pC->pPosInDecBufferOut = pC->AudioDecBufferOut.m_dataAddress;
8310 
8311     /* ________________ */
8312     /*|                |*/
8313     /*| FEED RESAMPLER |*/
8314     /*|________________|*/
8315 
8316 m4mcs_intaudiotranscoding_feed_resampler:
8317 
8318     /* Check if we have to empty the ssrc out buffer first */
8319     if( M4OSA_NULL != pC->pPosInSsrcBufferOut )
8320     {
8321         goto m4mcs_intaudiotranscoding_prepare_input_buffer;
8322     }
8323 
8324     /* Compute number of bytes remaining in the decoder buffer */
8325     uiSsrcInSize = pC->iSsrcNbSamplIn * sizeof(short)
8326         * pC->pReaderAudioStream->m_nbChannels;
8327     uiBytesDec = ( pC->AudioDecBufferOut.m_dataAddress
8328         + pC->AudioDecBufferOut.m_bufferSize) - pC->pPosInDecBufferOut;
8329 
8330     /* Check if we can feed directly the Ssrc with the decoder out buffer */
8331     if( ( pC->pPosInSsrcBufferIn == pC->pSsrcBufferIn)
8332         && (uiBytesDec >= uiSsrcInSize) )
8333     {
8334         pSsrcInput = pC->pPosInDecBufferOut;
8335 
8336         /* update data consumed into decoder buffer after resampling */
8337         if( uiBytesDec == uiSsrcInSize )
8338             pC->pPosInDecBufferOut = M4OSA_NULL;
8339         else
8340             pC->pPosInDecBufferOut += uiSsrcInSize;
8341 
8342         goto m4mcs_intaudiotranscoding_do_resampling;
8343     }
8344 
8345     /**
8346     * Compute remaining space in Ssrc buffer in */
8347     uiSsrcInRoom = ( pC->pSsrcBufferIn + uiSsrcInSize) - pC->pPosInSsrcBufferIn;
8348 
8349     /**
8350     * Nb of bytes copied is the minimum between nb of bytes remaining in
8351     * decoder out buffer and space remaining in ssrc in buffer */
8352     uiDecoder2Ssrc_NbBytes =
8353         (uiSsrcInRoom < uiBytesDec) ? uiSsrcInRoom : uiBytesDec;
8354 
8355     /**
8356     * Copy from the decoder out buffer into the Ssrc in buffer */
8357     memcpy((void *)pC->pPosInSsrcBufferIn, (void *)pC->pPosInDecBufferOut,
8358         uiDecoder2Ssrc_NbBytes);
8359 
8360     /**
8361     * Update the position in the decoder out buffer */
8362     pC->pPosInDecBufferOut += uiDecoder2Ssrc_NbBytes;
8363 
8364     /**
8365     * Update the position in the Ssrc in buffer */
8366     pC->pPosInSsrcBufferIn += uiDecoder2Ssrc_NbBytes;
8367 
8368     /**
8369     * Check if the decoder buffer out is empty */
8370     if( ( pC->pPosInDecBufferOut - pC->AudioDecBufferOut.m_dataAddress)
8371         == (M4OSA_Int32)pC->AudioDecBufferOut.m_bufferSize )
8372     {
8373         pC->pPosInDecBufferOut = M4OSA_NULL;
8374     }
8375 
8376     /* Check if the Ssrc in buffer is ready (= full) */
8377     if( ( pC->pPosInSsrcBufferIn - pC->pSsrcBufferIn)
8378         < (M4OSA_Int32)uiSsrcInSize )
8379     {
8380         goto m4mcs_intaudiotranscoding_end;
8381     }
8382 
8383     pSsrcInput = pC->pSsrcBufferIn;
8384 
8385     /* update data consumed into ssrc buffer in after resampling (empty) */
8386     pC->pPosInSsrcBufferIn = pC->pSsrcBufferIn;
8387 
8388     /* ___________________ */
8389     /*|                   |*/
8390     /*| DO THE RESAMPLING |*/
8391     /*|___________________|*/
8392 
8393 m4mcs_intaudiotranscoding_do_resampling:
8394 
8395     /**
8396     * No need for memcopy, we can feed Ssrc directly with the data in the audio
8397     decoder out buffer*/
8398 
8399     ssrcErr = 0;
8400 
8401     if( pC->pReaderAudioStream->m_nbChannels == 1 )
8402     {
8403         tempBuffOut =
8404             (short *)M4OSA_32bitAlignedMalloc((pC->iSsrcNbSamplOut * sizeof(short) * 2
8405             * ((*pC).InputFileProperties).uiNbChannels),
8406             M4VSS3GPP,(M4OSA_Char *) "tempBuffOut");
8407         memset((void *)tempBuffOut, 0,(pC->iSsrcNbSamplOut * sizeof(short) * 2
8408             * ((*pC).InputFileProperties).uiNbChannels));
8409 
8410         LVAudioresample_LowQuality((short *)tempBuffOut, (short *)pSsrcInput,
8411             pC->iSsrcNbSamplOut, pC->pLVAudioResampler);
8412     }
8413     else
8414     {
8415         memset((void *)pC->pSsrcBufferOut, 0, (pC->iSsrcNbSamplOut * sizeof(short)
8416             * ((*pC).InputFileProperties).uiNbChannels));
8417 
8418         LVAudioresample_LowQuality((short *)pC->pSsrcBufferOut,
8419             (short *)pSsrcInput, pC->iSsrcNbSamplOut, pC->pLVAudioResampler);
8420     }
8421 
8422     if( pC->pReaderAudioStream->m_nbChannels == 1 )
8423     {
8424         From2iToMono_16((short *)tempBuffOut, (short *)pC->pSsrcBufferOut,
8425             (short)pC->iSsrcNbSamplOut);
8426         free(tempBuffOut);
8427     }
8428 
8429 
8430     if( 0 != ssrcErr )
8431     {
8432         M4OSA_TRACE1_1(
8433             "M4MCS_intAudioTranscoding: SSRC_Process returns 0x%x, \
8434             returning M4MCS_ERR_AUDIO_CONVERSION_FAILED",
8435             ssrcErr);
8436         return M4MCS_ERR_AUDIO_CONVERSION_FAILED;
8437     }
8438 
8439     pC->pPosInSsrcBufferOut = pC->pSsrcBufferOut;
8440 
8441     /* ______________________ */
8442     /*|                      |*/
8443     /*| PREPARE INPUT BUFFER |*/
8444     /*|______________________|*/
8445 
8446 m4mcs_intaudiotranscoding_prepare_input_buffer:
8447 
8448     /* Set the flag for channel conversion requirement */
8449     if( ( pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
8450         && (pC->pReaderAudioStream->m_nbChannels == 2) )
8451     {
8452         needChannelConversion = 1;
8453         uiChannelConvertorCoeff = 4;
8454     }
8455     else if( ( pC->AudioEncParams.ChannelNum == M4ENCODER_kStereo)
8456         && (pC->pReaderAudioStream->m_nbChannels == 1) )
8457     {
8458         needChannelConversion = 2;
8459         uiChannelConvertorCoeff = 1;
8460     }
8461     else
8462     {
8463         needChannelConversion = 0;
8464         uiChannelConvertorCoeff = 2;
8465     }
8466 
8467     /* Compute number of bytes remaining in the Ssrc buffer */
8468     uiSsrcOutSize = pC->iSsrcNbSamplOut * sizeof(short)
8469         * pC->pReaderAudioStream->m_nbChannels;
8470     uiBytesSsrc =
8471         ( pC->pSsrcBufferOut + uiSsrcOutSize) - pC->pPosInSsrcBufferOut;
8472 
8473     /* Check if the ssrc buffer is full */
8474     if( pC->pPosInSsrcBufferOut == pC->pSsrcBufferOut )
8475     {
8476         uiSsrc2Encoder_NbBytes =
8477             pC->audioEncoderGranularity * uiChannelConvertorCoeff / 2;
8478 
8479         /* Check if we can feed directly the encoder with the ssrc out buffer */
8480         if( ( pC->pPosInAudioEncoderBuffer == M4OSA_NULL)
8481             && (uiBytesSsrc >= uiSsrc2Encoder_NbBytes) )
8482         {
8483             /* update position in ssrc out buffer after encoding */
8484             if( uiBytesSsrc == uiSsrc2Encoder_NbBytes )
8485                 pC->pPosInSsrcBufferOut = M4OSA_NULL;
8486             else
8487                 pC->pPosInSsrcBufferOut += uiSsrc2Encoder_NbBytes;
8488 
8489             /* mark the encoder buffer ready (= full) */
8490             pC->pPosInAudioEncoderBuffer =
8491                 pC->pAudioEncoderBuffer + pC->audioEncoderGranularity;
8492 
8493             if( needChannelConversion > 0 )
8494             {
8495                 /* channel convertor writes directly into encoder buffer */
8496                 pEncoderInput = pC->pAudioEncoderBuffer;
8497 
8498                 pChannelConvertorInput = pC->pSsrcBufferOut;
8499                 pChannelConvertorOutput = pC->pAudioEncoderBuffer;
8500                 uiChannelConvertorNbSamples =
8501                     uiSsrc2Encoder_NbBytes / sizeof(short);
8502 
8503                 goto m4mcs_intaudiotranscoding_channel_convertor;
8504             }
8505             else
8506             {
8507                 /* encode directly from ssrc out buffer */
8508                 pEncoderInput = pC->pSsrcBufferOut;
8509 
8510                 goto m4mcs_intaudiotranscoding_encode_and_write;
8511             }
8512         }
8513     }
8514 
8515     /**
8516     * Compute remaining space in encoder buffer in */
8517     if( pC->pPosInAudioEncoderBuffer == M4OSA_NULL )
8518     {
8519         pC->pPosInAudioEncoderBuffer = pC->pAudioEncoderBuffer;
8520     }
8521 
8522     uiEncoderInRoom = ( pC->pAudioEncoderBuffer + pC->audioEncoderGranularity)
8523         - pC->pPosInAudioEncoderBuffer;
8524     pEncoderInput = pC->pAudioEncoderBuffer;
8525 
8526     /**
8527     * Nb of bytes copied is the minimum between nb of bytes remaining in
8528     * decoder out buffer and space remaining in ssrc in buffer */
8529     uiSsrc2Encoder_NbBytes =
8530         (( uiEncoderInRoom * uiChannelConvertorCoeff / 2) < uiBytesSsrc)
8531         ? (uiEncoderInRoom * uiChannelConvertorCoeff / 2) : uiBytesSsrc;
8532 
8533     if( needChannelConversion > 0 )
8534     {
8535         /* channel convertor writes directly into encoder buffer */
8536         pChannelConvertorInput = pC->pPosInSsrcBufferOut;
8537         pChannelConvertorOutput = pC->pPosInAudioEncoderBuffer;
8538         uiChannelConvertorNbSamples = uiSsrc2Encoder_NbBytes / sizeof(short);
8539     }
8540     else
8541     {
8542         /* copy from the ssrc out buffer into the encoder in buffer */
8543         memcpy((void *)pC->pPosInAudioEncoderBuffer, (void *)pC->pPosInSsrcBufferOut,
8544             uiSsrc2Encoder_NbBytes);
8545     }
8546 
8547     /* Update position in ssrc out buffer after encoding */
8548     pC->pPosInSsrcBufferOut += uiSsrc2Encoder_NbBytes;
8549 
8550     /* Update the position in the encoder in buffer */
8551     pC->pPosInAudioEncoderBuffer +=
8552         uiSsrc2Encoder_NbBytes * 2 / uiChannelConvertorCoeff;
8553 
8554     /* Check if the ssrc buffer out is empty */
8555     if( ( pC->pPosInSsrcBufferOut - pC->pSsrcBufferOut)
8556         == (M4OSA_Int32)uiSsrcOutSize )
8557     {
8558         pC->pPosInSsrcBufferOut = M4OSA_NULL;
8559     }
8560 
8561     /* go to next statement */
8562     if( needChannelConversion > 0 )
8563         goto m4mcs_intaudiotranscoding_channel_convertor;
8564     else
8565         goto m4mcs_intaudiotranscoding_encode_and_write;
8566 
8567     /* _________________ */
8568     /*|                 |*/
8569     /*| STEREO <-> MONO |*/
8570     /*|_________________|*/
8571 
8572 m4mcs_intaudiotranscoding_channel_convertor:
8573 
8574     /* convert the input pcm stream to mono or to stereo */
8575     switch( needChannelConversion )
8576     {
8577         case 1: /* stereo to mono */
8578             From2iToMono_16((short *)pChannelConvertorInput,
8579                 (short *)pChannelConvertorOutput,
8580                 (short)(uiChannelConvertorNbSamples / 2));
8581             break;
8582 
8583         case 2: /* mono to stereo */
8584             MonoTo2I_16((short *)pChannelConvertorInput,
8585                 (short *)pChannelConvertorOutput,
8586                 (short)uiChannelConvertorNbSamples);
8587             break;
8588     }
8589 
8590     /* __________________ */
8591     /*|                  |*/
8592     /*| ENCODE AND WRITE |*/
8593     /*|__________________|*/
8594 
8595 m4mcs_intaudiotranscoding_encode_and_write:
8596 
8597     /* Check if the encoder in buffer is ready (= full) */
8598     if( ( pC->pPosInAudioEncoderBuffer - pC->pAudioEncoderBuffer)
8599         < (M4OSA_Int32)pC->audioEncoderGranularity )
8600     {
8601         goto m4mcs_intaudiotranscoding_end;
8602     }
8603 
8604     /* [Mono] or [Stereo interleaved] : all is in one buffer */
8605     pEncInBuffer.pTableBuffer[0] = pEncoderInput;
8606     pEncInBuffer.pTableBufferSize[0] = pC->audioEncoderGranularity;
8607     pEncInBuffer.pTableBuffer[1] = M4OSA_NULL;
8608     pEncInBuffer.pTableBufferSize[1] = 0;
8609 
8610     /* Time in ms from data size, because it is PCM16 samples */
8611     frameTimeDelta =
8612         ( pEncInBuffer.pTableBufferSize[0] * uiChannelConvertorCoeff / 2)
8613         / sizeof(short) / pC->pReaderAudioStream->m_nbChannels;
8614 
8615     /**
8616     * Prepare the writer AU */
8617     err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext,
8618         M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
8619 
8620     if( M4NO_ERROR != err )
8621     {
8622         M4OSA_TRACE1_1(
8623             "M4MCS_intAudioTranscoding(): pWriterDataFcts->pStartAU(Audio) returns 0x%x",
8624             err);
8625         return err;
8626     }
8627 
8628     /*FlB 2009.03.04: apply audio effects if an effect is active*/
8629     if( *pActiveEffectNumber >= 0 && *pActiveEffectNumber < pC->nbEffects )
8630     {
8631         if( pC->pEffects[*pActiveEffectNumber].ExtAudioEffectFct != M4OSA_NULL )
8632         {
8633             M4MCS_ExternalProgress pProgress;
8634             M4OSA_UInt32 tempProgress = 0;
8635             pProgress.uiClipTime = (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS;
8636 
8637             pProgress.uiOutputTime = ( pC->WriterAudioAU.CTS * 1000)
8638                 / pC->WriterAudioStream.timeScale;
8639             tempProgress = ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS
8640                 - pC->pEffects[*pActiveEffectNumber].uiStartTime
8641                 - pC->uiBeginCutTime) * 1000;
8642             pProgress.uiProgress =
8643                 (M4OSA_UInt32)(tempProgress / (M4OSA_UInt32)pC->pEffects[
8644                     *pActiveEffectNumber].uiDuration);
8645 
8646                     err = pC->pEffects[*pActiveEffectNumber].ExtAudioEffectFct(
8647                         pC->pEffects[*pActiveEffectNumber].pExtAudioEffectFctCtxt,
8648                         (M4OSA_Int16 *)pEncInBuffer.pTableBuffer[0],
8649                         pEncInBuffer.pTableBufferSize[0], &pProgress);
8650 
8651                     if( err != M4NO_ERROR )
8652                     {
8653                         M4OSA_TRACE1_1(
8654                             "M4MCS_intAudioTranscoding(): ExtAudioEffectFct() returns 0x%x",
8655                             err);
8656                         return err;
8657                     }
8658         }
8659     }
8660 
8661     /**
8662     * Prepare output buffer */
8663     pEncOutBuffer.pTableBuffer[0] =
8664         (M4OSA_MemAddr8)pC->WriterAudioAU.dataAddress;
8665     pEncOutBuffer.pTableBufferSize[0] = 0;
8666 
8667 #ifdef MCS_DUMP_PCM_TO_FILE
8668 
8669     fwrite(pEncInBuffer.pTableBuffer[0], pEncInBuffer.pTableBufferSize[0], 1,
8670         file_pcm_encoder);
8671 
8672 #endif
8673 
8674     if( M4OSA_FALSE == pC->b_isRawWriter )
8675     {
8676         /* This allow to write PCM data to file and to encode AMR data,
8677          when output file is not RAW */
8678         if( pC->pOutputPCMfile != M4OSA_NULL )
8679         {
8680             pC->pOsaFileWritPtr->writeData(pC->pOutputPCMfile,
8681                 pEncInBuffer.pTableBuffer[0], pEncInBuffer.pTableBufferSize[0]);
8682         }
8683 
8684         /**
8685         * Encode the PCM audio */
8686         err = pC->pAudioEncoderGlobalFcts->pFctStep(pC->pAudioEncCtxt,
8687             &pEncInBuffer, &pEncOutBuffer);
8688 
8689         if( M4NO_ERROR != err )
8690         {
8691             M4OSA_TRACE1_1(
8692                 "M4MCS_intAudioTranscoding(): pAudioEncoderGlobalFcts->pFctStep returns 0x%x",
8693                 err);
8694             return err;
8695         }
8696 
8697         /* update data consumed into encoder buffer in after encoding (empty) */
8698         pC->pPosInAudioEncoderBuffer = M4OSA_NULL;
8699 
8700         /**
8701         * Set AU cts and size */
8702         pC->WriterAudioAU.size =
8703             pEncOutBuffer.
8704             pTableBufferSize[0]; /**< Get the size of encoded data */
8705         pC->WriterAudioAU.CTS += frameTimeDelta;
8706 
8707         /**
8708         * Update duration of the encoded AU */
8709         pC->m_audioAUDuration =
8710             ( frameTimeDelta * 1000) / pC->WriterAudioStream.timeScale;
8711 
8712         /**
8713         * Write the encoded AU to the output file */
8714         pC->uiAudioAUCount++;
8715         err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext,
8716             M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
8717 
8718         if( M4NO_ERROR != err )
8719         {
8720             M4OSA_TRACE1_1(
8721                 "M4MCS_intAudioTranscoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x",
8722                 err);
8723             return err;
8724         }
8725     }
8726     else
8727     {
8728         /* update data consumed into encoder buffer in after encoding (empty) */
8729         pC->pPosInAudioEncoderBuffer = M4OSA_NULL;
8730 
8731         pC->WriterAudioAU.dataAddress =
8732             (M4OSA_MemAddr32)
8733             pEncoderInput; /* will be converted back to u8* in file write */
8734         pC->WriterAudioAU.size = pC->audioEncoderGranularity;
8735         pC->uiAudioAUCount++;
8736 
8737         err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext,
8738             M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
8739 
8740         if( M4NO_ERROR != err )
8741         {
8742             M4OSA_TRACE1_1(
8743                 "M4MCS_intAudioTranscoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x",
8744                 err);
8745             return err;
8746         }
8747     }
8748 
8749     /* _______________ */
8750     /*|               |*/
8751     /*| ONE PASS DONE |*/
8752     /*|_______________|*/
8753 
8754 m4mcs_intaudiotranscoding_end:
8755 
8756     /**
8757     * Return with no error */
8758     M4OSA_TRACE3_0("M4MCS_intAudioTranscoding(): returning M4NO_ERROR");
8759     return M4NO_ERROR;
8760 }
8761 
8762 /**
8763  ******************************************************************************
8764  * M4OSA_ERR M4MCS_intReallocTemporaryAU(M4OSA_MemAddr8* addr, M4OSA_UInt32 newSize)
8765  * Used only in case of 3GP constant memory reader, to be able to realloc temporary AU
8766  * because max AU size can be reevaluated during reading
8767  * @return   M4NO_ERROR:         No error
8768  ******************************************************************************
8769  */
M4MCS_intReallocTemporaryAU(M4OSA_MemAddr8 * addr,M4OSA_UInt32 newSize)8770 static M4OSA_ERR M4MCS_intReallocTemporaryAU( M4OSA_MemAddr8 *addr,
8771                                              M4OSA_UInt32 newSize )
8772 {
8773     if( *addr != M4OSA_NULL )
8774     {
8775         free(*addr);
8776         *addr = (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(newSize, M4MCS,
8777             (M4OSA_Char *)"Reallocation of temporary AU buffer");
8778 
8779         if( *addr == M4OSA_NULL )
8780         {
8781             return M4ERR_ALLOC;
8782         }
8783     }
8784 
8785     return M4NO_ERROR;
8786 }
8787 
8788 /**
8789  ******************************************************************************
8790  * M4OSA_ERR M4MCS_intVideoNullEncoding(M4MCS_InternalContext* pC)
8791  * @author   Alexis Vapillon (NXP Software Vision)
8792  * @return   M4NO_ERROR:         No error
8793  ******************************************************************************
8794  */
M4MCS_intVideoNullEncoding(M4MCS_InternalContext * pC)8795 static M4OSA_ERR M4MCS_intVideoNullEncoding( M4MCS_InternalContext *pC )
8796 {
8797     M4OSA_ERR err = M4NO_ERROR;
8798     /* Duration of the AU (find the next AU duration
8799      * to obtain a more precise video end cut)
8800      */
8801     M4OSA_UInt32 videoAUDuration = 0;
8802 
8803     M4OSA_MemAddr8 WritebufferAdd = M4OSA_NULL;
8804     M4OSA_Int32 lastdecodedCTS = 0;
8805     M4_AccessUnit lReaderVideoAU; /**< Read video access unit */
8806 
8807     if( pC->novideo )
8808         return M4NO_ERROR;
8809 
8810     /* H.264 Trimming */
8811     if( ( ( pC->bH264Trim == M4OSA_TRUE)
8812         && (pC->uiVideoAUCount < pC->m_pInstance->clip_sps.num_ref_frames)
8813         && (pC->uiBeginCutTime > 0))
8814         || (( pC->uiVideoAUCount == 0) && (pC->uiBeginCutTime > 0)) )
8815     {
8816         err = M4MCS_intVideoTranscoding(pC);
8817         return err;
8818     }
8819 
8820 
8821     if((pC->bLastDecodedFrameCTS == M4OSA_FALSE) && (pC->uiBeginCutTime > 0))
8822     {
8823         // StageFright encoder does prefetch, the one frame we requested will not be written until
8824         // the encoder is closed, so do it now rather than in MCS_close
8825         if( ( M4NO_ERROR != err)
8826             || (M4MCS_kEncoderRunning != pC->encoderState) )
8827         {
8828             M4OSA_TRACE1_2(
8829                 "!!! M4MCS_intVideoNullEncoding ERROR : M4MCS_intVideoTranscoding "
8830                 "returns 0x%X w/ encState=%d", err, pC->encoderState);
8831 
8832             return err;
8833         }
8834 
8835         /* Stop and close the encoder now to flush the frame (prefetch) */
8836         if( pC->pVideoEncoderGlobalFcts->pFctStop != M4OSA_NULL )
8837         {
8838             err = pC->pVideoEncoderGlobalFcts->pFctStop(pC->pViEncCtxt);
8839 
8840             if( M4NO_ERROR != err )
8841             {
8842                 M4OSA_TRACE1_1(
8843                     "!!! M4MCS_intVideoNullEncoding ERROR : encoder stop returns 0x%X",
8844                     err);
8845                 return err;
8846             }
8847         }
8848         pC->encoderState = M4MCS_kEncoderStopped;
8849         err = pC->pVideoEncoderGlobalFcts->pFctClose(pC->pViEncCtxt);
8850 
8851         if( M4NO_ERROR != err )
8852         {
8853             M4OSA_TRACE1_1(
8854                 "!!! M4MCS_intVideoNullEncoding ERROR : encoder close returns 0x%X",
8855                 err);
8856             return err;
8857         }
8858         pC->encoderState = M4MCS_kEncoderClosed;
8859     }
8860 
8861 
8862     if ((pC->EncodingVideoFormat == M4ENCODER_kNULL)
8863         && (pC->bLastDecodedFrameCTS == M4OSA_FALSE)
8864         && (pC->uiBeginCutTime > 0)) {
8865 
8866         pC->bLastDecodedFrameCTS = M4OSA_TRUE;
8867         err = pC->m_pVideoDecoder->m_pFctGetOption(pC->pViDecCtxt,
8868             M4DECODER_kOptionID_AVCLastDecodedFrameCTS, &lastdecodedCTS);
8869 
8870         if (M4NO_ERROR != err) {
8871             M4OSA_TRACE1_1(
8872                 "M4MCS_intVideoNullEncoding: m_pVideoDecoder->m_pFctGetOption returns 0x%x!",
8873                 err);
8874             return err;
8875         }
8876         /* Do not need video decoder any more, need to destroy it. Otherwise it
8877          * will call reader function which will cause frame lost during triming,
8878          * since the 3gp reader is shared between MCS and decoder.*/
8879         if (M4OSA_NULL != pC->pViDecCtxt) {
8880             err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt);
8881             pC->pViDecCtxt = M4OSA_NULL;
8882 
8883             if (M4NO_ERROR != err) {
8884                 M4OSA_TRACE1_1(
8885                     "M4MCS_intVideoNullEncoding: decoder pFctDestroy returns 0x%x",
8886                     err);
8887                 return err;
8888             }
8889         }
8890 
8891         err = pC->m_pReader->m_pFctJump(pC->pReaderContext,
8892             (M4_StreamHandler *)pC->pReaderVideoStream, &lastdecodedCTS);
8893 
8894         if (M4NO_ERROR != err) {
8895             M4OSA_TRACE1_1(
8896                 "M4MCS_intVideoNullEncoding: m_pFctJump(V) returns 0x%x!",
8897                 err);
8898             return err;
8899         }
8900 
8901 
8902         /* Initializes an access Unit */
8903 
8904         err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
8905             (M4_StreamHandler *)pC->pReaderVideoStream, &lReaderVideoAU);
8906 
8907         if (M4NO_ERROR != err) {
8908             M4OSA_TRACE1_1(
8909                 "M4MCS_intVideoNullEncoding:m_pReader->m_pFctFillAuStruct(video)\
8910                 returns 0x%x", err);
8911             return err;
8912         }
8913 
8914         err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
8915             (M4_StreamHandler *)pC->pReaderVideoStream, &lReaderVideoAU);
8916 
8917         if (M4WAR_NO_MORE_AU == err) {
8918             M4OSA_TRACE2_0(
8919                 "M4MCS_intVideoNullEncoding():\
8920                  m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU");
8921             /* The audio transcoding is finished */
8922             pC->VideoState = M4MCS_kStreamState_FINISHED;
8923             return err;
8924         }
8925         else if (M4NO_ERROR != err) {
8926             M4OSA_TRACE1_1(
8927                 "M4MCS_intVideoNullEncoding():\
8928                  m_pReaderDataIt->m_pFctGetNextAu(video) returns 0x%x",
8929                 err);
8930             return err;
8931         }
8932 
8933         M4OSA_TRACE1_1(
8934             "### [TS_CHECK] M4MCS_intVideoNullEncoding  video AU CTS: %d ",
8935             lReaderVideoAU.m_CTS);
8936 
8937 
8938     }
8939 
8940 
8941     pC->bLastDecodedFrameCTS = M4OSA_TRUE;
8942 
8943 
8944     /* Find the next AU duration to obtain a more precise video end cut*/
8945     /**
8946     * Initializes a new AU if needed */
8947 
8948     if (pC->ReaderVideoAU1.m_structSize == 0) {
8949         /**
8950         * Initializes an access Unit */
8951         err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
8952             (M4_StreamHandler *)pC->pReaderVideoStream,
8953             &pC->ReaderVideoAU1);
8954 
8955         if (M4NO_ERROR != err) {
8956             M4OSA_TRACE1_1(
8957                 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
8958                 err);
8959             return err;
8960         }
8961 
8962         pC->m_pDataVideoAddress1 =
8963             (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderVideoAU1.m_maxsize, M4MCS,
8964             (M4OSA_Char *)"Temporary video AU1 buffer");
8965 
8966         if (pC->m_pDataVideoAddress1 == M4OSA_NULL) {
8967             M4OSA_TRACE1_0("M4MCS_intVideoNullEncoding(): allocation error");
8968             return M4ERR_ALLOC;
8969         }
8970 
8971         err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
8972             (M4_StreamHandler *)pC->pReaderVideoStream,
8973             &pC->ReaderVideoAU1);
8974 
8975         if( M4WAR_NO_MORE_AU == err )
8976         {
8977             M4OSA_TRACE2_0(
8978                 "M4MCS_intVideoNullEncoding():\
8979                  m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU");
8980             /* The audio transcoding is finished */
8981             pC->VideoState = M4MCS_kStreamState_FINISHED;
8982             return err;
8983         }
8984         else if( M4NO_ERROR != err )
8985         {
8986             M4OSA_TRACE1_1(
8987                 "M4MCS_intVideoNullEncoding(): m_pReaderDataIt->m_pFctGetNextAu(video)\
8988                  returns 0x%x", err);
8989             return err;
8990         }
8991 
8992         if( pC->ReaderVideoAU1.m_maxsize
8993             > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize )
8994         {
8995             /* Constant memory reader case, we need to reallocate the temporary buffers */
8996             M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
8997                 *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU1.m_maxsize);
8998             /* pC->m_pDataVideoAddress1
8999             and pC->m_pDataVideoAddress2 must be reallocated at the same time */
9000             /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value.
9001              Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream->
9002              m_basicProperties.m_maxAUSize)" is never true */
9003             /* and the size of the second buffer is never changed. */
9004             M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
9005                 *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU1.m_maxsize);
9006             /* pC->m_pDataVideoAddress1 and
9007             pC->m_pDataVideoAddress2 must be reallocated at the same time */
9008             /* Update stream properties */
9009             pC->pReaderVideoStream->m_basicProperties.m_maxAUSize =
9010                 pC->ReaderVideoAU1.m_maxsize;
9011         }
9012         memcpy((void *)pC->m_pDataVideoAddress1,
9013             (void *)pC->ReaderVideoAU1.m_dataAddress,
9014             pC->ReaderVideoAU1.m_size);
9015     }
9016 
9017     if( pC->ReaderVideoAU2.m_structSize == 0 )
9018     {
9019         /**
9020         * Initializes an access Unit */
9021         err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
9022             (M4_StreamHandler *)pC->pReaderVideoStream,
9023             &pC->ReaderVideoAU2);
9024 
9025         if( M4NO_ERROR != err )
9026         {
9027             M4OSA_TRACE1_1(
9028                 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
9029                 err);
9030             return err;
9031         }
9032         pC->m_pDataVideoAddress2 =
9033             (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderVideoAU2.m_maxsize, M4MCS,
9034             (M4OSA_Char *)"Temporary video AU buffer");
9035 
9036         if( pC->m_pDataVideoAddress2 == M4OSA_NULL )
9037         {
9038             M4OSA_TRACE1_0("M4MCS_intVideoNullEncoding(): allocation error");
9039             return M4ERR_ALLOC;
9040         }
9041     }
9042     /**
9043     * Read the next video AU in the input file */
9044     if( pC->ReaderVideoAU2.m_CTS > pC->ReaderVideoAU1.m_CTS )
9045     {
9046         memcpy((void *) &pC->ReaderVideoAU,
9047             (void *) &pC->ReaderVideoAU2, sizeof(M4_AccessUnit));
9048         err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
9049             (M4_StreamHandler *)pC->pReaderVideoStream,
9050             &pC->ReaderVideoAU1);
9051 
9052         if( pC->ReaderVideoAU1.m_maxsize
9053             > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize )
9054         {
9055             /* Constant memory reader case, we need to reallocate the temporary buffers */
9056             M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
9057                 *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU1.m_maxsize);
9058             /* pC->m_pDataVideoAddress1 and
9059              pC->m_pDataVideoAddress2 must be reallocated at the same time */
9060             /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value.
9061              Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream->
9062              m_basicProperties.m_maxAUSize)" is never true */
9063             /* and the size of the second buffer is never changed. */
9064             M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
9065                 *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU1.m_maxsize);
9066             /* pC->m_pDataVideoAddress1 and
9067             pC->m_pDataVideoAddress2 must be reallocated at the same time */
9068             /* Update stream properties */
9069             pC->pReaderVideoStream->m_basicProperties.m_maxAUSize =
9070                 pC->ReaderVideoAU1.m_maxsize;
9071         }
9072         memcpy((void *)pC->m_pDataVideoAddress1,
9073             (void *)pC->ReaderVideoAU1.m_dataAddress,
9074             pC->ReaderVideoAU1.m_size);
9075         videoAUDuration = pC->ReaderVideoAU1.m_CTS - pC->ReaderVideoAU2.m_CTS;
9076         pC->ReaderVideoAU.m_dataAddress = pC->m_pDataVideoAddress2;
9077     }
9078     else
9079     {
9080         memcpy((void *) &pC->ReaderVideoAU,
9081             (void *) &pC->ReaderVideoAU1, sizeof(M4_AccessUnit));
9082         err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
9083             (M4_StreamHandler *)pC->pReaderVideoStream,
9084             &pC->ReaderVideoAU2);
9085 
9086         if( pC->ReaderVideoAU2.m_maxsize
9087             > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize )
9088         {
9089             /* Constant memory reader case, we need to reallocate the temporary buffers */
9090             M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
9091                 *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU2.m_maxsize);
9092             /* pC->m_pDataVideoAddress1 and
9093              pC->m_pDataVideoAddress2 must be reallocated at the same time */
9094             /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value.
9095              Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream->
9096              m_basicProperties.m_maxAUSize)" is never true */
9097             /* and the size of the second buffer is never changed. */
9098             M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
9099                 *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU2.m_maxsize);
9100             /* pC->m_pDataVideoAddress1 and
9101             pC->m_pDataVideoAddress2 must be reallocated at the same time */
9102             /* Update stream properties */
9103             pC->pReaderVideoStream->m_basicProperties.m_maxAUSize =
9104                 pC->ReaderVideoAU2.m_maxsize;
9105         }
9106         memcpy((void *)pC->m_pDataVideoAddress2,
9107             (void *)pC->ReaderVideoAU2.m_dataAddress,
9108             pC->ReaderVideoAU2.m_size);
9109         videoAUDuration = pC->ReaderVideoAU2.m_CTS - pC->ReaderVideoAU1.m_CTS;
9110         pC->ReaderVideoAU.m_dataAddress = pC->m_pDataVideoAddress1;
9111     }
9112 
9113     if( M4WAR_NO_MORE_AU == err )
9114     {
9115         M4OSA_TRACE2_0(
9116             "M4MCS_intVideoNullEncoding():\
9117              m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU");
9118         /* The video transcoding is finished */
9119         pC->VideoState = M4MCS_kStreamState_FINISHED;
9120         return err;
9121     }
9122     else if( M4NO_ERROR != err )
9123     {
9124         M4OSA_TRACE1_1(
9125             "M4MCS_intVideoNullEncoding(): m_pReaderDataIt->m_pFctGetNextAu(Video) returns 0x%x",
9126             err);
9127         return err;
9128     }
9129     else
9130     {
9131         /**
9132         * Prepare the writer AU */
9133         err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext,
9134             M4MCS_WRITER_VIDEO_STREAM_ID, &pC->WriterVideoAU);
9135 
9136         if( M4NO_ERROR != err )
9137         {
9138             M4OSA_TRACE1_1(
9139                 "M4MCS_intVideoNullEncoding(): pWriterDataFcts->pStartAU(Video) returns 0x%x",
9140                 err);
9141             return err;
9142         }
9143             /**
9144             * Copy video data from reader AU to writer AU */
9145             M4OSA_TRACE3_1(
9146                 "M4MCS_intVideoNullEncoding(): Copying video AU: size=%d",
9147                 pC->ReaderVideoAU.m_size);
9148             /* + CRLV6775 -H.264 Trimming */
9149             if( M4OSA_TRUE == pC->bH264Trim )
9150             {
9151                 if( pC->H264MCSTempBufferSize
9152                     < (pC->ReaderVideoAU.m_size + 2048) )
9153                 {
9154                     pC->H264MCSTempBufferSize =
9155                         (pC->ReaderVideoAU.m_size + 2048);
9156 
9157                     if( pC->H264MCSTempBuffer != M4OSA_NULL )
9158                     {
9159                         free(pC->H264MCSTempBuffer);
9160                     }
9161                     pC->H264MCSTempBuffer =
9162                         (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(pC->H264MCSTempBufferSize,
9163                         M4MCS, (M4OSA_Char *)"pC->H264MCSTempBuffer");
9164 
9165                     if( pC->H264MCSTempBuffer == M4OSA_NULL )
9166                     {
9167                         M4OSA_TRACE1_0(
9168                             "M4MCS_intVideoNullEncoding(): allocation error");
9169                         return M4ERR_ALLOC;
9170                     }
9171                 }
9172 
9173                 pC->H264MCSTempBufferDataSize = pC->H264MCSTempBufferSize;
9174 
9175                 err = H264MCS_ProcessNALU(pC->m_pInstance,
9176                     (M4OSA_UInt8 *)pC->ReaderVideoAU.m_dataAddress,
9177                     pC->ReaderVideoAU.m_size, pC->H264MCSTempBuffer,
9178                     (M4OSA_Int32 *)&pC->H264MCSTempBufferDataSize);
9179 
9180                 if( pC->m_pInstance->is_done == 1 )
9181                 {
9182                     M4MCS_convetFromByteStreamtoNALStream(
9183                         (M4OSA_UInt8 *)pC->ReaderVideoAU.m_dataAddress ,
9184                         pC->ReaderVideoAU.m_size);
9185 
9186                     memcpy((void *)pC->WriterVideoAU.dataAddress,
9187                         (void *)(pC->ReaderVideoAU.m_dataAddress + 4),
9188                         pC->ReaderVideoAU.m_size - 4);
9189                     pC->WriterVideoAU.size = pC->ReaderVideoAU.m_size - 4;
9190                     WritebufferAdd =
9191                         (M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress;
9192                 }
9193                 else
9194                 {
9195                     memcpy((void *)pC->WriterVideoAU.dataAddress,
9196                         (void *)(pC->H264MCSTempBuffer + 4),
9197                         pC->H264MCSTempBufferDataSize - 4);
9198                     pC->WriterVideoAU.size = pC->H264MCSTempBufferDataSize - 4;
9199                     WritebufferAdd =
9200                         (M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress;
9201                 }
9202             }
9203             /* H.264 Trimming */
9204             else
9205             {
9206                 memcpy((void *)pC->WriterVideoAU.dataAddress,
9207                     (void *)pC->ReaderVideoAU.m_dataAddress,
9208                     pC->ReaderVideoAU.m_size);
9209                 pC->WriterVideoAU.size = pC->ReaderVideoAU.m_size;
9210             }
9211             /**
9212             * Convert CTS unit from milliseconds to timescale */
9213             pC->WriterVideoAU.CTS =
9214                 (M4OSA_Time)((( pC->ReaderVideoAU.m_CTS - pC->dViDecStartingCts)
9215                 * (pC->WriterVideoStream.timeScale / 1000.0)));
9216             pC->WriterVideoAU.nbFrag = 0;
9217             pC->WriterVideoAU.attribute = pC->ReaderVideoAU.m_attribute;
9218 
9219             M4OSA_TRACE3_1("M4MCS_intVideoNullEncoding(): video AU: CTS=%d ms",
9220                 pC->WriterVideoAU.CTS);
9221 
9222         /**
9223         * Write it to the output file */
9224         pC->uiVideoAUCount++;
9225         err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext,
9226             M4MCS_WRITER_VIDEO_STREAM_ID, &pC->WriterVideoAU);
9227 
9228         if( M4NO_ERROR != err )
9229         {
9230             M4OSA_TRACE1_1(
9231                 "M4MCS_intVideoNullEncoding(): pWriterDataFcts->pProcessAU(Video) returns 0x%x",
9232                 err);
9233             return err;
9234         }
9235         /* + CRLV6775 -H.264 Trimming */
9236         if( M4OSA_TRUE == pC->bH264Trim )
9237         {
9238             if( pC->m_pInstance->is_done == 1 )
9239             {
9240                 memcpy((void *)(WritebufferAdd - 4),
9241                     (void *)(pC->ReaderVideoAU.m_dataAddress), 4);
9242             }
9243             else
9244             {
9245                 memcpy((void *)(WritebufferAdd - 4),
9246                     (void *)(pC->H264MCSTempBuffer), 4);
9247             }
9248         } /* H.264 Trimming */
9249     }
9250     /**
9251     * Check for end cut. */
9252     /* Bug fix 11/12/2008: We absolutely want to have less or same video duration ->
9253     (2*videoAUDuration) to have a more precise end cut*/
9254     if( pC->ReaderVideoAU.m_CTS + (2 *videoAUDuration) > pC->uiEndCutTime )
9255     {
9256         pC->VideoState = M4MCS_kStreamState_FINISHED;
9257     }
9258 
9259     /**
9260     * Return with no error */
9261     M4OSA_TRACE3_0("M4MCS_intVideoNullEncoding(): returning M4NO_ERROR");
9262     return M4NO_ERROR;
9263 }
9264 
9265 /**
9266  ******************************************************************************
9267  * M4OSA_ERR M4MCS_intVideoTranscoding(M4MCS_InternalContext* pC)
9268  * @author   Alexis Vapillon (NXP Software Vision)
9269  * @return   M4NO_ERROR:         No error
9270  ******************************************************************************
9271  */
M4MCS_intVideoTranscoding(M4MCS_InternalContext * pC)9272 static M4OSA_ERR M4MCS_intVideoTranscoding( M4MCS_InternalContext *pC )
9273 {
9274     M4OSA_ERR err = M4NO_ERROR;
9275     M4_MediaTime mtTranscodedTime = 0.0;
9276     M4ENCODER_FrameMode FrameMode;
9277     M4OSA_Int32 derive = 0;
9278 
9279     /**
9280     * Get video CTS to decode */
9281     mtTranscodedTime = pC->dViDecCurrentCts;
9282     FrameMode = M4ENCODER_kNormalFrame;
9283 
9284     /**
9285     * Decode video */
9286     M4OSA_TRACE3_1(
9287         "M4MCS_intVideoTranscoding(): Calling m_pVideoDecoder->m_pFctDecode(%.2f)",
9288         mtTranscodedTime);
9289     pC->isRenderDup = M4OSA_FALSE;
9290     err = pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &mtTranscodedTime,
9291         M4OSA_FALSE, 0);
9292 
9293     if( M4WAR_NO_MORE_AU == err )
9294     {
9295         FrameMode =
9296             M4ENCODER_kLastFrame; /**< We will give this value to the encoder to
9297             ask for the end of the encoding */
9298         pC->VideoState = M4MCS_kStreamState_FINISHED;
9299     }
9300     else if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME )
9301     {
9302         M4OSA_TRACE2_0("Decoding output the same frame as before 3");
9303         pC->isRenderDup = M4OSA_TRUE;
9304     }
9305     else if( M4NO_ERROR != err )
9306     {
9307         M4OSA_TRACE1_1(
9308             "M4MCS_intVideoTranscoding(): m_pVideoDecoder->m_pFctDecode returns 0x%x!",
9309             err);
9310         return err;
9311     }
9312 
9313     /**
9314     * Check for end cut.
9315     * We must check here if the end cut is reached, because in that case we must
9316     * call the last encode step (-> bLastFrame set to true) */
9317     if( ( pC->dViDecCurrentCts + pC->dCtsIncrement ) >= (pC->uiEndCutTime
9318         + M4MCS_ABS(pC->dViDecStartingCts - pC->uiBeginCutTime)) )
9319     {
9320         FrameMode =
9321             M4ENCODER_kLastFrame; /**< We will give this value to the encoder to
9322             ask for the end of the encoding */
9323         pC->VideoState = M4MCS_kStreamState_FINISHED;
9324         derive = (M4OSA_Int32)(( pC->dViDecCurrentCts + pC->dCtsIncrement + 0.5)
9325             - (pC->uiEndCutTime
9326             + M4MCS_ABS(pC->dViDecStartingCts - pC->uiBeginCutTime)));
9327     }
9328 
9329     /* Update starting CTS to have a more precise value (
9330     the begin cut is not a real CTS)*/
9331     if( pC->uiVideoAUCount == 0 )
9332     {
9333         pC->dViDecStartingCts = mtTranscodedTime;
9334         pC->dViDecCurrentCts = pC->dViDecStartingCts;
9335     }
9336 
9337     /**
9338     * Encode video */
9339     M4OSA_TRACE3_1(
9340         "M4MCS_intVideoTranscoding(): Calling pVideoEncoderGlobalFcts->pFctEncode with videoCts\
9341          = %.2f",pC->ReaderVideoAU.m_CTS);
9342     pC->uiVideoAUCount++;
9343     /* update the given duration (the begin cut is not a real CTS)*/
9344     err = pC->pVideoEncoderGlobalFcts->pFctEncode(pC->pViEncCtxt, M4OSA_NULL,
9345         (pC->dViDecCurrentCts - pC->dViDecStartingCts - (derive >> 1)),
9346         FrameMode);
9347 
9348     return err;
9349 }
9350 
9351 /**
9352  ******************************************************************************
9353  * M4OSA_ERR M4MCS_intGetInputClipProperties(M4MCS_InternalContext* pContext)
9354  * @author   Dounya Manai (NXP Software Vision)
9355  * @brief    Retrieve the properties of the audio and video streams from the input file.
9356  * @param    pContext            (IN) MCS context
9357  * @return   M4NO_ERROR:         No error
9358  * @return   M4ERR_PARAMETER:    pContext is M4OSA_NULL (If Debug Level >= 2)
9359  ******************************************************************************
9360  */
M4MCS_intGetInputClipProperties(M4MCS_InternalContext * pC)9361 static M4OSA_ERR M4MCS_intGetInputClipProperties( M4MCS_InternalContext *pC )
9362 {
9363     M4DECODER_MPEG4_DecoderConfigInfo DecConfInfo;
9364     M4READER_3GP_H263Properties H263prop;
9365     M4OSA_ERR err;
9366     M4OSA_UInt32 videoBitrate;
9367     M4DECODER_VideoSize videoSize;
9368     M4_AACType iAacType = 0;
9369 
9370     /**
9371     * Check input parameters */
9372     M4OSA_DEBUG_IF2(M4OSA_NULL == pC, M4ERR_PARAMETER,
9373         "M4MCS_intGetInputClipProperties: pC is M4OSA_NULL");
9374 
9375     /**
9376     * Reset common characteristics */
9377     pC->InputFileProperties.bAnalysed = M4OSA_FALSE;
9378     pC->InputFileProperties.FileType = 0;
9379     pC->InputFileProperties.Version[0] = M4VIDEOEDITING_VERSION_MAJOR;
9380     pC->InputFileProperties.Version[1] = M4VIDEOEDITING_VERSION_MINOR;
9381     pC->InputFileProperties.Version[2] = M4VIDEOEDITING_VERSION_REVISION;
9382     pC->InputFileProperties.uiClipDuration = 0;
9383 
9384     memset((void *) &pC->InputFileProperties.ftyp,
9385         0, sizeof(M4VIDEOEDITING_FtypBox));
9386 
9387     /**
9388     * Reset video characteristics */
9389     pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo;
9390     pC->InputFileProperties.uiClipVideoDuration = 0;
9391     pC->InputFileProperties.uiVideoBitrate = 0;
9392     pC->InputFileProperties.uiVideoMaxAuSize = 0;
9393     pC->InputFileProperties.uiVideoWidth = 0;
9394     pC->InputFileProperties.uiVideoHeight = 0;
9395     pC->InputFileProperties.uiVideoTimeScale = 0;
9396     pC->InputFileProperties.fAverageFrameRate = 0.0;
9397     pC->InputFileProperties.uiVideoLevel =
9398         M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL;
9399     pC->InputFileProperties.uiVideoProfile =
9400         M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE;
9401     pC->InputFileProperties.bMPEG4dataPartition = M4OSA_FALSE;
9402     pC->InputFileProperties.bMPEG4rvlc = M4OSA_FALSE;
9403     pC->InputFileProperties.bMPEG4resynchMarker = M4OSA_FALSE;
9404 
9405     /**
9406     * Reset audio characteristics */
9407     pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio;
9408     pC->InputFileProperties.uiClipAudioDuration = 0;
9409     pC->InputFileProperties.uiAudioBitrate = 0;
9410     pC->InputFileProperties.uiAudioMaxAuSize = 0;
9411     pC->InputFileProperties.uiNbChannels = 0;
9412     pC->InputFileProperties.uiSamplingFrequency = 0;
9413     pC->InputFileProperties.uiExtendedSamplingFrequency = 0;
9414     pC->InputFileProperties.uiDecodedPcmSize = 0;
9415 
9416     /* Reset compatibility chart (not used in MCS) */
9417     pC->InputFileProperties.bVideoIsEditable = M4OSA_FALSE;
9418     pC->InputFileProperties.bAudioIsEditable = M4OSA_FALSE;
9419     pC->InputFileProperties.bVideoIsCompatibleWithMasterClip = M4OSA_FALSE;
9420     pC->InputFileProperties.bAudioIsCompatibleWithMasterClip = M4OSA_FALSE;
9421 
9422     /**
9423     * Video stream properties */
9424     if( M4OSA_NULL != pC->pReaderVideoStream )
9425     {
9426         switch( pC->pReaderVideoStream->m_basicProperties.m_streamType )
9427         {
9428             case M4DA_StreamTypeVideoMpeg4:
9429                 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kMPEG4;
9430                 break;
9431 
9432             case M4DA_StreamTypeVideoH263:
9433                 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kH263;
9434                 break;
9435 
9436             case M4DA_StreamTypeVideoMpeg4Avc:
9437                 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kH264;
9438                 break;
9439 
9440             case M4DA_StreamTypeUnknown:
9441             default:
9442                 pC->InputFileProperties.VideoStreamType =
9443                     M4VIDEOEDITING_kUnsupportedVideo;
9444                 break;
9445         }
9446 
9447         /* if bitrate not available retrieve an estimation of the overall bitrate */
9448         pC->InputFileProperties.uiVideoBitrate =
9449             pC->pReaderVideoStream->m_basicProperties.m_averageBitRate;
9450 
9451         if( 0 == pC->InputFileProperties.uiVideoBitrate )
9452         {
9453             pC->m_pReader->m_pFctGetOption(pC->pReaderContext,
9454                 M4READER_kOptionID_Bitrate, &videoBitrate);
9455 
9456             if( M4OSA_NULL != pC->pReaderAudioStream )
9457             {
9458                 /* we get the overall bitrate, substract the audio bitrate if any */
9459                 videoBitrate -=
9460                     pC->pReaderAudioStream->m_basicProperties.m_averageBitRate;
9461             }
9462             pC->InputFileProperties.uiVideoBitrate = videoBitrate;
9463         }
9464 
9465         /**
9466         * Retrieve the Profile & Level */
9467         if( ( M4VIDEOEDITING_kH263 != pC->InputFileProperties.VideoStreamType)
9468             && (M4VIDEOEDITING_kH264
9469             != pC->InputFileProperties.VideoStreamType) )
9470         {
9471             /* Use the DSI parsing function from the external video shell decoder.
9472             See the comments in M4VSS3GPP_ClipAnalysis.c, it's pretty much the
9473             same issue. */
9474 
9475             err = M4DECODER_EXTERNAL_ParseVideoDSI(pC->pReaderVideoStream->
9476                 m_basicProperties.m_pDecoderSpecificInfo,
9477                 pC->pReaderVideoStream->
9478                 m_basicProperties.m_decoderSpecificInfoSize,
9479                 &DecConfInfo, &videoSize);
9480 
9481             if( M4NO_ERROR != err )
9482             {
9483                 M4OSA_TRACE1_1(
9484                     "M4MCS_intGetInputClipProperties():\
9485                      M4DECODER_EXTERNAL_ParseVideoDSI returns 0x%08X",
9486                     err);
9487                 return err;
9488             }
9489 
9490             pC->pReaderVideoStream->m_videoWidth = videoSize.m_uiWidth;
9491             pC->pReaderVideoStream->m_videoHeight = videoSize.m_uiHeight;
9492             pC->InputFileProperties.uiVideoTimeScale = DecConfInfo.uiTimeScale;
9493             pC->InputFileProperties.bMPEG4dataPartition =
9494                 DecConfInfo.bDataPartition;
9495             pC->InputFileProperties.bMPEG4rvlc = DecConfInfo.bUseOfRVLC;
9496             pC->InputFileProperties.bMPEG4resynchMarker =
9497                 DecConfInfo.uiUseOfResynchMarker;
9498 
9499             err = getMPEG4ProfileAndLevel(DecConfInfo.uiProfile,
9500                         &(pC->InputFileProperties.uiVideoProfile),
9501                         &(pC->InputFileProperties.uiVideoLevel));
9502             if ( M4NO_ERROR != err ) {
9503                 M4OSA_TRACE1_1("M4MCS_intGetInputClipProperties():\
9504                     getMPEG4ProfileAndLevel returns 0x%08X", err);
9505                 return err;
9506             }
9507         }
9508         else if( M4VIDEOEDITING_kH263 ==
9509             pC->InputFileProperties.VideoStreamType ) {
9510 
9511             err = getH263ProfileAndLevel(pC->pReaderVideoStream->
9512                         m_basicProperties.m_pDecoderSpecificInfo,
9513                         pC->pReaderVideoStream->m_basicProperties.m_decoderSpecificInfoSize,
9514                         &(pC->InputFileProperties.uiVideoProfile),
9515                         &(pC->InputFileProperties.uiVideoLevel));
9516             if ( M4NO_ERROR != err ) {
9517                 M4OSA_TRACE1_1("M4MCS_intGetInputClipProperties():\
9518                     getH263ProfileAndLevel returns 0x%08X", err);
9519                 return err;
9520             }
9521             /* For h263 set default timescale : 30000:1001 */
9522             pC->InputFileProperties.uiVideoTimeScale = 30000;
9523         }
9524         else if ( M4VIDEOEDITING_kH264 ==
9525             pC->InputFileProperties.VideoStreamType ) {
9526 
9527             pC->InputFileProperties.uiVideoTimeScale = 30000;
9528             err = getAVCProfileAndLevel(pC->pReaderVideoStream->
9529                         m_basicProperties.m_pDecoderSpecificInfo,
9530                         pC->pReaderVideoStream->m_basicProperties.m_decoderSpecificInfoSize,
9531                         &(pC->InputFileProperties.uiVideoProfile),
9532                         &(pC->InputFileProperties.uiVideoLevel));
9533             if ( M4NO_ERROR != err ) {
9534                 M4OSA_TRACE1_1("M4MCS_intGetInputClipProperties():\
9535                     getAVCProfileAndLevel returns 0x%08X", err);
9536                 return err;
9537             }
9538         }
9539 
9540         /* Here because width x height is correct only after dsi parsing
9541         (done in create decoder) */
9542         pC->InputFileProperties.uiVideoHeight =
9543             pC->pReaderVideoStream->m_videoHeight;
9544         pC->InputFileProperties.uiVideoWidth =
9545             pC->pReaderVideoStream->m_videoWidth;
9546         pC->InputFileProperties.uiClipVideoDuration =
9547             (M4OSA_UInt32)pC->pReaderVideoStream->m_basicProperties.m_duration;
9548         pC->InputFileProperties.fAverageFrameRate =
9549             pC->pReaderVideoStream->m_averageFrameRate;
9550         pC->InputFileProperties.uiVideoMaxAuSize =
9551             pC->pReaderVideoStream->m_basicProperties.m_maxAUSize;
9552         pC->InputFileProperties.videoRotationDegrees =
9553             pC->pReaderVideoStream->videoRotationDegrees;
9554     }
9555     else
9556     {
9557         if( M4OSA_TRUE == pC->bUnsupportedVideoFound )
9558         {
9559             pC->InputFileProperties.VideoStreamType =
9560                 M4VIDEOEDITING_kUnsupportedVideo;
9561         }
9562         else
9563         {
9564             pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo;
9565         }
9566     }
9567 
9568     /**
9569     * Audio stream properties */
9570     if( M4OSA_NULL != pC->pReaderAudioStream )
9571     {
9572         switch( pC->pReaderAudioStream->m_basicProperties.m_streamType )
9573         {
9574             case M4DA_StreamTypeAudioAmrNarrowBand:
9575                 pC->InputFileProperties.AudioStreamType =
9576                     M4VIDEOEDITING_kAMR_NB;
9577                 break;
9578 
9579             case M4DA_StreamTypeAudioAac:
9580                 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kAAC;
9581                 break;
9582 
9583             case M4DA_StreamTypeAudioMp3:
9584                 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kMP3;
9585                 break;
9586 
9587             case M4DA_StreamTypeAudioEvrc:
9588                 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kEVRC;
9589                 break;
9590 
9591             case M4DA_StreamTypeUnknown:
9592             default:
9593                 pC->InputFileProperties.AudioStreamType =
9594                     M4VIDEOEDITING_kUnsupportedAudio;
9595                 break;
9596         }
9597 
9598         if( ( M4OSA_NULL != pC->m_pAudioDecoder)
9599             && (M4OSA_NULL == pC->pAudioDecCtxt) )
9600         {
9601             M4OSA_TRACE3_1(
9602                 "M4MCS_intGetInputClipProperties: calling CreateAudioDecoder, userData= 0x%x",
9603                 pC->m_pCurrentAudioDecoderUserData);
9604 
9605             if( M4OSA_FALSE == pC->bExtOMXAudDecoder ) {
9606                 err = M4MCS_intCheckAndGetCodecProperties(pC);
9607             }
9608             else
9609             {
9610                 err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(
9611                     &pC->pAudioDecCtxt, pC->pReaderAudioStream,
9612                     pC->m_pCurrentAudioDecoderUserData);
9613 
9614                 if( M4NO_ERROR == err )
9615                 {
9616                     /* AAC properties*/
9617                     //get from Reader; temporary, till Audio decoder shell API available to
9618                     //get the AAC properties
9619                     pC->AacProperties.aNumChan =
9620                         pC->pReaderAudioStream->m_nbChannels;
9621                     pC->AacProperties.aSampFreq =
9622                         pC->pReaderAudioStream->m_samplingFrequency;
9623 
9624                     err = pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(
9625                         pC->pAudioDecCtxt, M4AD_kOptionID_StreamType,
9626                         (M4OSA_DataOption) &iAacType);
9627 
9628                     if( M4NO_ERROR != err )
9629                     {
9630                         M4OSA_TRACE1_1(
9631                             "M4MCS_intGetInputClipProperties:\
9632                              m_pAudioDecoder->m_pFctGetOptionAudioDec returns err 0x%x",
9633                             err);
9634                         iAacType = M4_kAAC; //set to default
9635                         err = M4NO_ERROR;
9636                     }
9637                     else
9638                     {
9639                         M4OSA_TRACE3_1(
9640                             "M4MCS_intGetInputClipProperties:\
9641                              m_pAudioDecoder->m_pFctGetOptionAudioDec returns streamType %d",
9642                             iAacType);
9643                     }
9644 
9645                     switch( iAacType )
9646                     {
9647                         case M4_kAAC:
9648                             pC->AacProperties.aSBRPresent = 0;
9649                             pC->AacProperties.aPSPresent = 0;
9650                             break;
9651 
9652                         case M4_kAACplus:
9653                             pC->AacProperties.aSBRPresent = 1;
9654                             pC->AacProperties.aPSPresent = 0;
9655                             pC->AacProperties.aExtensionSampFreq =
9656                                 pC->pReaderAudioStream->
9657                                 m_samplingFrequency; //TODO
9658                             break;
9659 
9660                         case M4_keAACplus:
9661                             pC->AacProperties.aSBRPresent = 1;
9662                             pC->AacProperties.aPSPresent = 1;
9663                             pC->AacProperties.aExtensionSampFreq =
9664                                 pC->pReaderAudioStream->
9665                                 m_samplingFrequency; //TODO
9666                             break;
9667                           case M4_kUnknown:
9668                           break;
9669                           default:
9670                           break;
9671                         }
9672                         M4OSA_TRACE3_2(
9673                             "M4MCS_intGetInputClipProperties: AAC NBChans=%d, SamplFreq=%d",
9674                             pC->AacProperties.aNumChan,
9675                             pC->AacProperties.aSampFreq);
9676                 }
9677             }
9678 
9679             if( M4NO_ERROR != err )
9680             {
9681                 M4OSA_TRACE1_1(
9682                     "M4MCS_intGetInputClipProperties:\
9683                      m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x",
9684                     err);
9685                 return err;
9686             }
9687         }
9688 
9689         //EVRC
9690         if( pC->pReaderAudioStream->m_basicProperties.m_streamType
9691             == M4DA_StreamTypeAudioEvrc )
9692         {
9693             /* decoder not implemented yet, provide some default values for the null encoding */
9694             pC->pReaderAudioStream->m_nbChannels = 1;
9695             pC->pReaderAudioStream->m_samplingFrequency = 8000;
9696         }
9697 
9698         /**
9699         * Bugfix P4ME00001128: With some IMTC files, the AMR bit rate is 0 kbps according
9700          the GetProperties function */
9701         if( 0 == pC->pReaderAudioStream->m_basicProperties.m_averageBitRate )
9702         {
9703             if( M4VIDEOEDITING_kAMR_NB
9704                 == pC->InputFileProperties.AudioStreamType )
9705             {
9706                 /**
9707                 * Better returning a guessed 12.2 kbps value than a sure-to-be-false
9708                 0 kbps value! */
9709                 pC->InputFileProperties.uiAudioBitrate =
9710                     M4VIDEOEDITING_k12_2_KBPS;
9711             }
9712             else if( M4VIDEOEDITING_kEVRC
9713                 == pC->InputFileProperties.AudioStreamType )
9714             {
9715                 /**
9716                 * Better returning a guessed 8.5 kbps value than a sure-to-be-false
9717                 0 kbps value! */
9718                 pC->InputFileProperties.uiAudioBitrate =
9719                     M4VIDEOEDITING_k9_2_KBPS;
9720             }
9721             else
9722             {
9723                 M4OSA_UInt32 FileBitrate;
9724 
9725                 /* Can happen also for aac, in this case we calculate an approximative */
9726                 /* value from global bitrate and video bitrate */
9727                 err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext,
9728                     M4READER_kOptionID_Bitrate,
9729                     (M4OSA_DataOption) &FileBitrate);
9730 
9731                 if( M4NO_ERROR != err )
9732                 {
9733                     M4OSA_TRACE1_1(
9734                         "M4MCS_intGetInputClipProperties: M4READER_kOptionID_Bitrate returns 0x%x",
9735                         err);
9736                     return err;
9737                 }
9738                 pC->InputFileProperties.uiAudioBitrate =
9739                     FileBitrate
9740                     - pC->
9741                     InputFileProperties.
9742                     uiVideoBitrate /* normally setted to 0, if no video */;
9743             }
9744         }
9745         else
9746         {
9747             pC->InputFileProperties.uiAudioBitrate =
9748                 pC->pReaderAudioStream->m_basicProperties.m_averageBitRate;
9749         }
9750 
9751         pC->InputFileProperties.uiNbChannels =
9752             pC->pReaderAudioStream->m_nbChannels;
9753         pC->InputFileProperties.uiSamplingFrequency =
9754             pC->pReaderAudioStream->m_samplingFrequency;
9755         pC->InputFileProperties.uiClipAudioDuration =
9756             (M4OSA_UInt32)pC->pReaderAudioStream->m_basicProperties.m_duration;
9757         pC->InputFileProperties.uiAudioMaxAuSize =
9758             pC->pReaderAudioStream->m_basicProperties.m_maxAUSize;
9759 
9760         /* Bug: with aac, value is 0 until decoder start() is called */
9761         pC->InputFileProperties.uiDecodedPcmSize =
9762             pC->pReaderAudioStream->m_byteFrameLength
9763             * pC->pReaderAudioStream->m_byteSampleSize
9764             * pC->pReaderAudioStream->m_nbChannels;
9765 
9766         /* New aac properties */
9767         if( M4DA_StreamTypeAudioAac
9768             == pC->pReaderAudioStream->m_basicProperties.m_streamType )
9769         {
9770             pC->InputFileProperties.uiNbChannels = pC->AacProperties.aNumChan;
9771             pC->InputFileProperties.uiSamplingFrequency =
9772                 pC->AacProperties.aSampFreq;
9773 
9774             if( pC->AacProperties.aSBRPresent )
9775             {
9776                 pC->InputFileProperties.AudioStreamType =
9777                     M4VIDEOEDITING_kAACplus;
9778                 pC->InputFileProperties.uiExtendedSamplingFrequency =
9779                     pC->AacProperties.aExtensionSampFreq;
9780             }
9781 
9782             if( pC->AacProperties.aPSPresent )
9783             {
9784                 pC->InputFileProperties.AudioStreamType =
9785                     M4VIDEOEDITING_keAACplus;
9786             }
9787         }
9788     }
9789     else
9790     {
9791         if( M4OSA_TRUE == pC->bUnsupportedAudioFound )
9792         {
9793             pC->InputFileProperties.AudioStreamType =
9794                 M4VIDEOEDITING_kUnsupportedAudio;
9795         }
9796         else
9797         {
9798             pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio;
9799         }
9800     }
9801 
9802     /* Get 'ftyp' atom */
9803     err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext,
9804         M4READER_kOptionID_3gpFtypBox, &pC->InputFileProperties.ftyp);
9805 
9806     /* Analysis is successful */
9807     if( pC->InputFileProperties.uiClipVideoDuration
9808         > pC->InputFileProperties.uiClipAudioDuration )
9809         pC->InputFileProperties.uiClipDuration =
9810         pC->InputFileProperties.uiClipVideoDuration;
9811     else
9812         pC->InputFileProperties.uiClipDuration =
9813         pC->InputFileProperties.uiClipAudioDuration;
9814 
9815     pC->InputFileProperties.FileType = pC->InputFileType;
9816     pC->InputFileProperties.bAnalysed = M4OSA_TRUE;
9817 
9818     return M4NO_ERROR;
9819 }
9820 
9821 /**
9822  ******************************************************************************
9823  * M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB(M4OSA_MemAddr8 pAudioFrame)
9824  * @brief   Return the length, in bytes, of the AMR Narrow-Band frame contained in the given buffer
9825  * @note
9826  * @param   pCpAudioFrame   (IN) AMRNB frame
9827  * @return  M4NO_ERROR: No error
9828  ******************************************************************************
9829  */
M4MCS_intGetFrameSize_AMRNB(M4OSA_MemAddr8 pAudioFrame)9830 static M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB( M4OSA_MemAddr8 pAudioFrame )
9831 {
9832     M4OSA_UInt32 frameSize = 0;
9833     M4OSA_UInt32 frameType = ( ( *pAudioFrame) &(0xF << 3)) >> 3;
9834 
9835     switch( frameType )
9836     {
9837         case 0:
9838             frameSize = 95;
9839             break; /*  4750 bps */
9840 
9841         case 1:
9842             frameSize = 103;
9843             break; /*  5150 bps */
9844 
9845         case 2:
9846             frameSize = 118;
9847             break; /*  5900 bps */
9848 
9849         case 3:
9850             frameSize = 134;
9851             break; /*  6700 bps */
9852 
9853         case 4:
9854             frameSize = 148;
9855             break; /*  7400 bps */
9856 
9857         case 5:
9858             frameSize = 159;
9859             break; /*  7950 bps */
9860 
9861         case 6:
9862             frameSize = 204;
9863             break; /* 10200 bps */
9864 
9865         case 7:
9866             frameSize = 244;
9867             break; /* 12000 bps */
9868 
9869         case 8:
9870             frameSize = 39;
9871             break; /* SID (Silence) */
9872 
9873         case 15:
9874             frameSize = 0;
9875             break; /* No data */
9876 
9877         default:
9878             M4OSA_TRACE3_0(
9879                 "M4MCS_intGetFrameSize_AMRNB(): Corrupted AMR frame! returning 0.");
9880             return 0;
9881     }
9882 
9883     return (1 + (( frameSize + 7) / 8));
9884 }
9885 
9886 /**
9887  ******************************************************************************
9888  * M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC(M4OSA_MemAddr8 pAudioFrame)
9889  * @brief   Return the length, in bytes, of the EVRC frame contained in the given buffer
9890  * @note
9891  *     0 1 2 3
9892  *    +-+-+-+-+
9893  *    |fr type|              RFC 3558
9894  *    +-+-+-+-+
9895  *
9896  * Frame Type: 4 bits
9897  *    The frame type indicates the type of the corresponding codec data
9898  *    frame in the RTP packet.
9899  *
9900  * For EVRC and SMV codecs, the frame type values and size of the
9901  * associated codec data frame are described in the table below:
9902  *
9903  * Value   Rate      Total codec data frame size (in octets)
9904  * ---------------------------------------------------------
9905  *   0     Blank      0    (0 bit)
9906  *   1     1/8        2    (16 bits)
9907  *   2     1/4        5    (40 bits; not valid for EVRC)
9908  *   3     1/2       10    (80 bits)
9909  *   4     1         22    (171 bits; 5 padded at end with zeros)
9910  *   5     Erasure    0    (SHOULD NOT be transmitted by sender)
9911  *
9912  * @param   pCpAudioFrame   (IN) EVRC frame
9913  * @return  M4NO_ERROR: No error
9914  ******************************************************************************
9915  */
M4MCS_intGetFrameSize_EVRC(M4OSA_MemAddr8 pAudioFrame)9916 static M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC( M4OSA_MemAddr8 pAudioFrame )
9917 {
9918     M4OSA_UInt32 frameSize = 0;
9919     M4OSA_UInt32 frameType = ( *pAudioFrame) &0x0F;
9920 
9921     switch( frameType )
9922     {
9923         case 0:
9924             frameSize = 0;
9925             break; /*  blank */
9926 
9927         case 1:
9928             frameSize = 16;
9929             break; /*  1/8 */
9930 
9931         case 2:
9932             frameSize = 40;
9933             break; /*  1/4 */
9934 
9935         case 3:
9936             frameSize = 80;
9937             break; /*  1/2 */
9938 
9939         case 4:
9940             frameSize = 171;
9941             break; /*  1 */
9942 
9943         case 5:
9944             frameSize = 0;
9945             break; /*  erasure */
9946 
9947         default:
9948             M4OSA_TRACE3_0(
9949                 "M4MCS_intGetFrameSize_EVRC(): Corrupted EVRC frame! returning 0.");
9950             return 0;
9951     }
9952 
9953     return (1 + (( frameSize + 7) / 8));
9954 }
9955 
9956 /**
9957  ******************************************************************************
9958  * M4OSA_ERR M4MCS_intCheckMaxFileSize(M4MCS_Context pContext)
9959  * @brief    Check if max file size is greater enough to encode a file with the
9960  *           current selected bitrates and duration.
9961  * @param    pContext            (IN) MCS context
9962  * @return   M4NO_ERROR
9963  * @return   M4MCS_ERR_MAXFILESIZE_TOO_SMALL
9964  ******************************************************************************
9965  */
M4MCS_intCheckMaxFileSize(M4MCS_Context pContext)9966 static M4OSA_ERR M4MCS_intCheckMaxFileSize( M4MCS_Context pContext )
9967 {
9968     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
9969 
9970     M4OSA_UInt32 duration;
9971     M4OSA_UInt32 audiobitrate;
9972     M4OSA_UInt32 videobitrate;
9973 
9974     /* free file size : OK */
9975     if( pC->uiMaxFileSize == 0 )
9976         return M4NO_ERROR;
9977 
9978     /* duration */
9979     if( pC->uiEndCutTime == 0 )
9980     {
9981         duration = pC->InputFileProperties.uiClipDuration - pC->uiBeginCutTime;
9982     }
9983     else
9984     {
9985         duration = pC->uiEndCutTime - pC->uiBeginCutTime;
9986     }
9987 
9988     /* audio bitrate */
9989     if( pC->noaudio )
9990     {
9991         audiobitrate = 0;
9992     }
9993     else if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
9994     {
9995         audiobitrate = pC->InputFileProperties.uiAudioBitrate;
9996     }
9997     else if( pC->uiAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate )
9998     {
9999         switch( pC->AudioEncParams.Format )
10000         {
10001             case M4ENCODER_kAMRNB:
10002                 audiobitrate = M4VIDEOEDITING_k12_2_KBPS;
10003                 break;
10004                 //EVRC
10005                 //            case M4ENCODER_kEVRC:
10006                 //                audiobitrate = M4VIDEOEDITING_k9_2_KBPS;
10007                 //                break;
10008 
10009             default: /* AAC and MP3*/
10010                 audiobitrate =
10011                     (pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
10012                     ? M4VIDEOEDITING_k16_KBPS : M4VIDEOEDITING_k32_KBPS;
10013                 break;
10014         }
10015     }
10016     else
10017     {
10018         audiobitrate = pC->uiAudioBitrate;
10019     }
10020 
10021     /* video bitrate */
10022     if( pC->novideo )
10023     {
10024         videobitrate = 0;
10025     }
10026     else if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
10027     {
10028         videobitrate = pC->InputFileProperties.uiVideoBitrate;
10029     }
10030     else if( pC->uiVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate )
10031     {
10032         videobitrate = M4VIDEOEDITING_k16_KBPS;
10033     }
10034     else
10035     {
10036         videobitrate = pC->uiVideoBitrate;
10037     }
10038 
10039     /* max file size */
10040     if( (M4OSA_UInt32)pC->uiMaxFileSize
10041         < (M4OSA_UInt32)(M4MCS_MOOV_OVER_FILESIZE_RATIO
10042         * (audiobitrate + videobitrate) * (duration / 8000.0)) )
10043         return M4MCS_ERR_MAXFILESIZE_TOO_SMALL;
10044     else
10045         return M4NO_ERROR;
10046 }
10047 
10048 /**
10049  ******************************************************************************
10050  * M4VIDEOEDITING_Bitrate M4MCS_intGetNearestBitrate(M4OSA_UInt32 freebitrate, M4OSA_Int8 mode)
10051  * @brief    Returns the closest bitrate value from the enum list of type M4VIDEOEDITING_Bitrate
10052  * @param    freebitrate: unsigned int value
10053  * @param    mode: -1:previous,0:current,1:next
10054  * @return   bitrate value in enum list M4VIDEOEDITING_Bitrate
10055  ******************************************************************************
10056  */
10057 static M4VIDEOEDITING_Bitrate
M4MCS_intGetNearestBitrate(M4OSA_Int32 freebitrate,M4OSA_Int8 mode)10058 M4MCS_intGetNearestBitrate( M4OSA_Int32 freebitrate, M4OSA_Int8 mode )
10059 {
10060     M4OSA_Int32 bitarray [] =
10061     {
10062         0, M4VIDEOEDITING_k16_KBPS, M4VIDEOEDITING_k24_KBPS,
10063         M4VIDEOEDITING_k32_KBPS, M4VIDEOEDITING_k48_KBPS,
10064         M4VIDEOEDITING_k64_KBPS, M4VIDEOEDITING_k96_KBPS,
10065         M4VIDEOEDITING_k128_KBPS, M4VIDEOEDITING_k192_KBPS,
10066         M4VIDEOEDITING_k256_KBPS, M4VIDEOEDITING_k288_KBPS,
10067         M4VIDEOEDITING_k384_KBPS, M4VIDEOEDITING_k512_KBPS,
10068         M4VIDEOEDITING_k800_KBPS, M4VIDEOEDITING_k2_MBPS,
10069         M4VIDEOEDITING_k5_MBPS,
10070         M4VIDEOEDITING_k8_MBPS, /*+ New Encoder bitrates */
10071         M4OSA_INT32_MAX
10072     };
10073 
10074     const M4OSA_UInt32 nbbitrates = 14;
10075     M4OSA_UInt32 i;
10076 
10077     for ( i = 0; freebitrate >= bitarray[i]; i++ );
10078 
10079     switch( mode )
10080     {
10081         case -1: /* previous */
10082             if( i <= 2 )
10083                 return 0;
10084             else
10085                 return bitarray[i - 2];
10086             break;
10087 
10088         case 0: /* current */
10089             if( i <= 1 )
10090                 return 0;
10091             else
10092                 return bitarray[i - 1];
10093             break;
10094 
10095         case 1: /* next */
10096             if( i >= nbbitrates )
10097                 return M4OSA_INT32_MAX;
10098             else
10099                 return bitarray[i];
10100             break;
10101     }
10102 
10103     return 0;
10104 }
10105 
10106 /**
10107  ******************************************************************************
10108  * M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders(M4MCS_InternalContext* pC);
10109  * @brief    Free all resources allocated by M4MCS_open()
10110  * @param    pContext            (IN) MCS context
10111  * @return   M4NO_ERROR:         No error
10112  ******************************************************************************
10113  */
M4MCS_intCleanUp_ReadersDecoders(M4MCS_InternalContext * pC)10114 static M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders( M4MCS_InternalContext *pC )
10115 {
10116     M4OSA_ERR err = M4NO_ERROR;
10117 
10118     M4OSA_TRACE2_1("M4MCS_intCleanUp_ReadersDecoders called with pC=0x%x", pC);
10119 
10120     /**/
10121     /* ----- Free video decoder stuff, if needed ----- */
10122 
10123     if( M4OSA_NULL != pC->pViDecCtxt )
10124     {
10125         err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt);
10126         pC->pViDecCtxt = M4OSA_NULL;
10127 
10128         if( M4NO_ERROR != err )
10129         {
10130             M4OSA_TRACE1_1(
10131                 "M4MCS_cleanUp: m_pVideoDecoder->pFctDestroy returns 0x%x",
10132                 err);
10133             /**< don't return, we still have stuff to free */
10134         }
10135     }
10136 
10137     /* ----- Free the audio decoder stuff ----- */
10138 
10139     if( M4OSA_NULL != pC->pAudioDecCtxt )
10140     {
10141         err = pC->m_pAudioDecoder->m_pFctDestroyAudioDec(pC->pAudioDecCtxt);
10142         pC->pAudioDecCtxt = M4OSA_NULL;
10143 
10144         if( M4NO_ERROR != err )
10145         {
10146             M4OSA_TRACE1_1(
10147                 "M4MCS_cleanUp: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x",
10148                 err);
10149             /**< don't return, we still have stuff to free */
10150         }
10151     }
10152 
10153     if( M4OSA_NULL != pC->AudioDecBufferOut.m_dataAddress )
10154     {
10155         free(pC->AudioDecBufferOut.m_dataAddress);
10156         pC->AudioDecBufferOut.m_dataAddress = M4OSA_NULL;
10157     }
10158 
10159     /* ----- Free reader stuff, if needed ----- */
10160     // We cannot free the reader before decoders because the decoders may read
10161     // from the reader (in another thread) before being stopped.
10162 
10163     if( M4OSA_NULL != pC->
10164         pReaderContext ) /**< may be M4OSA_NULL if M4MCS_open was not called */
10165     {
10166         err = pC->m_pReader->m_pFctClose(pC->pReaderContext);
10167 
10168         if( M4NO_ERROR != err )
10169         {
10170             M4OSA_TRACE1_1("M4MCS_cleanUp: m_pReader->m_pFctClose returns 0x%x",
10171                 err);
10172             /**< don't return, we still have stuff to free */
10173         }
10174 
10175         err = pC->m_pReader->m_pFctDestroy(pC->pReaderContext);
10176         pC->pReaderContext = M4OSA_NULL;
10177 
10178         if( M4NO_ERROR != err )
10179         {
10180             M4OSA_TRACE1_1(
10181                 "M4MCS_cleanUp: m_pReader->m_pFctDestroy returns 0x%x", err);
10182             /**< don't return, we still have stuff to free */
10183         }
10184     }
10185 
10186     if( pC->m_pDataAddress1 != M4OSA_NULL )
10187     {
10188         free(pC->m_pDataAddress1);
10189         pC->m_pDataAddress1 = M4OSA_NULL;
10190     }
10191 
10192     if( pC->m_pDataAddress2 != M4OSA_NULL )
10193     {
10194         free(pC->m_pDataAddress2);
10195         pC->m_pDataAddress2 = M4OSA_NULL;
10196     }
10197     /*Bug fix 11/12/2008 (to obtain more precise video end cut)*/
10198     if( pC->m_pDataVideoAddress1 != M4OSA_NULL )
10199     {
10200         free(pC->m_pDataVideoAddress1);
10201         pC->m_pDataVideoAddress1 = M4OSA_NULL;
10202     }
10203 
10204     if( pC->m_pDataVideoAddress2 != M4OSA_NULL )
10205     {
10206         free(pC->m_pDataVideoAddress2);
10207         pC->m_pDataVideoAddress2 = M4OSA_NULL;
10208     }
10209 
10210     return M4NO_ERROR;
10211 }
10212 
10213 
10214 /**
10215 
10216  ******************************************************************************
10217  * M4OSA_ERR M4MCS_open_normalMode(M4MCS_Context pContext, M4OSA_Void* pFileIn,
10218  *                             M4OSA_Void* pFileOut, M4OSA_Void* pTempFile);
10219  * @brief   Set the MCS input and output files. It is the same as M4MCS_open without
10220  *                                M4MCS_WITH_FAST_OPEN flag
10221 It is used in VideoArtist
10222  * @note    It opens the input file, but the output file is not created yet.
10223  * @param   pContext            (IN) MCS context
10224  * @param   pFileIn             (IN) Input file to transcode (The type of this parameter
10225  *                                    (URL, pipe...) depends on the OSAL implementation).
10226  * @param   mediaType           (IN) Container type (.3gp,.amr, ...) of input file.
10227  * @param   pFileOut            (IN) Output file to create  (The type of this parameter
10228  *                                (URL, pipe...) depends on the OSAL implementation).
10229  * @param   pTempFile           (IN) Temporary file for the constant memory writer to store
10230  *                                 metadata ("moov.bin").
10231  * @return  M4NO_ERROR:         No error
10232  * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
10233  * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
10234  * @return  M4ERR_ALLOC:        There is no more available memory
10235  * @return  M4ERR_FILE_NOT_FOUND:   The input file has not been found
10236  * @return  M4MCS_ERR_INVALID_INPUT_FILE:   The input file is not a valid file, or is corrupted
10237  * @return  M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM:  The input file contains no
10238  *                                                         supported audio or video stream
10239  ******************************************************************************
10240  */
M4MCS_open_normalMode(M4MCS_Context pContext,M4OSA_Void * pFileIn,M4VIDEOEDITING_FileType InputFileType,M4OSA_Void * pFileOut,M4OSA_Void * pTempFile)10241 M4OSA_ERR M4MCS_open_normalMode(M4MCS_Context pContext, M4OSA_Void* pFileIn,
10242                                  M4VIDEOEDITING_FileType InputFileType,
10243                                   M4OSA_Void* pFileOut, M4OSA_Void* pTempFile)
10244 {
10245     M4MCS_InternalContext *pC = (M4MCS_InternalContext*)(pContext);
10246     M4OSA_ERR err;
10247 
10248     M4READER_MediaFamily mediaFamily;
10249     M4_StreamHandler* pStreamHandler;
10250 
10251     M4OSA_TRACE2_3("M4MCS_open_normalMode called with pContext=0x%x, pFileIn=0x%x,\
10252      pFileOut=0x%x", pContext, pFileIn, pFileOut);
10253 
10254     /**
10255     * Check input parameters */
10256     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
10257      "M4MCS_open_normalMode: pContext is M4OSA_NULL");
10258     M4OSA_DEBUG_IF2((M4OSA_NULL == pFileIn) , M4ERR_PARAMETER,
10259      "M4MCS_open_normalMode: pFileIn is M4OSA_NULL");
10260 
10261     if ((InputFileType == M4VIDEOEDITING_kFileType_JPG)
10262         ||(InputFileType == M4VIDEOEDITING_kFileType_PNG)
10263         ||(InputFileType == M4VIDEOEDITING_kFileType_GIF)
10264         ||(InputFileType == M4VIDEOEDITING_kFileType_BMP))
10265     {
10266         M4OSA_TRACE1_0("M4MCS_open_normalMode: Still picture is not\
10267              supported with this function");
10268         return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM;
10269     }
10270 
10271     /**
10272     * Check state automaton */
10273     if (M4MCS_kState_CREATED != pC->State)
10274     {
10275         M4OSA_TRACE1_1("M4MCS_open_normalMode(): Wrong State (%d), returning M4ERR_STATE",
10276              pC->State);
10277         return M4ERR_STATE;
10278     }
10279 
10280     /* Copy function input parameters into our context */
10281     pC->pInputFile     = pFileIn;
10282     pC->InputFileType  = InputFileType;
10283     pC->pOutputFile    = pFileOut;
10284     pC->pTemporaryFile = pTempFile;
10285 
10286     /***********************************/
10287     /* Open input file with the reader */
10288     /***********************************/
10289 
10290     err = M4MCS_setCurrentReader(pContext, pC->InputFileType);
10291     M4ERR_CHECK_RETURN(err);
10292 
10293     /**
10294     * Reset reader related variables */
10295     pC->VideoState          = M4MCS_kStreamState_NOSTREAM;
10296     pC->AudioState          = M4MCS_kStreamState_NOSTREAM;
10297     pC->pReaderVideoStream  = M4OSA_NULL;
10298     pC->pReaderAudioStream  = M4OSA_NULL;
10299 
10300     /*******************************************************/
10301     /* Initializes the reader shell and open the data file */
10302     /*******************************************************/
10303     err = pC->m_pReader->m_pFctCreate(&pC->pReaderContext);
10304     if (M4NO_ERROR != err)
10305     {
10306         M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctCreate returns 0x%x", err);
10307         return err;
10308     }
10309 
10310     /**
10311     * Link the reader interface to the reader context */
10312     pC->m_pReaderDataIt->m_readerContext = pC->pReaderContext;
10313 
10314     /**
10315     * Set the reader shell file access functions */
10316     err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext,
10317          M4READER_kOptionID_SetOsaFileReaderFctsPtr,
10318         (M4OSA_DataOption)pC->pOsaFileReadPtr);
10319     if (M4NO_ERROR != err)
10320     {
10321         M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctSetOption returns 0x%x", err);
10322         return err;
10323     }
10324 
10325     /**
10326     * Open the input file */
10327     err = pC->m_pReader->m_pFctOpen(pC->pReaderContext, pC->pInputFile);
10328     if (M4NO_ERROR != err)
10329     {
10330         M4OSA_UInt32 uiDummy, uiCoreId;
10331         M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctOpen returns 0x%x", err);
10332 
10333         if (err == ((M4OSA_UInt32)M4ERR_UNSUPPORTED_MEDIA_TYPE)) {
10334             M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning M4MCS_ERR_FILE_DRM_PROTECTED");
10335             return M4MCS_ERR_FILE_DRM_PROTECTED;
10336         } else {
10337             /**
10338             * If the error is from the core reader, we change it to a public VXS error */
10339             M4OSA_ERR_SPLIT(err, uiDummy, uiCoreId, uiDummy);
10340             if (M4MP4_READER == uiCoreId)
10341             {
10342                 M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning M4MCS_ERR_INVALID_INPUT_FILE");
10343                 return M4MCS_ERR_INVALID_INPUT_FILE;
10344             }
10345         }
10346         return err;
10347     }
10348 
10349     /**
10350     * Get the streams from the input file */
10351     while (M4NO_ERROR == err)
10352     {
10353         err = pC->m_pReader->m_pFctGetNextStream(pC->pReaderContext, &mediaFamily,
10354             &pStreamHandler);
10355 
10356         /**
10357         * In case we found a BIFS stream or something else...*/
10358         if((err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE))
10359             || (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS)))
10360         {
10361             err = M4NO_ERROR;
10362             continue;
10363         }
10364 
10365         if (M4NO_ERROR == err) /**< One stream found */
10366         {
10367             /**
10368             * Found the first video stream */
10369             if ((M4READER_kMediaFamilyVideo == mediaFamily) \
10370                 && (M4OSA_NULL == pC->pReaderVideoStream))
10371             {
10372                 if ((M4DA_StreamTypeVideoH263==pStreamHandler->m_streamType) ||
10373                     (M4DA_StreamTypeVideoMpeg4==pStreamHandler->m_streamType)
10374 #ifdef M4VSS_SUPPORT_VIDEO_AVC
10375                     ||(M4DA_StreamTypeVideoMpeg4Avc==pStreamHandler->m_streamType))
10376 #else
10377                     ||((M4DA_StreamTypeVideoMpeg4Avc==pStreamHandler->m_streamType)
10378                     &&(pC->m_pVideoDecoderItTable[M4DECODER_kVideoTypeAVC] != M4OSA_NULL)))
10379 #endif
10380                 {
10381                     M4OSA_TRACE3_0("M4MCS_open_normalMode():\
10382                      Found a H263 or MPEG-4 video stream in input 3gpp clip");
10383 
10384                     /**
10385                     * Keep pointer to the video stream */
10386                     pC->pReaderVideoStream = (M4_VideoStreamHandler*)pStreamHandler;
10387                     pC->bUnsupportedVideoFound = M4OSA_FALSE;
10388                     pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
10389 
10390                     /**
10391                     * Init our video stream state variable */
10392                     pC->VideoState = M4MCS_kStreamState_STARTED;
10393 
10394                     /**
10395                     * Reset the stream reader */
10396                     err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
10397                          (M4_StreamHandler*)pC->pReaderVideoStream);
10398                     if (M4NO_ERROR != err)
10399                     {
10400                         M4OSA_TRACE1_1("M4MCS_open_normalMode():\
10401                              m_pReader->m_pFctReset(video) returns 0x%x", err);
10402                         return err;
10403                     }
10404 
10405                     /**
10406                     * Initializes an access Unit */
10407                     err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, pStreamHandler,
10408                          &pC->ReaderVideoAU);
10409                     if (M4NO_ERROR != err)
10410                     {
10411                         M4OSA_TRACE1_1("M4MCS_open_normalMode():\
10412                              m_pReader->m_pFctFillAuStruct(video) returns 0x%x", err);
10413                         return err;
10414                     }
10415                 }
10416                 else /**< Not H263 or MPEG-4 (H264, etc.) */
10417                 {
10418                     M4OSA_TRACE1_1("M4MCS_open_normalMode():\
10419                          Found an unsupported video stream (0x%x) in input 3gpp clip",
10420                              pStreamHandler->m_streamType);
10421 
10422                     pC->bUnsupportedVideoFound = M4OSA_TRUE;
10423                     pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
10424                 }
10425             }
10426             /**
10427             * Found the first audio stream */
10428             else if ((M4READER_kMediaFamilyAudio == mediaFamily)
10429                 && (M4OSA_NULL == pC->pReaderAudioStream))
10430             {
10431                 if ((M4DA_StreamTypeAudioAmrNarrowBand==pStreamHandler->m_streamType) ||
10432                     (M4DA_StreamTypeAudioAac==pStreamHandler->m_streamType) ||
10433                     (M4DA_StreamTypeAudioMp3==pStreamHandler->m_streamType) ||
10434                     (M4DA_StreamTypeAudioEvrc==pStreamHandler->m_streamType) )
10435                 {
10436                     M4OSA_TRACE3_0("M4MCS_open_normalMode(): Found an AMR-NB, AAC \
10437                         or MP3 audio stream in input clip");
10438 
10439                     /**
10440                     * Keep pointer to the audio stream */
10441                     pC->pReaderAudioStream = (M4_AudioStreamHandler*)pStreamHandler;
10442                     pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
10443                     pC->bUnsupportedAudioFound = M4OSA_FALSE;
10444 
10445                     /**
10446                     * Init our audio stream state variable */
10447                     pC->AudioState = M4MCS_kStreamState_STARTED;
10448 
10449                     /**
10450                     * Reset the stream reader */
10451                     err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
10452                          (M4_StreamHandler*)pC->pReaderAudioStream);
10453                     if (M4NO_ERROR != err)
10454                     {
10455                         M4OSA_TRACE1_1("M4MCS_open_normalMode():\
10456                              m_pReader->m_pFctReset(audio) returns 0x%x", err);
10457                         return err;
10458                     }
10459 
10460                     /**
10461                     * Initializes an access Unit */
10462                     err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, pStreamHandler,
10463                          &pC->ReaderAudioAU);
10464                     if (M4NO_ERROR != err)
10465                     {
10466                         M4OSA_TRACE1_1("M4MCS_open_normalMode(): \
10467                             m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", err);
10468                         return err;
10469                     }
10470 
10471                     /**
10472                     * Output max AU size is equal to input max AU size (this value
10473                     * will be changed if there is audio transcoding) */
10474                     pC->uiAudioMaxAuSize = pStreamHandler->m_maxAUSize;
10475 
10476                 }
10477                 else
10478                 {
10479                     /**< Not AMR-NB, AAC, MP3 nor EVRC (AMR-WB, WAV...) */
10480                     M4OSA_TRACE1_1("M4MCS_open_normalMode(): Found an unsupported audio stream\
10481                          (0x%x) in input 3gpp clip", pStreamHandler->m_streamType);
10482 
10483                     pC->bUnsupportedAudioFound = M4OSA_TRUE;
10484                     pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
10485                 }
10486             }
10487         }
10488     } /**< end of while (M4NO_ERROR == err) */
10489 
10490     /**
10491     * Check we found at least one supported stream */
10492     if((M4OSA_NULL == pC->pReaderVideoStream) && (M4OSA_NULL == pC->pReaderAudioStream))
10493     {
10494         M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning \
10495             M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM");
10496         return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM;
10497     }
10498 
10499 #ifndef M4VSS_ENABLE_EXTERNAL_DECODERS
10500     if(pC->VideoState == M4MCS_kStreamState_STARTED)
10501     {
10502         err = M4MCS_setCurrentVideoDecoder(pContext,
10503             pC->pReaderVideoStream->m_basicProperties.m_streamType);
10504         M4ERR_CHECK_RETURN(err);
10505     }
10506 #endif
10507 
10508     if(pC->AudioState == M4MCS_kStreamState_STARTED)
10509     {
10510         //EVRC
10511         if(M4DA_StreamTypeAudioEvrc != pStreamHandler->m_streamType)
10512          /* decoder not supported yet, but allow to do null encoding */
10513         {
10514             err = M4MCS_setCurrentAudioDecoder(pContext,
10515                  pC->pReaderAudioStream->m_basicProperties.m_streamType);
10516             M4ERR_CHECK_RETURN(err);
10517         }
10518     }
10519 
10520     /**
10521     * Get the audio and video stream properties */
10522     err = M4MCS_intGetInputClipProperties(pC);
10523     if (M4NO_ERROR != err)
10524     {
10525         M4OSA_TRACE1_1("M4MCS_open_normalMode():\
10526              M4MCS_intGetInputClipProperties returns 0x%x", err);
10527         return err;
10528     }
10529 
10530     /**
10531     * Set the begin cut decoding increment according to the input frame rate */
10532     if (0. != pC->InputFileProperties.fAverageFrameRate) /**< sanity check */
10533     {
10534         pC->iVideoBeginDecIncr = (M4OSA_Int32)(3000. \
10535             / pC->InputFileProperties.fAverageFrameRate); /**< about 3 frames */
10536     }
10537     else
10538     {
10539         pC->iVideoBeginDecIncr = 200; /**< default value: 200 milliseconds (3 frames @ 15fps)*/
10540     }
10541 
10542     /**
10543     * Update state automaton */
10544     pC->State = M4MCS_kState_OPENED;
10545 
10546     /**
10547     * Return with no error */
10548     M4OSA_TRACE3_0("M4MCS_open_normalMode(): returning M4NO_ERROR");
10549     return M4NO_ERROR;
10550 }
10551 
M4MCS_intCheckAndGetCodecProperties(M4MCS_InternalContext * pC)10552 M4OSA_ERR M4MCS_intCheckAndGetCodecProperties(
10553                                  M4MCS_InternalContext *pC) {
10554 
10555     M4OSA_ERR err = M4NO_ERROR;
10556     M4AD_Buffer outputBuffer;
10557     uint32_t optionValue =0;
10558 
10559     M4OSA_TRACE3_0("M4MCS_intCheckAndGetCodecProperties :start");
10560 
10561     // Decode first audio frame from clip to get properties from codec
10562 
10563     if (M4DA_StreamTypeAudioAac ==
10564             pC->pReaderAudioStream->m_basicProperties.m_streamType) {
10565 
10566         err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(
10567                     &pC->pAudioDecCtxt,
10568                     pC->pReaderAudioStream, &(pC->AacProperties));
10569     } else {
10570         err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(
10571                     &pC->pAudioDecCtxt,
10572                     pC->pReaderAudioStream,
10573                     pC->m_pCurrentAudioDecoderUserData);
10574     }
10575     if (M4NO_ERROR != err) {
10576 
10577         M4OSA_TRACE1_1(
10578             "M4MCS_intCheckAndGetCodecProperties: m_pFctCreateAudioDec \
10579              returns 0x%x", err);
10580         return err;
10581     }
10582 
10583     pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
10584            M4AD_kOptionID_3gpReaderInterface, (M4OSA_DataOption) pC->m_pReaderDataIt);
10585 
10586     pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
10587            M4AD_kOptionID_AudioAU, (M4OSA_DataOption) &pC->ReaderAudioAU);
10588 
10589     if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) {
10590 
10591         err = pC->m_pAudioDecoder->m_pFctStartAudioDec(pC->pAudioDecCtxt);
10592         if( M4NO_ERROR != err ) {
10593 
10594             M4OSA_TRACE1_1(
10595                 "M4MCS_intCheckAndGetCodecProperties: m_pFctStartAudioDec \
10596                  returns 0x%x", err);
10597             return err;
10598         }
10599     }
10600 
10601     /**
10602     * Allocate output buffer for the audio decoder */
10603     outputBuffer.m_bufferSize =
10604         pC->pReaderAudioStream->m_byteFrameLength
10605         * pC->pReaderAudioStream->m_byteSampleSize
10606         * pC->pReaderAudioStream->m_nbChannels;
10607 
10608     if( outputBuffer.m_bufferSize > 0 ) {
10609 
10610         outputBuffer.m_dataAddress =
10611             (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(outputBuffer.m_bufferSize \
10612             *sizeof(short), M4MCS, (M4OSA_Char *)"outputBuffer.m_bufferSize");
10613 
10614         if( M4OSA_NULL == outputBuffer.m_dataAddress ) {
10615 
10616             M4OSA_TRACE1_0(
10617                 "M4MCS_intCheckAndGetCodecProperties():\
10618                  unable to allocate outputBuffer.m_dataAddress, returning M4ERR_ALLOC");
10619             return M4ERR_ALLOC;
10620         }
10621     }
10622 
10623     err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt,
10624         M4OSA_NULL, &outputBuffer, M4OSA_FALSE);
10625 
10626     if ( err == M4WAR_INFO_FORMAT_CHANGE ) {
10627 
10628         // Get the properties from codec node
10629         pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt,
10630            M4AD_kOptionID_AudioNbChannels, (M4OSA_DataOption) &optionValue);
10631 
10632         // Reset Reader structure value also
10633         pC->pReaderAudioStream->m_nbChannels = optionValue;
10634 
10635         pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt,
10636          M4AD_kOptionID_AudioSampFrequency, (M4OSA_DataOption) &optionValue);
10637 
10638         // Reset Reader structure value also
10639         pC->pReaderAudioStream->m_samplingFrequency = optionValue;
10640 
10641         if (M4DA_StreamTypeAudioAac ==
10642             pC->pReaderAudioStream->m_basicProperties.m_streamType) {
10643 
10644             pC->AacProperties.aNumChan =
10645                 pC->pReaderAudioStream->m_nbChannels;
10646             pC->AacProperties.aSampFreq =
10647                 pC->pReaderAudioStream->m_samplingFrequency;
10648 
10649         }
10650 
10651     } else if( err != M4NO_ERROR) {
10652         M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecProperties:\
10653             m_pFctStepAudioDec returns err = 0x%x", err);
10654     }
10655 
10656     free(outputBuffer.m_dataAddress);
10657 
10658     // Reset the stream reader
10659     err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
10660                  (M4_StreamHandler *)pC->pReaderAudioStream);
10661 
10662     if (M4NO_ERROR != err) {
10663         M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecProperties\
10664             Error in reseting reader: 0x%x", err);
10665     }
10666 
10667     return err;
10668 
10669 }
10670 
M4MCS_intLimitBitratePerCodecProfileLevel(M4ENCODER_AdvancedParams * EncParams)10671 M4OSA_ERR M4MCS_intLimitBitratePerCodecProfileLevel(
10672                                  M4ENCODER_AdvancedParams* EncParams) {
10673 
10674     M4OSA_ERR err = M4NO_ERROR;
10675 
10676     switch (EncParams->Format) {
10677         case M4ENCODER_kH263:
10678             EncParams->Bitrate = M4MCS_intLimitBitrateForH263Enc(
10679                                      EncParams->videoProfile,
10680                                      EncParams->videoLevel, EncParams->Bitrate);
10681             break;
10682 
10683         case M4ENCODER_kMPEG4:
10684             EncParams->Bitrate = M4MCS_intLimitBitrateForMpeg4Enc(
10685                                      EncParams->videoProfile,
10686                                      EncParams->videoLevel, EncParams->Bitrate);
10687             break;
10688 
10689         case M4ENCODER_kH264:
10690             EncParams->Bitrate = M4MCS_intLimitBitrateForH264Enc(
10691                                      EncParams->videoProfile,
10692                                      EncParams->videoLevel, EncParams->Bitrate);
10693             break;
10694 
10695         default:
10696             M4OSA_TRACE1_1("M4MCS_intLimitBitratePerCodecProfileLevel: \
10697                 Wrong enc format %d", EncParams->Format);
10698             err = M4ERR_PARAMETER;
10699             break;
10700     }
10701 
10702     return err;
10703 
10704 }
10705 
M4MCS_intLimitBitrateForH264Enc(M4OSA_Int32 profile,M4OSA_Int32 level,M4OSA_Int32 bitrate)10706 M4OSA_Int32 M4MCS_intLimitBitrateForH264Enc(M4OSA_Int32 profile,
10707                                     M4OSA_Int32 level, M4OSA_Int32 bitrate) {
10708 
10709     M4OSA_Int32 vidBitrate = 0;
10710 
10711     switch (profile) {
10712         case OMX_VIDEO_AVCProfileBaseline:
10713         case OMX_VIDEO_AVCProfileMain:
10714 
10715             switch (level) {
10716 
10717                 case OMX_VIDEO_AVCLevel1:
10718                     vidBitrate = (bitrate > 64000) ? 64000 : bitrate;
10719                     break;
10720 
10721                 case OMX_VIDEO_AVCLevel1b:
10722                     vidBitrate = (bitrate > 128000) ? 128000 : bitrate;
10723                     break;
10724 
10725                 case OMX_VIDEO_AVCLevel11:
10726                     vidBitrate = (bitrate > 192000) ? 192000 : bitrate;
10727                     break;
10728 
10729                 case OMX_VIDEO_AVCLevel12:
10730                     vidBitrate = (bitrate > 384000) ? 384000 : bitrate;
10731                     break;
10732 
10733                 case OMX_VIDEO_AVCLevel13:
10734                     vidBitrate = (bitrate > 768000) ? 768000 : bitrate;
10735                     break;
10736 
10737                 case OMX_VIDEO_AVCLevel2:
10738                     vidBitrate = (bitrate > 2000000) ? 2000000 : bitrate;
10739                     break;
10740 
10741                 case OMX_VIDEO_AVCLevel21:
10742                     vidBitrate = (bitrate > 4000000) ? 4000000 : bitrate;
10743                     break;
10744 
10745                 case OMX_VIDEO_AVCLevel22:
10746                     vidBitrate = (bitrate > 4000000) ? 4000000 : bitrate;
10747                     break;
10748 
10749                 case OMX_VIDEO_AVCLevel3:
10750                     vidBitrate = (bitrate > 10000000) ? 10000000 : bitrate;
10751                     break;
10752 
10753                 case OMX_VIDEO_AVCLevel31:
10754                     vidBitrate = (bitrate > 14000000) ? 14000000 : bitrate;
10755                     break;
10756 
10757                 case OMX_VIDEO_AVCLevel32:
10758                     vidBitrate = (bitrate > 20000000) ? 20000000 : bitrate;
10759                     break;
10760 
10761                 case OMX_VIDEO_AVCLevel4:
10762                     vidBitrate = (bitrate > 20000000) ? 20000000 : bitrate;
10763                     break;
10764 
10765                 case OMX_VIDEO_AVCLevel41:
10766                     vidBitrate = (bitrate > 50000000) ? 50000000 : bitrate;
10767                     break;
10768 
10769                 case OMX_VIDEO_AVCLevel42:
10770                     vidBitrate = (bitrate > 50000000) ? 50000000 : bitrate;
10771                     break;
10772 
10773                 case OMX_VIDEO_AVCLevel5:
10774                     vidBitrate = (bitrate > 135000000) ? 135000000 : bitrate;
10775                     break;
10776 
10777                 case OMX_VIDEO_AVCLevel51:
10778                     vidBitrate = (bitrate > 240000000) ? 240000000 : bitrate;
10779                     break;
10780 
10781                 default:
10782                     vidBitrate = bitrate;
10783                     break;
10784             }
10785             break;
10786 
10787         case OMX_VIDEO_AVCProfileHigh:
10788             switch (level) {
10789                 case OMX_VIDEO_AVCLevel1:
10790                     vidBitrate = (bitrate > 80000) ? 80000 : bitrate;
10791                     break;
10792 
10793                 case OMX_VIDEO_AVCLevel1b:
10794                     vidBitrate = (bitrate > 160000) ? 160000 : bitrate;
10795                     break;
10796 
10797                 case OMX_VIDEO_AVCLevel11:
10798                     vidBitrate = (bitrate > 240000) ? 240000 : bitrate;
10799                     break;
10800 
10801                 case OMX_VIDEO_AVCLevel12:
10802                     vidBitrate = (bitrate > 480000) ? 480000 : bitrate;
10803                     break;
10804 
10805                 case OMX_VIDEO_AVCLevel13:
10806                     vidBitrate = (bitrate > 960000) ? 960000 : bitrate;
10807                     break;
10808 
10809                 case OMX_VIDEO_AVCLevel2:
10810                     vidBitrate = (bitrate > 2500000) ? 2500000 : bitrate;
10811                     break;
10812 
10813                 case OMX_VIDEO_AVCLevel21:
10814                     vidBitrate = (bitrate > 5000000) ? 5000000 : bitrate;
10815                     break;
10816 
10817                 case OMX_VIDEO_AVCLevel22:
10818                     vidBitrate = (bitrate > 5000000) ? 5000000 : bitrate;
10819                     break;
10820 
10821                 case OMX_VIDEO_AVCLevel3:
10822                     vidBitrate = (bitrate > 12500000) ? 12500000 : bitrate;
10823                     break;
10824 
10825                 case OMX_VIDEO_AVCLevel31:
10826                     vidBitrate = (bitrate > 17500000) ? 17500000 : bitrate;
10827                     break;
10828 
10829                 case OMX_VIDEO_AVCLevel32:
10830                     vidBitrate = (bitrate > 25000000) ? 25000000 : bitrate;
10831                     break;
10832 
10833                 case OMX_VIDEO_AVCLevel4:
10834                     vidBitrate = (bitrate > 25000000) ? 25000000 : bitrate;
10835                     break;
10836 
10837                 case OMX_VIDEO_AVCLevel41:
10838                     vidBitrate = (bitrate > 62500000) ? 62500000 : bitrate;
10839                     break;
10840 
10841                 case OMX_VIDEO_AVCLevel42:
10842                     vidBitrate = (bitrate > 62500000) ? 62500000 : bitrate;
10843                     break;
10844 
10845                 case OMX_VIDEO_AVCLevel5:
10846                     vidBitrate = (bitrate > 168750000) ? 168750000 : bitrate;
10847                     break;
10848 
10849                 case OMX_VIDEO_AVCLevel51:
10850                     vidBitrate = (bitrate > 300000000) ? 300000000 : bitrate;
10851                     break;
10852 
10853                 default:
10854                     vidBitrate = bitrate;
10855                     break;
10856             }
10857             break;
10858 
10859         default:
10860             // We do not handle any other AVC profile for now.
10861             // Return input bitrate
10862             vidBitrate = bitrate;
10863             break;
10864     }
10865 
10866     return vidBitrate;
10867 }
10868 
M4MCS_intLimitBitrateForMpeg4Enc(M4OSA_Int32 profile,M4OSA_Int32 level,M4OSA_Int32 bitrate)10869 M4OSA_Int32 M4MCS_intLimitBitrateForMpeg4Enc(M4OSA_Int32 profile,
10870                                     M4OSA_Int32 level, M4OSA_Int32 bitrate) {
10871 
10872     M4OSA_Int32 vidBitrate = 0;
10873 
10874     switch (profile) {
10875         case OMX_VIDEO_MPEG4ProfileSimple:
10876             switch (level) {
10877 
10878                 case OMX_VIDEO_MPEG4Level0:
10879                     vidBitrate = (bitrate > 64000) ? 64000 : bitrate;
10880                     break;
10881 
10882                 case OMX_VIDEO_MPEG4Level0b:
10883                     vidBitrate = (bitrate > 128000) ? 128000 : bitrate;
10884                     break;
10885 
10886                 case OMX_VIDEO_MPEG4Level1:
10887                     vidBitrate = (bitrate > 64000) ? 64000 : bitrate;
10888                     break;
10889 
10890                 case OMX_VIDEO_MPEG4Level2:
10891                     vidBitrate = (bitrate > 128000) ? 128000 : bitrate;
10892                     break;
10893 
10894                 case OMX_VIDEO_MPEG4Level3:
10895                     vidBitrate = (bitrate > 384000) ? 384000 : bitrate;
10896                     break;
10897 
10898                 default:
10899                     vidBitrate = bitrate;
10900                     break;
10901             }
10902             break;
10903 
10904         default:
10905             // We do not handle any other MPEG4 profile for now.
10906             // Return input bitrate
10907             vidBitrate = bitrate;
10908             break;
10909     }
10910 
10911     return vidBitrate;
10912 }
10913 
M4MCS_intLimitBitrateForH263Enc(M4OSA_Int32 profile,M4OSA_Int32 level,M4OSA_Int32 bitrate)10914 M4OSA_Int32 M4MCS_intLimitBitrateForH263Enc(M4OSA_Int32 profile,
10915                                     M4OSA_Int32 level, M4OSA_Int32 bitrate) {
10916 
10917     M4OSA_Int32 vidBitrate = 0;
10918 
10919     switch (profile) {
10920         case OMX_VIDEO_H263ProfileBaseline:
10921             switch (level) {
10922 
10923                 case OMX_VIDEO_H263Level10:
10924                     vidBitrate = (bitrate > 64000) ? 64000 : bitrate;
10925                     break;
10926 
10927                 case OMX_VIDEO_H263Level20:
10928                     vidBitrate = (bitrate > 128000) ? 128000 : bitrate;
10929                     break;
10930 
10931                 case OMX_VIDEO_H263Level30:
10932                     vidBitrate = (bitrate > 384000) ? 384000 : bitrate;
10933                     break;
10934 
10935                 default:
10936                     vidBitrate = bitrate;
10937                     break;
10938             }
10939             break;
10940 
10941         default:
10942             // We do not handle any other H263 profile for now.
10943             // Return input bitrate
10944             vidBitrate = bitrate;
10945             break;
10946     }
10947 
10948     return vidBitrate;
10949 }
10950