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