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