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