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