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