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