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