M4MCS_API.c revision 95651ebc7fbb2efba3f407f4825b7805874bbdf2
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>
48FILE *file_au_reader = NULL;
49FILE *file_pcm_decoder = NULL;
50FILE *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
87static M4OSA_ERR M4MCS_intStepSet( M4MCS_InternalContext *pC );
88static M4OSA_ERR M4MCS_intPrepareVideoDecoder(
89                                    M4MCS_InternalContext *pC );
90static M4OSA_ERR M4MCS_intPrepareVideoEncoder(
91                                    M4MCS_InternalContext *pC );
92static M4OSA_ERR M4MCS_intPrepareAudioProcessing(
93                                    M4MCS_InternalContext *pC );
94static M4OSA_ERR M4MCS_intPrepareWriter( M4MCS_InternalContext *pC );
95static M4OSA_ERR M4MCS_intPrepareAudioBeginCut(
96                                    M4MCS_InternalContext *pC );
97static M4OSA_ERR M4MCS_intStepEncoding(
98                                    M4MCS_InternalContext *pC,
99                                    M4OSA_UInt8 *pTranscodedTime );
100static M4OSA_ERR M4MCS_intStepBeginVideoJump(
101                                    M4MCS_InternalContext *pC );
102static M4OSA_ERR M4MCS_intStepBeginVideoDecode(
103                                    M4MCS_InternalContext *pC );
104static M4OSA_ERR M4MCS_intAudioNullEncoding( M4MCS_InternalContext *pC );
105static M4OSA_ERR M4MCS_intAudioTranscoding( M4MCS_InternalContext *pC );
106static M4OSA_ERR M4MCS_intVideoNullEncoding( M4MCS_InternalContext *pC );
107static M4OSA_ERR M4MCS_intVideoTranscoding( M4MCS_InternalContext *pC );
108static M4OSA_ERR M4MCS_intGetInputClipProperties(
109                                    M4MCS_InternalContext   *pContext );
110static M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB(
111                                    M4OSA_MemAddr8 pAudioFrame );
112static M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC(
113                                    M4OSA_MemAddr8 pAudioFrame );
114static M4OSA_ERR M4MCS_intCheckMaxFileSize( M4MCS_Context pContext );
115static M4VIDEOEDITING_Bitrate M4MCS_intGetNearestBitrate(
116                                    M4OSA_Int32 freebitrate,
117                                    M4OSA_Int8 mode );
118static M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders(
119                                    M4MCS_InternalContext *pC );
120static M4OSA_ERR M4MCS_intReallocTemporaryAU(
121                                    M4OSA_MemAddr8 *addr,
122                                    M4OSA_UInt32 newSize );
123static M4OSA_ERR M4MCS_intCheckAndGetCodecProperties(
124                                 M4MCS_InternalContext *pC);
125
126static M4OSA_ERR M4MCS_intLimitBitratePerCodecProfileLevel(
127                                 M4ENCODER_AdvancedParams* EncParams);
128static M4OSA_Int32 M4MCS_intLimitBitrateForH263Enc(M4OSA_Int32 profile,
129                                 M4OSA_Int32 level, M4OSA_Int32 bitrate);
130static M4OSA_Int32 M4MCS_intLimitBitrateForMpeg4Enc(M4OSA_Int32 profile,
131                                 M4OSA_Int32 level, M4OSA_Int32 bitrate);
132static 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
142M4OSA_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
156static M4OSA_UChar Tab_MCS[8] =
157{
158    17, 5, 3, 3, 1, 1, 1, 1
159};
160
161M4OSA_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
208M4OSA_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
265M4OSA_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
305M4OSA_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
374M4OSA_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
389M4OSA_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
407M4OSA_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
418M4OSA_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
516M4OSA_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
603M4OSA_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
664M4OSA_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
694M4OSA_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
733M4OSA_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
1027M4OSA_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
1157M4OSA_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
1287M4OSA_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
1745M4OSA_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
2004M4OSA_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
2048M4OSA_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 */
2095M4OSA_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
2128M4OSA_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 */
2354M4OSA_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 */
2787M4OSA_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 */
2862M4OSA_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 */
2954M4OSA_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 */
3034M4OSA_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 */
3259M4OSA_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 */
3466M4OSA_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
3537structure which is filled with the input stream properties.
3538 * @note    The structure pProperties must be allocated and further de-allocated
3539by 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 */
3545M4OSA_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 */
3613M4OSA_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 */
4458M4OSA_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 */
4707M4OSA_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 */
5312M4OSA_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 */
5427static 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 */
5605static 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 */
5682static 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 */
6051static 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 */
6559static 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 */
7143static 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 */
7283static 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 */
7572static 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 */
7750static 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
7814const 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
7821extern
7822const
7823M4OSA_UInt8
7824M4VSS3GPP_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
7836const M4OSA_UInt8 M4VSS3GPP_AAC_AU_SILENCE_MONO[
7837    M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE] =
7838    {
7839        0x00, 0xC8, 0x20, 0x07
7840    };
7841#else
7842
7843extern const M4OSA_UInt8
7844M4VSS3GPP_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
7852const 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
7859extern const
7860M4OSA_UInt8
7861M4VSS3GPP_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
7872static 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 */
8219static 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
8319m4mcs_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
8396m4mcs_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
8449m4mcs_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
8575m4mcs_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
8598m4mcs_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
8757m4mcs_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 */
8773static 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 */
8798static 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 */
9275static 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 */
9364static 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 */
9833static 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 */
9919static 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 */
9969static 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 */
10060static M4VIDEOEDITING_Bitrate
10061M4MCS_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 */
10117static 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
10224It 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 */
10244M4OSA_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
10555M4OSA_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
10579    pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
10580           M4AD_kOptionID_3gpReaderInterface, (M4OSA_DataOption) pC->m_pReaderDataIt);
10581
10582    pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
10583           M4AD_kOptionID_AudioAU, (M4OSA_DataOption) &pC->ReaderAudioAU);
10584
10585    if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) {
10586
10587        err = pC->m_pAudioDecoder->m_pFctStartAudioDec(pC->pAudioDecCtxt);
10588        if( M4NO_ERROR != err ) {
10589
10590            M4OSA_TRACE1_1(
10591                "M4MCS_intCheckAndGetCodecProperties: m_pFctStartAudioDec \
10592                 returns 0x%x", err);
10593            return err;
10594        }
10595    }
10596
10597    /**
10598    * Allocate output buffer for the audio decoder */
10599    outputBuffer.m_bufferSize =
10600        pC->pReaderAudioStream->m_byteFrameLength
10601        * pC->pReaderAudioStream->m_byteSampleSize
10602        * pC->pReaderAudioStream->m_nbChannels;
10603
10604    if( outputBuffer.m_bufferSize > 0 ) {
10605
10606        outputBuffer.m_dataAddress =
10607            (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(outputBuffer.m_bufferSize \
10608            *sizeof(short), M4MCS, (M4OSA_Char *)"outputBuffer.m_bufferSize");
10609
10610        if( M4OSA_NULL == outputBuffer.m_dataAddress ) {
10611
10612            M4OSA_TRACE1_0(
10613                "M4MCS_intCheckAndGetCodecProperties():\
10614                 unable to allocate outputBuffer.m_dataAddress, returning M4ERR_ALLOC");
10615            return M4ERR_ALLOC;
10616        }
10617    }
10618
10619    err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt,
10620        M4OSA_NULL, &outputBuffer, M4OSA_FALSE);
10621
10622    if ( err == M4WAR_INFO_FORMAT_CHANGE ) {
10623
10624        // Get the properties from codec node
10625        pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt,
10626           M4AD_kOptionID_AudioNbChannels, (M4OSA_DataOption) &optionValue);
10627
10628        // Reset Reader structure value also
10629        pC->pReaderAudioStream->m_nbChannels = optionValue;
10630
10631        pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt,
10632         M4AD_kOptionID_AudioSampFrequency, (M4OSA_DataOption) &optionValue);
10633
10634        // Reset Reader structure value also
10635        pC->pReaderAudioStream->m_samplingFrequency = optionValue;
10636
10637        if (M4DA_StreamTypeAudioAac ==
10638            pC->pReaderAudioStream->m_basicProperties.m_streamType) {
10639
10640            pC->AacProperties.aNumChan =
10641                pC->pReaderAudioStream->m_nbChannels;
10642            pC->AacProperties.aSampFreq =
10643                pC->pReaderAudioStream->m_samplingFrequency;
10644
10645        }
10646
10647    } else if( err != M4NO_ERROR) {
10648        M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecProperties:\
10649            m_pFctStepAudioDec returns err = 0x%x", err);
10650    }
10651
10652    free(outputBuffer.m_dataAddress);
10653
10654    // Reset the stream reader
10655    err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
10656                 (M4_StreamHandler *)pC->pReaderAudioStream);
10657
10658    if (M4NO_ERROR != err) {
10659        M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecProperties\
10660            Error in reseting reader: 0x%x", err);
10661    }
10662
10663    return err;
10664
10665}
10666
10667M4OSA_ERR M4MCS_intLimitBitratePerCodecProfileLevel(
10668                                 M4ENCODER_AdvancedParams* EncParams) {
10669
10670    M4OSA_ERR err = M4NO_ERROR;
10671
10672    switch (EncParams->Format) {
10673        case M4ENCODER_kH263:
10674            EncParams->Bitrate = M4MCS_intLimitBitrateForH263Enc(
10675                                     EncParams->videoProfile,
10676                                     EncParams->videoLevel, EncParams->Bitrate);
10677            break;
10678
10679        case M4ENCODER_kMPEG4:
10680            EncParams->Bitrate = M4MCS_intLimitBitrateForMpeg4Enc(
10681                                     EncParams->videoProfile,
10682                                     EncParams->videoLevel, EncParams->Bitrate);
10683            break;
10684
10685        case M4ENCODER_kH264:
10686            EncParams->Bitrate = M4MCS_intLimitBitrateForH264Enc(
10687                                     EncParams->videoProfile,
10688                                     EncParams->videoLevel, EncParams->Bitrate);
10689            break;
10690
10691        default:
10692            M4OSA_TRACE1_1("M4MCS_intLimitBitratePerCodecProfileLevel: \
10693                Wrong enc format %d", EncParams->Format);
10694            err = M4ERR_PARAMETER;
10695            break;
10696    }
10697
10698    return err;
10699
10700}
10701
10702M4OSA_Int32 M4MCS_intLimitBitrateForH264Enc(M4OSA_Int32 profile,
10703                                    M4OSA_Int32 level, M4OSA_Int32 bitrate) {
10704
10705    M4OSA_Int32 vidBitrate = 0;
10706
10707    switch (profile) {
10708        case OMX_VIDEO_AVCProfileBaseline:
10709        case OMX_VIDEO_AVCProfileMain:
10710
10711            switch (level) {
10712
10713                case OMX_VIDEO_AVCLevel1:
10714                    vidBitrate = (bitrate > 64000) ? 64000 : bitrate;
10715                    break;
10716
10717                case OMX_VIDEO_AVCLevel1b:
10718                    vidBitrate = (bitrate > 128000) ? 128000 : bitrate;
10719                    break;
10720
10721                case OMX_VIDEO_AVCLevel11:
10722                    vidBitrate = (bitrate > 192000) ? 192000 : bitrate;
10723                    break;
10724
10725                case OMX_VIDEO_AVCLevel12:
10726                    vidBitrate = (bitrate > 384000) ? 384000 : bitrate;
10727                    break;
10728
10729                case OMX_VIDEO_AVCLevel13:
10730                    vidBitrate = (bitrate > 768000) ? 768000 : bitrate;
10731                    break;
10732
10733                case OMX_VIDEO_AVCLevel2:
10734                    vidBitrate = (bitrate > 2000000) ? 2000000 : bitrate;
10735                    break;
10736
10737                case OMX_VIDEO_AVCLevel21:
10738                    vidBitrate = (bitrate > 4000000) ? 4000000 : bitrate;
10739                    break;
10740
10741                case OMX_VIDEO_AVCLevel22:
10742                    vidBitrate = (bitrate > 4000000) ? 4000000 : bitrate;
10743                    break;
10744
10745                case OMX_VIDEO_AVCLevel3:
10746                    vidBitrate = (bitrate > 10000000) ? 10000000 : bitrate;
10747                    break;
10748
10749                case OMX_VIDEO_AVCLevel31:
10750                    vidBitrate = (bitrate > 14000000) ? 14000000 : bitrate;
10751                    break;
10752
10753                case OMX_VIDEO_AVCLevel32:
10754                    vidBitrate = (bitrate > 20000000) ? 20000000 : bitrate;
10755                    break;
10756
10757                case OMX_VIDEO_AVCLevel4:
10758                    vidBitrate = (bitrate > 20000000) ? 20000000 : bitrate;
10759                    break;
10760
10761                case OMX_VIDEO_AVCLevel41:
10762                    vidBitrate = (bitrate > 50000000) ? 50000000 : bitrate;
10763                    break;
10764
10765                case OMX_VIDEO_AVCLevel42:
10766                    vidBitrate = (bitrate > 50000000) ? 50000000 : bitrate;
10767                    break;
10768
10769                case OMX_VIDEO_AVCLevel5:
10770                    vidBitrate = (bitrate > 135000000) ? 135000000 : bitrate;
10771                    break;
10772
10773                case OMX_VIDEO_AVCLevel51:
10774                    vidBitrate = (bitrate > 240000000) ? 240000000 : bitrate;
10775                    break;
10776
10777                default:
10778                    vidBitrate = bitrate;
10779                    break;
10780            }
10781            break;
10782
10783        case OMX_VIDEO_AVCProfileHigh:
10784            switch (level) {
10785                case OMX_VIDEO_AVCLevel1:
10786                    vidBitrate = (bitrate > 80000) ? 80000 : bitrate;
10787                    break;
10788
10789                case OMX_VIDEO_AVCLevel1b:
10790                    vidBitrate = (bitrate > 160000) ? 160000 : bitrate;
10791                    break;
10792
10793                case OMX_VIDEO_AVCLevel11:
10794                    vidBitrate = (bitrate > 240000) ? 240000 : bitrate;
10795                    break;
10796
10797                case OMX_VIDEO_AVCLevel12:
10798                    vidBitrate = (bitrate > 480000) ? 480000 : bitrate;
10799                    break;
10800
10801                case OMX_VIDEO_AVCLevel13:
10802                    vidBitrate = (bitrate > 960000) ? 960000 : bitrate;
10803                    break;
10804
10805                case OMX_VIDEO_AVCLevel2:
10806                    vidBitrate = (bitrate > 2500000) ? 2500000 : bitrate;
10807                    break;
10808
10809                case OMX_VIDEO_AVCLevel21:
10810                    vidBitrate = (bitrate > 5000000) ? 5000000 : bitrate;
10811                    break;
10812
10813                case OMX_VIDEO_AVCLevel22:
10814                    vidBitrate = (bitrate > 5000000) ? 5000000 : bitrate;
10815                    break;
10816
10817                case OMX_VIDEO_AVCLevel3:
10818                    vidBitrate = (bitrate > 12500000) ? 12500000 : bitrate;
10819                    break;
10820
10821                case OMX_VIDEO_AVCLevel31:
10822                    vidBitrate = (bitrate > 17500000) ? 17500000 : bitrate;
10823                    break;
10824
10825                case OMX_VIDEO_AVCLevel32:
10826                    vidBitrate = (bitrate > 25000000) ? 25000000 : bitrate;
10827                    break;
10828
10829                case OMX_VIDEO_AVCLevel4:
10830                    vidBitrate = (bitrate > 25000000) ? 25000000 : bitrate;
10831                    break;
10832
10833                case OMX_VIDEO_AVCLevel41:
10834                    vidBitrate = (bitrate > 62500000) ? 62500000 : bitrate;
10835                    break;
10836
10837                case OMX_VIDEO_AVCLevel42:
10838                    vidBitrate = (bitrate > 62500000) ? 62500000 : bitrate;
10839                    break;
10840
10841                case OMX_VIDEO_AVCLevel5:
10842                    vidBitrate = (bitrate > 168750000) ? 168750000 : bitrate;
10843                    break;
10844
10845                case OMX_VIDEO_AVCLevel51:
10846                    vidBitrate = (bitrate > 300000000) ? 300000000 : bitrate;
10847                    break;
10848
10849                default:
10850                    vidBitrate = bitrate;
10851                    break;
10852            }
10853            break;
10854
10855        default:
10856            // We do not handle any other AVC profile for now.
10857            // Return input bitrate
10858            vidBitrate = bitrate;
10859            break;
10860    }
10861
10862    return vidBitrate;
10863}
10864
10865M4OSA_Int32 M4MCS_intLimitBitrateForMpeg4Enc(M4OSA_Int32 profile,
10866                                    M4OSA_Int32 level, M4OSA_Int32 bitrate) {
10867
10868    M4OSA_Int32 vidBitrate = 0;
10869
10870    switch (profile) {
10871        case OMX_VIDEO_MPEG4ProfileSimple:
10872            switch (level) {
10873
10874                case OMX_VIDEO_MPEG4Level0:
10875                    vidBitrate = (bitrate > 64000) ? 64000 : bitrate;
10876                    break;
10877
10878                case OMX_VIDEO_MPEG4Level0b:
10879                    vidBitrate = (bitrate > 128000) ? 128000 : bitrate;
10880                    break;
10881
10882                case OMX_VIDEO_MPEG4Level1:
10883                    vidBitrate = (bitrate > 64000) ? 64000 : bitrate;
10884                    break;
10885
10886                case OMX_VIDEO_MPEG4Level2:
10887                    vidBitrate = (bitrate > 128000) ? 128000 : bitrate;
10888                    break;
10889
10890                case OMX_VIDEO_MPEG4Level3:
10891                    vidBitrate = (bitrate > 384000) ? 384000 : bitrate;
10892                    break;
10893
10894                default:
10895                    vidBitrate = bitrate;
10896                    break;
10897            }
10898            break;
10899
10900        default:
10901            // We do not handle any other MPEG4 profile for now.
10902            // Return input bitrate
10903            vidBitrate = bitrate;
10904            break;
10905    }
10906
10907    return vidBitrate;
10908}
10909
10910M4OSA_Int32 M4MCS_intLimitBitrateForH263Enc(M4OSA_Int32 profile,
10911                                    M4OSA_Int32 level, M4OSA_Int32 bitrate) {
10912
10913    M4OSA_Int32 vidBitrate = 0;
10914
10915    switch (profile) {
10916        case OMX_VIDEO_H263ProfileBaseline:
10917            switch (level) {
10918
10919                case OMX_VIDEO_H263Level10:
10920                    vidBitrate = (bitrate > 64000) ? 64000 : bitrate;
10921                    break;
10922
10923                case OMX_VIDEO_H263Level20:
10924                    vidBitrate = (bitrate > 128000) ? 128000 : bitrate;
10925                    break;
10926
10927                case OMX_VIDEO_H263Level30:
10928                    vidBitrate = (bitrate > 384000) ? 384000 : bitrate;
10929                    break;
10930
10931                default:
10932                    vidBitrate = bitrate;
10933                    break;
10934            }
10935            break;
10936
10937        default:
10938            // We do not handle any other H263 profile for now.
10939            // Return input bitrate
10940            vidBitrate = bitrate;
10941            break;
10942    }
10943
10944    return vidBitrate;
10945}
10946