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