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