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