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             pC->encodingVideoLevel = pC->InputFileProperties.uiVideoLevel;
   3750 
   3751             // Clip's original width and height may not be
   3752             // multiple of 16.
   3753             // Ensure encoding width and height are multiple of 16
   3754 
   3755             uint32_t remainder = pC->EncodingWidth % 16;
   3756             if (remainder != 0) {
   3757                 if (remainder >= 8) {
   3758                     // Roll forward
   3759                     pC->EncodingWidth =
   3760                         pC->EncodingWidth + (16-remainder);
   3761                 } else {
   3762                     // Roll backward
   3763                     pC->EncodingWidth =
   3764                         pC->EncodingWidth - remainder;
   3765                 }
   3766                 uiFrameWidth = pC->EncodingWidth;
   3767             }
   3768 
   3769             remainder = pC->EncodingHeight % 16;
   3770             if (remainder != 0) {
   3771                 if (remainder >= 8) {
   3772                     // Roll forward
   3773                     pC->EncodingHeight =
   3774                         pC->EncodingHeight + (16-remainder);
   3775                 } else {
   3776                     // Roll backward
   3777                     pC->EncodingHeight =
   3778                         pC->EncodingHeight - remainder;
   3779                 }
   3780                 uiFrameHeight = pC->EncodingHeight;
   3781             }
   3782 
   3783         }
   3784         else
   3785         {
   3786             /**
   3787             * Set output video profile and level */
   3788             pC->encodingVideoProfile = pParams->outputVideoProfile;
   3789             pC->encodingVideoLevel = pParams->outputVideoLevel;
   3790 
   3791             switch( pParams->OutputVideoFrameSize )
   3792             {
   3793                 case M4VIDEOEDITING_kSQCIF:
   3794                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_SQCIF_Width;
   3795                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_SQCIF_Height;
   3796                     break;
   3797 
   3798                 case M4VIDEOEDITING_kQQVGA:
   3799                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_QQVGA_Width;
   3800                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_QQVGA_Height;
   3801                     break;
   3802 
   3803                 case M4VIDEOEDITING_kQCIF:
   3804                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_QCIF_Width;
   3805                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_QCIF_Height;
   3806                     break;
   3807 
   3808                 case M4VIDEOEDITING_kQVGA:
   3809                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_QVGA_Width;
   3810                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_QVGA_Height;
   3811                     break;
   3812 
   3813                 case M4VIDEOEDITING_kCIF:
   3814                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_CIF_Width;
   3815                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_CIF_Height;
   3816                     break;
   3817 
   3818                 case M4VIDEOEDITING_kVGA:
   3819                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_VGA_Width;
   3820                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_VGA_Height;
   3821                     break;
   3822                     /* +PR LV5807 */
   3823                 case M4VIDEOEDITING_kWVGA:
   3824                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_WVGA_Width;
   3825                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_WVGA_Height;
   3826                     break;
   3827 
   3828                 case M4VIDEOEDITING_kNTSC:
   3829                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_NTSC_Width;
   3830                     uiFrameHeight = pC->EncodingHeight = M4ENCODER_NTSC_Height;
   3831                     break;
   3832                     /* -PR LV5807*/
   3833                     /* +CR Google */
   3834                 case M4VIDEOEDITING_k640_360:
   3835                     uiFrameWidth = pC->EncodingWidth = M4ENCODER_640_360_Width;
   3836                     uiFrameHeight =
   3837                         pC->EncodingHeight = M4ENCODER_640_360_Height;
   3838                     break;
   3839 
   3840                 case M4VIDEOEDITING_k854_480:
   3841                     uiFrameWidth =
   3842                         pC->EncodingWidth = M4ENCODER_854_480_Width;
   3843                     uiFrameHeight =
   3844                         pC->EncodingHeight = M4ENCODER_854_480_Height;
   3845                     break;
   3846 
   3847                 case M4VIDEOEDITING_k1280_720:
   3848                     uiFrameWidth =
   3849                         pC->EncodingWidth = M4ENCODER_1280_720_Width;
   3850                     uiFrameHeight =
   3851                         pC->EncodingHeight = M4ENCODER_1280_720_Height;
   3852                     break;
   3853 
   3854                 case M4VIDEOEDITING_k1080_720:
   3855                     uiFrameWidth =
   3856                         pC->EncodingWidth = M4ENCODER_1080_720_Width;
   3857                     uiFrameHeight =
   3858                         pC->EncodingHeight = M4ENCODER_1080_720_Height;
   3859                     break;
   3860 
   3861                 case M4VIDEOEDITING_k960_720:
   3862                     uiFrameWidth =
   3863                         pC->EncodingWidth = M4ENCODER_960_720_Width;
   3864                     uiFrameHeight =
   3865                         pC->EncodingHeight = M4ENCODER_960_720_Height;
   3866                     break;
   3867 
   3868                 case M4VIDEOEDITING_k1920_1080:
   3869                     uiFrameWidth =
   3870                         pC->EncodingWidth = M4ENCODER_1920_1080_Width;
   3871                     uiFrameHeight =
   3872                         pC->EncodingHeight = M4ENCODER_1920_1080_Height;
   3873                     break;
   3874                     /* -CR Google */
   3875                 default:
   3876                     M4OSA_TRACE1_1(
   3877                         "M4MCS_setOutputParams: Undefined output video frame size \
   3878                         (%d), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE",
   3879                         pParams->OutputVideoFrameSize);
   3880                     return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE;
   3881             }
   3882         }
   3883 
   3884         /**
   3885         * Compute video max au size and max chunck size.
   3886         * We do it here because it depends on the frame size only, and
   3887         * because we need it for the file size/video bitrate estimations */
   3888         pC->uiVideoMaxAuSize =
   3889             (M4OSA_UInt32)(1.5F *(M4OSA_Float)(uiFrameWidth * uiFrameHeight) \
   3890             *M4MCS_VIDEO_MIN_COMPRESSION_RATIO);
   3891         pC->uiVideoMaxChunckSize = (M4OSA_UInt32)(pC->uiVideoMaxAuSize       \
   3892             *
   3893             M4MCS_VIDEO_CHUNK_AU_SIZE_RATIO); /**< from max AU size to max Chunck size */
   3894 
   3895         if( 0 == pC->uiVideoMaxAuSize )
   3896         {
   3897             /* Size may be zero in case of null encoding with unrecognized stream */
   3898             M4OSA_TRACE1_0("M4MCS_setOutputParams: video frame size is 0 returning\
   3899                            M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE");
   3900             return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE;
   3901         }
   3902 
   3903 
   3904         /**
   3905         * Size check for H263 (only valid sizes are CIF, QCIF and SQCIF) */
   3906 
   3907         if( M4VIDEOEDITING_kH263 == pParams->OutputVideoFormat )
   3908         {
   3909             switch( pParams->OutputVideoFrameSize )
   3910             {
   3911                 case M4VIDEOEDITING_kSQCIF:
   3912                 case M4VIDEOEDITING_kQCIF:
   3913                 case M4VIDEOEDITING_kCIF:
   3914                     /* OK */
   3915                     break;
   3916 
   3917                 default:
   3918                     M4OSA_TRACE1_0(
   3919                         "M4MCS_setOutputParams():\
   3920                         returning M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263");
   3921                     return M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263;
   3922             }
   3923         }
   3924 
   3925         /**
   3926         * Check Video Frame rate correctness */
   3927         if( M4VIDEOEDITING_kNullVideo != pParams->OutputVideoFormat )
   3928         {
   3929             switch( pParams->OutputVideoFrameRate )
   3930             {
   3931                 case M4VIDEOEDITING_k5_FPS:
   3932                     pC->EncodingVideoFramerate = M4ENCODER_k5_FPS;
   3933                     break;
   3934 
   3935                 case M4VIDEOEDITING_k7_5_FPS:
   3936                     pC->EncodingVideoFramerate = M4ENCODER_k7_5_FPS;
   3937                     break;
   3938 
   3939                 case M4VIDEOEDITING_k10_FPS:
   3940                     pC->EncodingVideoFramerate = M4ENCODER_k10_FPS;
   3941                     break;
   3942 
   3943                 case M4VIDEOEDITING_k12_5_FPS:
   3944                     pC->EncodingVideoFramerate = M4ENCODER_k12_5_FPS;
   3945                     break;
   3946 
   3947                 case M4VIDEOEDITING_k15_FPS:
   3948                     pC->EncodingVideoFramerate = M4ENCODER_k15_FPS;
   3949                     break;
   3950 
   3951                 case M4VIDEOEDITING_k20_FPS:
   3952                     pC->EncodingVideoFramerate = M4ENCODER_k20_FPS;
   3953                     break;
   3954 
   3955                 case M4VIDEOEDITING_k25_FPS:
   3956                     pC->EncodingVideoFramerate = M4ENCODER_k25_FPS;
   3957                     break;
   3958 
   3959                 case M4VIDEOEDITING_k30_FPS:
   3960                     pC->EncodingVideoFramerate = M4ENCODER_k30_FPS;
   3961                     break;
   3962 
   3963                 default:
   3964                     M4OSA_TRACE1_1(
   3965                         "M4MCS_setOutputParams: Undefined output video frame rate\
   3966                         (%d), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE",
   3967                         pParams->OutputVideoFrameRate);
   3968                     return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE;
   3969             }
   3970         }
   3971 
   3972         /**
   3973         * Frame rate check for H263 (only dividers of 30 fps (29.97 actually)) */
   3974         if( M4VIDEOEDITING_kH263 == pParams->OutputVideoFormat )
   3975         {
   3976             switch( pC->EncodingVideoFramerate )
   3977             {
   3978                 case M4ENCODER_k5_FPS:
   3979                 case M4ENCODER_k7_5_FPS:
   3980                 case M4ENCODER_k10_FPS:
   3981                 case M4ENCODER_k15_FPS:
   3982                 case M4ENCODER_k30_FPS:
   3983                     /* OK */
   3984                     break;
   3985 
   3986                 default:
   3987                     M4OSA_TRACE1_0(
   3988                         "M4MCS_setOutputParams():\
   3989                         returning M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263");
   3990                     return M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263;
   3991             }
   3992         }
   3993     }
   3994 
   3995     /* Set audio parameters */
   3996     if( pC->noaudio == M4OSA_FALSE )
   3997     {
   3998         /**
   3999         * Check Audio Format correctness */
   4000         switch( pParams->OutputAudioFormat )
   4001         {
   4002             case M4VIDEOEDITING_kAMR_NB:
   4003 
   4004                 err = M4MCS_setCurrentAudioEncoder(pContext,
   4005                     pParams->OutputAudioFormat);
   4006                 M4ERR_CHECK_RETURN(err);
   4007 
   4008                 pC->AudioEncParams.Format = M4ENCODER_kAMRNB;
   4009                 pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
   4010                 pC->AudioEncParams.ChannelNum = M4ENCODER_kMono;
   4011                 pC->AudioEncParams.SpecifParam.AmrSID = M4ENCODER_kAmrNoSID;
   4012                 break;
   4013 
   4014             case M4VIDEOEDITING_kAAC:
   4015 
   4016                 err = M4MCS_setCurrentAudioEncoder(pContext,
   4017                     pParams->OutputAudioFormat);
   4018                 M4ERR_CHECK_RETURN(err);
   4019 
   4020                 pC->AudioEncParams.Format = M4ENCODER_kAAC;
   4021                 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
   4022 
   4023                 switch( pParams->OutputAudioSamplingFrequency )
   4024                 {
   4025                     case M4VIDEOEDITING_k8000_ASF:
   4026                         pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
   4027                         break;
   4028 
   4029                     case M4VIDEOEDITING_k16000_ASF:
   4030                         pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
   4031                         break;
   4032 
   4033                     case M4VIDEOEDITING_k22050_ASF:
   4034                         pC->AudioEncParams.Frequency = M4ENCODER_k22050Hz;
   4035                         break;
   4036 
   4037                     case M4VIDEOEDITING_k24000_ASF:
   4038                         pC->AudioEncParams.Frequency = M4ENCODER_k24000Hz;
   4039                         break;
   4040 
   4041                     case M4VIDEOEDITING_k32000_ASF:
   4042                         pC->AudioEncParams.Frequency = M4ENCODER_k32000Hz;
   4043                         break;
   4044 
   4045                     case M4VIDEOEDITING_k44100_ASF:
   4046                         pC->AudioEncParams.Frequency = M4ENCODER_k44100Hz;
   4047                         break;
   4048 
   4049                     case M4VIDEOEDITING_k48000_ASF:
   4050                         pC->AudioEncParams.Frequency = M4ENCODER_k48000Hz;
   4051                         break;
   4052 
   4053                     case M4VIDEOEDITING_k11025_ASF:
   4054                     case M4VIDEOEDITING_k12000_ASF:
   4055                     case M4VIDEOEDITING_kDefault_ASF:
   4056                         break;
   4057                 }
   4058                     pC->AudioEncParams.ChannelNum =
   4059                         (pParams->bAudioMono == M4OSA_TRUE) ? \
   4060                         M4ENCODER_kMono : M4ENCODER_kStereo;
   4061                     pC->AudioEncParams.SpecifParam.AacParam.Regulation =
   4062                         M4ENCODER_kAacRegulNone; //M4ENCODER_kAacBitReservoir
   4063                     /* unused */
   4064                     pC->AudioEncParams.SpecifParam.AacParam.bIS = M4OSA_FALSE;
   4065                     pC->AudioEncParams.SpecifParam.AacParam.bMS = M4OSA_FALSE;
   4066                     pC->AudioEncParams.SpecifParam.AacParam.bPNS = M4OSA_FALSE;
   4067                     pC->AudioEncParams.SpecifParam.AacParam.bTNS = M4OSA_FALSE;
   4068                     /* TODO change into highspeed asap */
   4069                     pC->AudioEncParams.SpecifParam.AacParam.bHighSpeed =
   4070                         M4OSA_FALSE;
   4071                     break;
   4072 
   4073                     /*FlB 26.02.2009: add mp3 as mcs output format, add mp3 encoder*/
   4074                 case M4VIDEOEDITING_kMP3:
   4075                     err = M4MCS_setCurrentAudioEncoder(pContext,
   4076                         pParams->OutputAudioFormat);
   4077                     M4ERR_CHECK_RETURN(err);
   4078 
   4079                     pC->AudioEncParams.Format = M4ENCODER_kMP3;
   4080                     pC->AudioEncParams.ChannelNum =
   4081                         (pParams->bAudioMono == M4OSA_TRUE) ? \
   4082                         M4ENCODER_kMono : M4ENCODER_kStereo;
   4083 
   4084                     pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
   4085 
   4086                     switch( pParams->OutputAudioSamplingFrequency )
   4087                     {
   4088                         case M4VIDEOEDITING_k8000_ASF:
   4089                             pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
   4090                             break;
   4091 
   4092                         case M4VIDEOEDITING_k11025_ASF:
   4093                             pC->AudioEncParams.Frequency = M4ENCODER_k11025Hz;
   4094                             break;
   4095 
   4096                         case M4VIDEOEDITING_k12000_ASF:
   4097                             pC->AudioEncParams.Frequency = M4ENCODER_k12000Hz;
   4098                             break;
   4099 
   4100                         case M4VIDEOEDITING_k16000_ASF:
   4101                             pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
   4102                             break;
   4103 
   4104                         case M4VIDEOEDITING_k22050_ASF:
   4105                             pC->AudioEncParams.Frequency = M4ENCODER_k22050Hz;
   4106                             break;
   4107 
   4108                         case M4VIDEOEDITING_k24000_ASF:
   4109                             pC->AudioEncParams.Frequency = M4ENCODER_k24000Hz;
   4110                             break;
   4111 
   4112                         case M4VIDEOEDITING_k32000_ASF:
   4113                             pC->AudioEncParams.Frequency = M4ENCODER_k32000Hz;
   4114                             break;
   4115 
   4116                         case M4VIDEOEDITING_k44100_ASF:
   4117                             pC->AudioEncParams.Frequency = M4ENCODER_k44100Hz;
   4118                             break;
   4119 
   4120                         case M4VIDEOEDITING_k48000_ASF:
   4121                             pC->AudioEncParams.Frequency = M4ENCODER_k48000Hz;
   4122                             break;
   4123 
   4124                         case M4VIDEOEDITING_kDefault_ASF:
   4125                             break;
   4126                     }
   4127 
   4128                     break;
   4129 
   4130                 case M4VIDEOEDITING_kNullAudio:
   4131                     if( pParams->pEffects == M4OSA_NULL || pParams->nbEffects == 0 )
   4132                     {
   4133                         /* no encoder needed */
   4134                         pC->AudioEncParams.Format = M4ENCODER_kAudioNULL;
   4135                         pC->AudioEncParams.Frequency =
   4136                             pC->pReaderAudioStream->m_samplingFrequency;
   4137                         pC->AudioEncParams.ChannelNum =
   4138                             (pC->pReaderAudioStream->m_nbChannels == 1) ? \
   4139                             M4ENCODER_kMono : M4ENCODER_kStereo;
   4140                     }
   4141                     else
   4142                     {
   4143                         pC->AudioEncParams.Frequency =
   4144                             pC->pReaderAudioStream->m_samplingFrequency;
   4145                         pC->AudioEncParams.ChannelNum =
   4146                             (pC->pReaderAudioStream->m_nbChannels == 1) ? \
   4147                             M4ENCODER_kMono : M4ENCODER_kStereo;
   4148 
   4149                         switch( pC->InputFileProperties.AudioStreamType )
   4150                         {
   4151                             case M4VIDEOEDITING_kAMR_NB:
   4152                                 M4OSA_TRACE3_0(
   4153                                     "M4MCS_setOutputParams calling \
   4154                                     M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, AMR");
   4155                                 err = M4MCS_setCurrentAudioEncoder(pContext,
   4156                                     pC->InputFileProperties.AudioStreamType);
   4157                                 M4ERR_CHECK_RETURN(err);
   4158 
   4159                                 pC->AudioEncParams.Format = M4ENCODER_kAMRNB;
   4160                                 pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
   4161                                 pC->AudioEncParams.ChannelNum = M4ENCODER_kMono;
   4162 
   4163                                 if( pC->pReaderAudioStream->m_samplingFrequency
   4164                                     != 8000 )
   4165                                 {
   4166                                     pC->AudioEncParams.Format = M4ENCODER_kAMRNB;
   4167                                 }
   4168                                 pC->AudioEncParams.SpecifParam.AmrSID =
   4169                                     M4ENCODER_kAmrNoSID;
   4170                                 break;
   4171 
   4172                             case M4VIDEOEDITING_kAAC:
   4173                                 M4OSA_TRACE3_0(
   4174                                     "M4MCS_setOutputParams calling \
   4175                                     M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, AAC");
   4176                                 err = M4MCS_setCurrentAudioEncoder(pContext,
   4177                                     pC->InputFileProperties.AudioStreamType);
   4178                                 M4ERR_CHECK_RETURN(err);
   4179 
   4180                                 pC->AudioEncParams.Format = M4ENCODER_kAAC;
   4181                                 pC->AudioEncParams.SpecifParam.AacParam.Regulation =
   4182                                     M4ENCODER_kAacRegulNone; //M4ENCODER_kAacBitReservoir
   4183                                 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
   4184                                 pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
   4185 
   4186                                 switch( pC->pReaderAudioStream->
   4187                                     m_samplingFrequency )
   4188                                 {
   4189                                 case 16000:
   4190                                     pC->AudioEncParams.Frequency =
   4191                                         M4ENCODER_k16000Hz;
   4192                                     break;
   4193 
   4194                                 case 22050:
   4195                                     pC->AudioEncParams.Frequency =
   4196                                         M4ENCODER_k22050Hz;
   4197                                     break;
   4198 
   4199                                 case 24000:
   4200                                     pC->AudioEncParams.Frequency =
   4201                                         M4ENCODER_k24000Hz;
   4202                                     break;
   4203 
   4204                                 case 32000:
   4205                                     pC->AudioEncParams.Frequency =
   4206                                         M4ENCODER_k32000Hz;
   4207                                     break;
   4208 
   4209                                 case 44100:
   4210                                     pC->AudioEncParams.Frequency =
   4211                                         M4ENCODER_k44100Hz;
   4212                                     break;
   4213 
   4214                                 case 48000:
   4215                                     pC->AudioEncParams.Frequency =
   4216                                         M4ENCODER_k48000Hz;
   4217                                     break;
   4218 
   4219                                 default:
   4220                                     pC->AudioEncParams.Format = M4ENCODER_kAAC;
   4221                                     break;
   4222                             }
   4223                             /* unused */
   4224                             pC->AudioEncParams.SpecifParam.AacParam.bIS =
   4225                                 M4OSA_FALSE;
   4226                             pC->AudioEncParams.SpecifParam.AacParam.bMS =
   4227                                 M4OSA_FALSE;
   4228                             pC->AudioEncParams.SpecifParam.AacParam.bPNS =
   4229                                 M4OSA_FALSE;
   4230                             pC->AudioEncParams.SpecifParam.AacParam.bTNS =
   4231                                 M4OSA_FALSE;
   4232                             /* TODO change into highspeed asap */
   4233                             pC->AudioEncParams.SpecifParam.AacParam.bHighSpeed =
   4234                                 M4OSA_FALSE;
   4235                             break;
   4236 
   4237                         case M4VIDEOEDITING_kMP3:
   4238                             M4OSA_TRACE3_0(
   4239                                 "M4MCS_setOutputParams calling\
   4240                                 M4MCS_setCurrentAudioEncoder M4VIDEOEDITING_kNull, MP3");
   4241                             err = M4MCS_setCurrentAudioEncoder(pContext,
   4242                                 pC->InputFileProperties.AudioStreamType);
   4243                             M4ERR_CHECK_RETURN(err);
   4244 
   4245                             pC->AudioEncParams.Format = M4ENCODER_kMP3;
   4246                             pC->AudioEncParams.Frequency = M4ENCODER_k16000Hz;
   4247 
   4248                             switch( pC->pReaderAudioStream->
   4249                                 m_samplingFrequency )
   4250                             {
   4251                                 case 8000:
   4252                                     pC->AudioEncParams.Frequency =
   4253                                         M4ENCODER_k8000Hz;
   4254                                     break;
   4255 
   4256                                 case 16000:
   4257                                     pC->AudioEncParams.Frequency =
   4258                                         M4ENCODER_k16000Hz;
   4259                                     break;
   4260 
   4261                                 case 22050:
   4262                                     pC->AudioEncParams.Frequency =
   4263                                         M4ENCODER_k22050Hz;
   4264                                     break;
   4265 
   4266                                 case 24000:
   4267                                     pC->AudioEncParams.Frequency =
   4268                                         M4ENCODER_k24000Hz;
   4269                                     break;
   4270 
   4271                                 case 32000:
   4272                                     pC->AudioEncParams.Frequency =
   4273                                         M4ENCODER_k32000Hz;
   4274                                     break;
   4275 
   4276                                 case 44100:
   4277                                     pC->AudioEncParams.Frequency =
   4278                                         M4ENCODER_k44100Hz;
   4279                                     break;
   4280 
   4281                                 case 48000:
   4282                                     pC->AudioEncParams.Frequency =
   4283                                         M4ENCODER_k48000Hz;
   4284                                     break;
   4285 
   4286                                 default:
   4287                                     pC->AudioEncParams.Format = M4ENCODER_kMP3;
   4288                                     break;
   4289                             }
   4290                             break;
   4291 
   4292                         case M4VIDEOEDITING_kEVRC:
   4293                         case M4VIDEOEDITING_kUnsupportedAudio:
   4294                         default:
   4295                             M4OSA_TRACE1_1(
   4296                                 "M4MCS_setOutputParams: Output audio format (%d) is\
   4297                                 incompatible with audio effects, returning \
   4298                                 M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT",
   4299                                 pC->InputFileProperties.AudioStreamType);
   4300                             return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT;
   4301                         }
   4302                     }
   4303                     break;
   4304                     /* EVRC
   4305                     //            case M4VIDEOEDITING_kEVRC:
   4306                     //
   4307                     //                err = M4MCS_setCurrentAudioEncoder(pContext, pParams->\
   4308                     //                    OutputAudioFormat);
   4309                     //                M4ERR_CHECK_RETURN(err);
   4310                     //
   4311                     //                pC->AudioEncParams.Format = M4ENCODER_kEVRC;
   4312                     //                pC->AudioEncParams.Frequency = M4ENCODER_k8000Hz;
   4313                     //                pC->AudioEncParams.ChannelNum = M4ENCODER_kMono;
   4314                     //                break; */
   4315 
   4316                 default:
   4317                     M4OSA_TRACE1_1("M4MCS_setOutputParams: Undefined output audio format (%d),\
   4318                                    returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT",
   4319                                    pParams->OutputAudioFormat);
   4320                     return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT;
   4321         }
   4322     }
   4323 
   4324     if( pParams->pOutputPCMfile != M4OSA_NULL )
   4325     {
   4326         pC->pOutputPCMfile = pParams->pOutputPCMfile;
   4327 
   4328         /* Open output PCM file */
   4329         pC->pOsaFileWritPtr->openWrite(&(pC->pOutputPCMfile),
   4330             pParams->pOutputPCMfile, M4OSA_kFileWrite);
   4331     }
   4332     else
   4333     {
   4334         pC->pOutputPCMfile = M4OSA_NULL;
   4335     }
   4336 
   4337     /*Store media rendering parameter into the internal context*/
   4338     pC->MediaRendering = pParams->MediaRendering;
   4339 
   4340     /* Add audio effects*/
   4341     /*Copy MCS effects structure into internal context*/
   4342     if( pParams->nbEffects > 0 )
   4343     {
   4344         M4OSA_UInt32 j = 0;
   4345         pC->nbEffects = pParams->nbEffects;
   4346         pC->pEffects = (M4MCS_EffectSettings *)M4OSA_32bitAlignedMalloc(pC->nbEffects \
   4347             *sizeof(M4MCS_EffectSettings), M4MCS,
   4348             (M4OSA_Char *)"Allocation of effects list");
   4349 
   4350         if( pC->pEffects == M4OSA_NULL )
   4351         {
   4352             M4OSA_TRACE1_0("M4MCS_setOutputParams(): allocation error");
   4353             return M4ERR_ALLOC;
   4354         }
   4355 
   4356         for ( j = 0; j < pC->nbEffects; j++ )
   4357         {
   4358             /* Copy effect to "local" structure */
   4359             memcpy((void *) &(pC->pEffects[j]),
   4360                 (void *) &(pParams->pEffects[j]),
   4361                 sizeof(M4MCS_EffectSettings));
   4362 
   4363             switch( pC->pEffects[j].AudioEffectType )
   4364             {
   4365                 case M4MCS_kAudioEffectType_None:
   4366                     M4OSA_TRACE3_1(
   4367                         "M4MCS_setOutputParams(): effect type %i is None", j);
   4368                     pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL;
   4369                     pC->pEffects[j].ExtAudioEffectFct = M4OSA_NULL;
   4370                     break;
   4371 
   4372                 case M4MCS_kAudioEffectType_FadeIn:
   4373                     M4OSA_TRACE3_1(
   4374                         "M4MCS_setOutputParams(): effect type %i is FadeIn", j);
   4375                     pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL;
   4376                     pC->pEffects[j].ExtAudioEffectFct =
   4377                         M4MCS_editAudioEffectFct_FadeIn;
   4378                     break;
   4379 
   4380                 case M4MCS_kAudioEffectType_FadeOut:
   4381                     M4OSA_TRACE3_1(
   4382                         "M4MCS_setOutputParams(): effect type %i is FadeOut",
   4383                         j);
   4384                     pC->pEffects[j].pExtAudioEffectFctCtxt = M4OSA_NULL;
   4385                     pC->pEffects[j].ExtAudioEffectFct =
   4386                         M4MCS_editAudioEffectFct_FadeOut;
   4387                     break;
   4388 
   4389                 case M4MCS_kAudioEffectType_External:
   4390                     M4OSA_TRACE3_1(
   4391                         "M4MCS_setOutputParams(): effect type %i is External",
   4392                         j);
   4393 
   4394                     if( pParams->pEffects != M4OSA_NULL )
   4395                     {
   4396                         if( pParams->pEffects[j].ExtAudioEffectFct
   4397                             == M4OSA_NULL )
   4398                         {
   4399                             M4OSA_TRACE1_1("M4MCS_setOutputParams(): no external effect function\
   4400                                            associated to external effect number %i", j);
   4401                             return M4ERR_PARAMETER;
   4402                         }
   4403                         pC->pEffects[j].pExtAudioEffectFctCtxt =
   4404                             pParams->pEffects[j].pExtAudioEffectFctCtxt;
   4405 
   4406                         pC->pEffects[j].ExtAudioEffectFct =
   4407                             pParams->pEffects[j].ExtAudioEffectFct;
   4408                     }
   4409 
   4410                     break;
   4411 
   4412                 default:
   4413                     M4OSA_TRACE1_0(
   4414                         "M4MCS_setOutputParams(): effect type not recognized");
   4415                     return M4ERR_PARAMETER;
   4416             }
   4417         }
   4418     }
   4419     else
   4420     {
   4421         pC->nbEffects = 0;
   4422         pC->pEffects = M4OSA_NULL;
   4423     }
   4424 
   4425     /**
   4426     * Update state automaton */
   4427     pC->State = M4MCS_kState_SET;
   4428 
   4429     /**
   4430     * Return with no error */
   4431     M4OSA_TRACE3_0("M4MCS_setOutputParams(): returning M4NO_ERROR");
   4432     return M4NO_ERROR;
   4433 }
   4434 
   4435 /**
   4436  ******************************************************************************
   4437  * M4OSA_ERR M4MCS_setEncodingParams(M4MCS_Context pContext, M4MCS_EncodingParams* pRates)
   4438  * @brief   Set the values of the encoding parameters
   4439  * @note    Must be called before M4MCS_checkParamsAndStart().
   4440  * @param   pContext           (IN) MCS context
   4441  * @param   pRates             (IN) Transcoding parameters
   4442  * @return  M4NO_ERROR:         No error
   4443  * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
   4444  * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
   4445  * @return  M4MCS_ERR_AUDIOBITRATE_TOO_HIGH: Audio bitrate too high (we limit to 96 kbps)
   4446  * @return  M4MCS_ERR_AUDIOBITRATE_TOO_LOW: Audio bitrate is too low (16 kbps min for aac, 12.2
   4447  *                                            for amr, 8 for mp3)
   4448  * @return  M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: Begin cut and End cut are equals
   4449  * @return  M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION: Begin cut time is larger than the input clip
   4450  *                                                     duration
   4451  * @return  M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT: End cut time is smaller than begin cut time
   4452  * @return  M4MCS_ERR_MAXFILESIZE_TOO_SMALL: Not enough space to store whole output file at given
   4453  *                                             bitrates
   4454  * @return  M4MCS_ERR_VIDEOBITRATE_TOO_HIGH: Video bitrate too high (we limit to 800 kbps)
   4455  * @return  M4MCS_ERR_VIDEOBITRATE_TOO_LOW:  Video bitrate too low
   4456  ******************************************************************************
   4457  */
   4458 M4OSA_ERR M4MCS_setEncodingParams( M4MCS_Context pContext,
   4459                                   M4MCS_EncodingParams *pRates )
   4460 {
   4461     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
   4462     M4OSA_UInt32 j = 0;
   4463 
   4464     M4OSA_TRACE2_2(
   4465         "M4MCS_setEncodingParams called with pContext=0x%x, pRates=0x%x",
   4466         pContext, pRates);
   4467 
   4468     /**
   4469     * Check input parameters */
   4470     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
   4471         "M4MCS_setEncodingParams: pContext is M4OSA_NULL");
   4472     M4OSA_DEBUG_IF2((M4OSA_NULL == pRates), M4ERR_PARAMETER,
   4473         "M4MCS_setEncodingParams: pRates is M4OSA_NULL");
   4474 
   4475 #ifdef M4MCS_SUPPORT_STILL_PICTURE
   4476 
   4477     if( pC->m_bIsStillPicture )
   4478     {
   4479         /**
   4480         * Call the corresponding still picture MCS function*/
   4481         return M4MCS_stillPicSetEncodingParams(pC, pRates);
   4482     }
   4483 
   4484 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
   4485 
   4486     /**
   4487     * Check state automaton */
   4488 
   4489     if( M4MCS_kState_SET != pC->State )
   4490     {
   4491         M4OSA_TRACE1_1(
   4492             "M4MCS_setEncodingParams(): Wrong State (%d), returning M4ERR_STATE",
   4493             pC->State);
   4494         return M4ERR_STATE;
   4495     }
   4496 
   4497     /* Set given values */
   4498     pC->uiVideoBitrate = pRates->OutputVideoBitrate;
   4499     pC->uiAudioBitrate = pRates->OutputAudioBitrate;
   4500     pC->uiBeginCutTime = pRates->BeginCutTime;
   4501     pC->uiEndCutTime = pRates->EndCutTime;
   4502     pC->uiMaxFileSize = pRates->OutputFileSize;
   4503 
   4504     /**
   4505     * Check begin cut time validity */
   4506     if( pC->uiBeginCutTime >= pC->InputFileProperties.uiClipDuration )
   4507     {
   4508         M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin cut larger than duration (%d>%d),\
   4509                        returning M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION",
   4510                        pC->uiBeginCutTime, pC->InputFileProperties.uiClipDuration);
   4511         return M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION;
   4512     }
   4513 
   4514     /**
   4515     * If end cut time is too large, we set it to the clip duration */
   4516     if( pC->uiEndCutTime > pC->InputFileProperties.uiClipDuration )
   4517     {
   4518         pC->uiEndCutTime = pC->InputFileProperties.uiClipDuration;
   4519     }
   4520 
   4521     /**
   4522     * Check end cut time validity */
   4523     if( pC->uiEndCutTime > 0 )
   4524     {
   4525         if( pC->uiEndCutTime < pC->uiBeginCutTime )
   4526         {
   4527             M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin cut greater than end cut (%d,%d), \
   4528                            returning M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT",
   4529                            pC->uiBeginCutTime, pC->uiEndCutTime);
   4530             return M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT;
   4531         }
   4532 
   4533         if( pC->uiEndCutTime == pC->uiBeginCutTime )
   4534         {
   4535             M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Begin and End cuts are equal (%d,%d),\
   4536                            returning M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT",
   4537                            pC->uiBeginCutTime, pC->uiEndCutTime);
   4538             return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
   4539         }
   4540     }
   4541 
   4542     /**
   4543     * FlB 2009.03.04: check audio effects start time and duration validity*/
   4544     for ( j = 0; j < pC->nbEffects; j++ )
   4545     {
   4546         M4OSA_UInt32 outputEndCut = pC->uiEndCutTime;
   4547 
   4548         if( pC->uiEndCutTime == 0 )
   4549         {
   4550             outputEndCut = pC->InputFileProperties.uiClipDuration;
   4551         }
   4552 
   4553         if( pC->pEffects[j].uiStartTime > (outputEndCut - pC->uiBeginCutTime) )
   4554         {
   4555             M4OSA_TRACE1_2("M4MCS_setEncodingParams(): Effects start time is larger than\
   4556                            duration (%d,%d), returning M4ERR_PARAMETER",
   4557                            pC->pEffects[j].uiStartTime,
   4558                            (pC->uiEndCutTime - pC->uiBeginCutTime));
   4559             return M4ERR_PARAMETER;
   4560         }
   4561 
   4562         if( pC->pEffects[j].uiStartTime + pC->pEffects[j].uiDuration > \
   4563             (outputEndCut - pC->uiBeginCutTime) )
   4564         {
   4565             /* Re-adjust the effect duration until the end of the output clip*/
   4566             pC->pEffects[j].uiDuration = (outputEndCut - pC->uiBeginCutTime) - \
   4567                 pC->pEffects[j].uiStartTime;
   4568         }
   4569     }
   4570 
   4571     /* Check audio bitrate consistency */
   4572     if( ( pC->noaudio == M4OSA_FALSE)
   4573         && (pC->AudioEncParams.Format != M4ENCODER_kAudioNULL) )
   4574     {
   4575         if( pC->uiAudioBitrate != M4VIDEOEDITING_kUndefinedBitrate )
   4576         {
   4577             if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB )
   4578             {
   4579                 if( pC->uiAudioBitrate > M4VIDEOEDITING_k12_2_KBPS )
   4580                     return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
   4581 
   4582                 if( pC->uiAudioBitrate < M4VIDEOEDITING_k12_2_KBPS )
   4583                     return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
   4584             }
   4585             //EVRC
   4586             //            else if(pC->AudioEncParams.Format == M4ENCODER_kEVRC)
   4587             //            {
   4588             //                if(pC->uiAudioBitrate > M4VIDEOEDITING_k9_2_KBPS)
   4589             //                    return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
   4590             //                if(pC->uiAudioBitrate < M4VIDEOEDITING_k9_2_KBPS)
   4591             //                     return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
   4592             //            }
   4593             /*FlB 26.02.2009: add mp3 as mcs output format, add mp3 encoder*/
   4594             else if( pC->AudioEncParams.Format == M4ENCODER_kMP3 )
   4595             {
   4596                 if( pC->AudioEncParams.Frequency >= M4ENCODER_k32000Hz )
   4597                 {
   4598                     /*Mpeg layer 1*/
   4599                     if( pC->uiAudioBitrate > 320000 )
   4600                         return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
   4601 
   4602                     if( pC->uiAudioBitrate < 32000 )
   4603                         return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
   4604                 }
   4605                 else if( pC->AudioEncParams.Frequency >= M4ENCODER_k16000Hz )
   4606                 {
   4607                     /*Mpeg layer 2*/
   4608                     if( pC->uiAudioBitrate > 160000 )
   4609                         return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
   4610 
   4611                     if( ( pC->uiAudioBitrate < 8000
   4612                         && pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
   4613                         || (pC->uiAudioBitrate < 16000
   4614                         && pC->AudioEncParams.ChannelNum
   4615                         == M4ENCODER_kStereo) )
   4616                         return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
   4617                 }
   4618                 else if( pC->AudioEncParams.Frequency == M4ENCODER_k8000Hz
   4619                     || pC->AudioEncParams.Frequency == M4ENCODER_k11025Hz
   4620                     || pC->AudioEncParams.Frequency == M4ENCODER_k12000Hz )
   4621                 {
   4622                     /*Mpeg layer 2.5*/
   4623                     if( pC->uiAudioBitrate > 64000 )
   4624                         return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
   4625 
   4626                     if( ( pC->uiAudioBitrate < 8000
   4627                         && pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
   4628                         || (pC->uiAudioBitrate < 16000
   4629                         && pC->AudioEncParams.ChannelNum
   4630                         == M4ENCODER_kStereo) )
   4631                         return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
   4632                 }
   4633                 else
   4634                 {
   4635                     M4OSA_TRACE1_1("M4MCS_setEncodingParams: MP3 audio sampling frequency error\
   4636                                    (%d)", pC->AudioEncParams.Frequency);
   4637                     return M4ERR_PARAMETER;
   4638                 }
   4639             }
   4640             else
   4641             {
   4642                 if( pC->uiAudioBitrate > M4VIDEOEDITING_k192_KBPS )
   4643                     return M4MCS_ERR_AUDIOBITRATE_TOO_HIGH;
   4644 
   4645                 if( pC->AudioEncParams.ChannelNum == M4ENCODER_kMono )
   4646                 {
   4647                     if( pC->uiAudioBitrate < M4VIDEOEDITING_k16_KBPS )
   4648                         return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
   4649                 }
   4650                 else
   4651                 {
   4652                     if( pC->uiAudioBitrate < M4VIDEOEDITING_k32_KBPS )
   4653                         return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
   4654                 }
   4655             }
   4656         }
   4657     }
   4658     else
   4659     {
   4660         /* NULL audio : copy input file bitrate */
   4661         pC->uiAudioBitrate = pC->InputFileProperties.uiAudioBitrate;
   4662     }
   4663 
   4664     /* Check video bitrate consistency */
   4665     if( ( pC->novideo == M4OSA_FALSE)
   4666         && (pC->EncodingVideoFormat != M4ENCODER_kNULL) )
   4667     {
   4668         if( pC->uiVideoBitrate != M4VIDEOEDITING_kUndefinedBitrate )
   4669         {
   4670             if( pC->uiVideoBitrate > M4VIDEOEDITING_k8_MBPS )
   4671                 return M4MCS_ERR_VIDEOBITRATE_TOO_HIGH;
   4672 
   4673             if( pC->uiVideoBitrate < M4VIDEOEDITING_k16_KBPS )
   4674                 return M4MCS_ERR_VIDEOBITRATE_TOO_LOW;
   4675         }
   4676     }
   4677     else
   4678     {
   4679         /* NULL video : copy input file bitrate */
   4680         pC->uiVideoBitrate = pC->InputFileProperties.uiVideoBitrate;
   4681     }
   4682 
   4683     if( pRates->OutputVideoTimescale <= 30000
   4684         && pRates->OutputVideoTimescale > 0 )
   4685     {
   4686         pC->outputVideoTimescale = pRates->OutputVideoTimescale;
   4687     }
   4688 
   4689     /* Check file size */
   4690     return M4MCS_intCheckMaxFileSize(pC);
   4691 }
   4692 
   4693 /**
   4694  ******************************************************************************
   4695  * M4OSA_ERR M4MCS_getExtendedEncodingParams(M4MCS_Context pContext, M4MCS_EncodingParams* pRates)
   4696  * @brief   Get the extended values of the encoding parameters
   4697  * @note    Could be called after M4MCS_setEncodingParams.
   4698  * @param   pContext           (IN) MCS context
   4699  * @param   pRates             (OUT) Transcoding parameters
   4700  * @return  M4NO_ERROR:         No error
   4701  * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
   4702  * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
   4703  * @return  M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT: Encoding settings would produce a null duration
   4704  *                                             clip = encoding is impossible
   4705  ******************************************************************************
   4706  */
   4707 M4OSA_ERR M4MCS_getExtendedEncodingParams( M4MCS_Context pContext,
   4708                                           M4MCS_EncodingParams *pRates )
   4709 {
   4710     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
   4711 
   4712     M4OSA_Int32 minaudiobitrate;
   4713     M4OSA_Int32 minvideobitrate;
   4714     M4OSA_Int32 maxcombinedbitrate;
   4715 
   4716     M4OSA_Int32 calcbitrate;
   4717 
   4718     M4OSA_UInt32 maxduration;
   4719     M4OSA_UInt32 calcduration;
   4720 
   4721     M4OSA_Bool fixed_audio = M4OSA_FALSE;
   4722     M4OSA_Bool fixed_video = M4OSA_FALSE;
   4723 
   4724 #ifdef M4MCS_SUPPORT_STILL_PICTURE
   4725 
   4726     if( pC->m_bIsStillPicture )
   4727     {
   4728         /**
   4729         * Call the corresponding still picture MCS function*/
   4730         return M4MCS_stillPicGetExtendedEncodingParams(pC, pRates);
   4731     }
   4732 
   4733 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
   4734 
   4735     pRates->OutputVideoBitrate =
   4736         M4MCS_intGetNearestBitrate(pC->uiVideoBitrate, 0);
   4737     pRates->OutputAudioBitrate =
   4738         M4MCS_intGetNearestBitrate(pC->uiAudioBitrate, 0);
   4739     pRates->BeginCutTime = pC->uiBeginCutTime;
   4740     pRates->EndCutTime = pC->uiEndCutTime;
   4741     pRates->OutputFileSize = pC->uiMaxFileSize;
   4742 
   4743     /**
   4744     * Check state automaton */
   4745     if( M4MCS_kState_SET != pC->State )
   4746     {
   4747         M4OSA_TRACE1_1("M4MCS_getExtendedEncodingParams(): Wrong State (%d),\
   4748                        returning M4ERR_STATE", pC->State);
   4749         return M4ERR_STATE;
   4750     }
   4751 
   4752     /* Compute min audio bitrate */
   4753     if( pC->noaudio )
   4754     {
   4755         fixed_audio = M4OSA_TRUE;
   4756         pRates->OutputAudioBitrate = 0;
   4757         minaudiobitrate = 0;
   4758     }
   4759     else if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
   4760     {
   4761         fixed_audio = M4OSA_TRUE;
   4762         pRates->OutputAudioBitrate = pC->InputFileProperties.uiAudioBitrate;
   4763         minaudiobitrate = pC->InputFileProperties.uiAudioBitrate;
   4764     }
   4765     else
   4766     {
   4767         if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB )
   4768         {
   4769             fixed_audio = M4OSA_TRUE;
   4770             pRates->OutputAudioBitrate = M4VIDEOEDITING_k12_2_KBPS;
   4771             minaudiobitrate = M4VIDEOEDITING_k12_2_KBPS;
   4772         }
   4773         //EVRC
   4774         //        if(pC->AudioEncParams.Format == M4ENCODER_kEVRC)
   4775         //        {
   4776         //            fixed_audio = M4OSA_TRUE;
   4777         //            pRates->OutputAudioBitrate = M4VIDEOEDITING_k9_2_KBPS;
   4778         //            minaudiobitrate = M4VIDEOEDITING_k9_2_KBPS;
   4779         //        }
   4780         /*FlB 26.02.2009: add mp3 as mcs output format*/
   4781         else if( pC->AudioEncParams.Format == M4ENCODER_kMP3 )
   4782         {
   4783             minaudiobitrate =
   4784                 M4VIDEOEDITING_k32_KBPS; /*Default min audio bitrate for MPEG layer 1,
   4785                                              for both mono and stereo channels*/
   4786         }
   4787         else
   4788         {
   4789             minaudiobitrate = (pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
   4790                 ? M4VIDEOEDITING_k16_KBPS : M4VIDEOEDITING_k32_KBPS;
   4791         }
   4792     }
   4793 
   4794     /* Check audio bitrate is in the correct range */
   4795     if( fixed_audio == M4OSA_FALSE )
   4796     {
   4797         if( ( pC->uiAudioBitrate > 0)
   4798             && (pRates->OutputAudioBitrate < minaudiobitrate) )
   4799         {
   4800             pRates->OutputAudioBitrate = minaudiobitrate;
   4801         }
   4802 
   4803         if( pRates->OutputAudioBitrate > M4VIDEOEDITING_k96_KBPS )
   4804         {
   4805             pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS;
   4806         }
   4807     }
   4808 
   4809     /* Compute min video bitrate */
   4810     if( pC->novideo )
   4811     {
   4812         fixed_video = M4OSA_TRUE;
   4813         pRates->OutputVideoBitrate = 0;
   4814         minvideobitrate = 0;
   4815     }
   4816     else if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
   4817     {
   4818         fixed_video = M4OSA_TRUE;
   4819         pRates->OutputVideoBitrate = pC->InputFileProperties.uiVideoBitrate;
   4820         minvideobitrate = pC->InputFileProperties.uiVideoBitrate;
   4821     }
   4822     else
   4823     {
   4824         minvideobitrate = M4VIDEOEDITING_k16_KBPS;
   4825     }
   4826 
   4827     /* Check video bitrate is in the correct range */
   4828     if( fixed_video == M4OSA_FALSE )
   4829     {
   4830         if( ( pC->uiVideoBitrate > 0)
   4831             && (pRates->OutputVideoBitrate < minvideobitrate) )
   4832         {
   4833             pRates->OutputVideoBitrate = minvideobitrate;
   4834         }
   4835         /*+ New Encoder bitrates */
   4836         if( pRates->OutputVideoBitrate > M4VIDEOEDITING_k8_MBPS )
   4837         {
   4838             pRates->OutputVideoBitrate = M4VIDEOEDITING_k8_MBPS;
   4839         }
   4840         /*- New Encoder bitrates */
   4841     }
   4842 
   4843     /* Check cut times are in correct range */
   4844     if( ( pRates->BeginCutTime >= pC->InputFileProperties.uiClipDuration)
   4845         || (( pRates->BeginCutTime >= pRates->EndCutTime)
   4846         && (pRates->EndCutTime > 0)) )
   4847     {
   4848         pRates->BeginCutTime = 0;
   4849         pRates->EndCutTime = 0;
   4850     }
   4851 
   4852     if( pRates->EndCutTime == 0 )
   4853         calcduration =
   4854         pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime;
   4855     else
   4856         calcduration = pRates->EndCutTime - pRates->BeginCutTime;
   4857 
   4858     /* priority 1 : max file size */
   4859     if( pRates->OutputFileSize == 0 )
   4860     {
   4861         /* we can put maximum values for all undefined parameters */
   4862         if( pRates->EndCutTime == 0 )
   4863         {
   4864             pRates->EndCutTime = pC->InputFileProperties.uiClipDuration;
   4865         }
   4866 
   4867         if( ( pRates->OutputAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate)
   4868             && (fixed_audio == M4OSA_FALSE) )
   4869         {
   4870             pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS;
   4871         }
   4872 
   4873         if( ( pRates->OutputVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate)
   4874             && (fixed_video == M4OSA_FALSE) )
   4875         {
   4876             /*+ New Encoder bitrates */
   4877             pRates->OutputVideoBitrate = M4VIDEOEDITING_k8_MBPS;
   4878             /*- New Encoder bitrates */
   4879         }
   4880     }
   4881     else
   4882     {
   4883         /* compute max duration */
   4884         maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
   4885             / M4MCS_MOOV_OVER_FILESIZE_RATIO
   4886             / (minvideobitrate + minaudiobitrate) * 8000.0);
   4887 
   4888         if( maxduration
   4889             + pRates->BeginCutTime > pC->InputFileProperties.uiClipDuration )
   4890         {
   4891             maxduration =
   4892                 pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime;
   4893         }
   4894 
   4895         /* priority 2 : cut times */
   4896         if( ( pRates->BeginCutTime > 0) || (pRates->EndCutTime > 0) )
   4897         {
   4898             if( calcduration > maxduration )
   4899             {
   4900                 calcduration = maxduration;
   4901             }
   4902 
   4903             if( calcduration == 0 )
   4904             {
   4905                 return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
   4906             }
   4907 
   4908             maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize
   4909                 / M4MCS_MOOV_OVER_FILESIZE_RATIO / (calcduration / 8000.0));
   4910 
   4911             /* audio and video bitrates */
   4912             if( ( pRates->OutputAudioBitrate
   4913                 == M4VIDEOEDITING_kUndefinedBitrate)
   4914                 && (pRates->OutputVideoBitrate
   4915                 == M4VIDEOEDITING_kUndefinedBitrate) )
   4916             {
   4917                 /* set audio = 1/3 and video = 2/3 */
   4918                 if( fixed_audio == M4OSA_FALSE )
   4919                 {
   4920                     if( pC->novideo )
   4921                         pRates->OutputAudioBitrate =
   4922                         M4MCS_intGetNearestBitrate(maxcombinedbitrate, 0);
   4923                     else
   4924                         pRates->OutputAudioBitrate =
   4925                         M4MCS_intGetNearestBitrate(maxcombinedbitrate / 3,
   4926                         0);
   4927 
   4928                     if( pRates->OutputAudioBitrate < minaudiobitrate )
   4929                         pRates->OutputAudioBitrate = minaudiobitrate;
   4930 
   4931                     if( pRates->OutputAudioBitrate > M4VIDEOEDITING_k96_KBPS )
   4932                         pRates->OutputAudioBitrate = M4VIDEOEDITING_k96_KBPS;
   4933                 }
   4934 
   4935                 if( fixed_video == M4OSA_FALSE )
   4936                 {
   4937                     pRates->OutputVideoBitrate =
   4938                         M4MCS_intGetNearestBitrate(maxcombinedbitrate
   4939                         - pRates->OutputAudioBitrate, 0);
   4940 
   4941                     if( pRates->OutputVideoBitrate < minvideobitrate )
   4942                         pRates->OutputVideoBitrate = minvideobitrate;
   4943 
   4944                     if( pRates->OutputVideoBitrate > M4VIDEOEDITING_k8_MBPS )
   4945                         pRates->OutputVideoBitrate =
   4946                         M4VIDEOEDITING_k8_MBPS; /*+ New Encoder
   4947                                                 bitrates */
   4948                 }
   4949             }
   4950             else
   4951             {
   4952                 /* priority 3 : audio bitrate */
   4953                 if( pRates->OutputAudioBitrate
   4954                     != M4VIDEOEDITING_kUndefinedBitrate )
   4955                 {
   4956                     while( ( fixed_audio == M4OSA_FALSE)
   4957                         && (pRates->OutputAudioBitrate >= minaudiobitrate)
   4958                         && (pRates->OutputAudioBitrate
   4959                         + minvideobitrate > maxcombinedbitrate) )
   4960                     {
   4961                         pRates->OutputAudioBitrate =
   4962                             M4MCS_intGetNearestBitrate(
   4963                             pRates->OutputAudioBitrate, -1);
   4964                     }
   4965 
   4966                     if( ( fixed_audio == M4OSA_FALSE)
   4967                         && (pRates->OutputAudioBitrate < minaudiobitrate) )
   4968                     {
   4969                         pRates->OutputAudioBitrate = minaudiobitrate;
   4970                     }
   4971 
   4972                     calcbitrate = M4MCS_intGetNearestBitrate(
   4973                                     maxcombinedbitrate
   4974                                     - pRates->OutputAudioBitrate, 0);
   4975 
   4976                     if( calcbitrate < minvideobitrate )
   4977                         calcbitrate = minvideobitrate;
   4978 
   4979                     if( calcbitrate > M4VIDEOEDITING_k8_MBPS )
   4980                         calcbitrate = M4VIDEOEDITING_k8_MBPS;
   4981 
   4982                     if( ( fixed_video == M4OSA_FALSE)
   4983                         && (( pRates->OutputVideoBitrate
   4984                         == M4VIDEOEDITING_kUndefinedBitrate)
   4985                         || (pRates->OutputVideoBitrate > calcbitrate)) )
   4986                     {
   4987                         pRates->OutputVideoBitrate = calcbitrate;
   4988                     }
   4989                 }
   4990                 else
   4991                 {
   4992                     /* priority 4 : video bitrate */
   4993                     if( pRates->OutputVideoBitrate
   4994                         != M4VIDEOEDITING_kUndefinedBitrate )
   4995                     {
   4996                         while( ( fixed_video == M4OSA_FALSE)
   4997                             && (pRates->OutputVideoBitrate >= minvideobitrate)
   4998                             && (pRates->OutputVideoBitrate
   4999                             + minaudiobitrate > maxcombinedbitrate) )
   5000                         {
   5001                             pRates->OutputVideoBitrate =
   5002                                 M4MCS_intGetNearestBitrate(
   5003                                 pRates->OutputVideoBitrate, -1);
   5004                         }
   5005 
   5006                         if( ( fixed_video == M4OSA_FALSE)
   5007                             && (pRates->OutputVideoBitrate < minvideobitrate) )
   5008                         {
   5009                             pRates->OutputVideoBitrate = minvideobitrate;
   5010                         }
   5011 
   5012                         calcbitrate =
   5013                             M4MCS_intGetNearestBitrate(maxcombinedbitrate
   5014                             - pRates->OutputVideoBitrate, 0);
   5015 
   5016                         if( calcbitrate < minaudiobitrate )
   5017                             calcbitrate = minaudiobitrate;
   5018 
   5019                         if( calcbitrate > M4VIDEOEDITING_k96_KBPS )
   5020                             calcbitrate = M4VIDEOEDITING_k96_KBPS;
   5021 
   5022                         if( ( fixed_audio == M4OSA_FALSE)
   5023                             && (( pRates->OutputAudioBitrate
   5024                             == M4VIDEOEDITING_kUndefinedBitrate)
   5025                             || (pRates->OutputAudioBitrate > calcbitrate)) )
   5026                         {
   5027                             pRates->OutputAudioBitrate = calcbitrate;
   5028                         }
   5029                     }
   5030                 }
   5031             }
   5032         }
   5033         else
   5034         {
   5035             /* priority 3 : audio bitrate */
   5036             if( pRates->OutputAudioBitrate != M4VIDEOEDITING_kUndefinedBitrate )
   5037             {
   5038                 /* priority 4 : video bitrate */
   5039                 if( pRates->OutputVideoBitrate
   5040                     != M4VIDEOEDITING_kUndefinedBitrate )
   5041                 {
   5042                     /* compute max duration */
   5043                     maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
   5044                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
   5045                         / (pRates->OutputVideoBitrate
   5046                         + pRates->OutputAudioBitrate) * 8000.0);
   5047 
   5048                     if( maxduration + pRates->BeginCutTime
   5049                         > pC->InputFileProperties.uiClipDuration )
   5050                     {
   5051                         maxduration = pC->InputFileProperties.uiClipDuration
   5052                             - pRates->BeginCutTime;
   5053                     }
   5054 
   5055                     if( calcduration > maxduration )
   5056                     {
   5057                         calcduration = maxduration;
   5058                     }
   5059 
   5060                     if( calcduration == 0 )
   5061                     {
   5062                         return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
   5063                     }
   5064                 }
   5065                 else
   5066                 {
   5067                     /* start with min video bitrate */
   5068                     pRates->OutputVideoBitrate = minvideobitrate;
   5069 
   5070                     /* compute max duration */
   5071                     maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
   5072                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
   5073                         / (pRates->OutputVideoBitrate
   5074                         + pRates->OutputAudioBitrate) * 8000.0);
   5075 
   5076                     if( maxduration + pRates->BeginCutTime
   5077                         > pC->InputFileProperties.uiClipDuration )
   5078                     {
   5079                         maxduration = pC->InputFileProperties.uiClipDuration
   5080                             - pRates->BeginCutTime;
   5081                     }
   5082 
   5083                     if( calcduration > maxduration )
   5084                     {
   5085                         calcduration = maxduration;
   5086                     }
   5087 
   5088                     if( calcduration == 0 )
   5089                     {
   5090                         return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
   5091                     }
   5092 
   5093                     /* search max possible video bitrate */
   5094                     maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize
   5095                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
   5096                         / (calcduration / 8000.0));
   5097 
   5098                     while( ( fixed_video == M4OSA_FALSE)
   5099                         && (pRates->OutputVideoBitrate
   5100                         < M4VIDEOEDITING_k8_MBPS) ) /*+ New Encoder bitrates */
   5101                     {
   5102                         calcbitrate = M4MCS_intGetNearestBitrate(
   5103                             pRates->OutputVideoBitrate, +1);
   5104 
   5105                         if( calcbitrate
   5106                             + pRates->OutputAudioBitrate <= maxcombinedbitrate )
   5107                             pRates->OutputVideoBitrate = calcbitrate;
   5108                         else
   5109                             break;
   5110                     }
   5111                 }
   5112             }
   5113             else
   5114             {
   5115                 /* priority 4 : video bitrate */
   5116                 if( pRates->OutputVideoBitrate
   5117                     != M4VIDEOEDITING_kUndefinedBitrate )
   5118                 {
   5119                     /* start with min audio bitrate */
   5120                     pRates->OutputAudioBitrate = minaudiobitrate;
   5121 
   5122                     /* compute max duration */
   5123                     maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
   5124                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
   5125                         / (pRates->OutputVideoBitrate
   5126                         + pRates->OutputAudioBitrate) * 8000.0);
   5127 
   5128                     if( maxduration + pRates->BeginCutTime
   5129                         > pC->InputFileProperties.uiClipDuration )
   5130                     {
   5131                         maxduration = pC->InputFileProperties.uiClipDuration
   5132                             - pRates->BeginCutTime;
   5133                     }
   5134 
   5135                     if( calcduration > maxduration )
   5136                     {
   5137                         calcduration = maxduration;
   5138                     }
   5139 
   5140                     if( calcduration == 0 )
   5141                     {
   5142                         return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
   5143                     }
   5144 
   5145                     /* search max possible audio bitrate */
   5146                     maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize
   5147                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
   5148                         / (calcduration / 8000.0));
   5149 
   5150                     while( ( fixed_audio == M4OSA_FALSE)
   5151                         && (pRates->OutputAudioBitrate
   5152                         < M4VIDEOEDITING_k96_KBPS) )
   5153                     {
   5154                         calcbitrate = M4MCS_intGetNearestBitrate(
   5155                             pRates->OutputAudioBitrate, +1);
   5156 
   5157                         if( calcbitrate
   5158                             + pRates->OutputVideoBitrate <= maxcombinedbitrate )
   5159                             pRates->OutputAudioBitrate = calcbitrate;
   5160                         else
   5161                             break;
   5162                     }
   5163                 }
   5164                 else
   5165                 {
   5166                     /* compute max duration */
   5167                     maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
   5168                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
   5169                         / (minvideobitrate + minaudiobitrate) * 8000.0);
   5170 
   5171                     if( maxduration + pRates->BeginCutTime
   5172                         > pC->InputFileProperties.uiClipDuration )
   5173                     {
   5174                         maxduration = pC->InputFileProperties.uiClipDuration
   5175                             - pRates->BeginCutTime;
   5176                     }
   5177 
   5178                     if( calcduration > maxduration )
   5179                     {
   5180                         calcduration = maxduration;
   5181                     }
   5182 
   5183                     if( calcduration == 0 )
   5184                     {
   5185                         return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
   5186                     }
   5187 
   5188                     /* set audio = 1/3 and video = 2/3 */
   5189                     maxcombinedbitrate = (M4OSA_UInt32)(pRates->OutputFileSize
   5190                         / M4MCS_MOOV_OVER_FILESIZE_RATIO
   5191                         / (calcduration / 8000.0));
   5192 
   5193                     if( fixed_audio == M4OSA_FALSE )
   5194                     {
   5195                         if( pC->novideo )
   5196                             pRates->OutputAudioBitrate =
   5197                             M4MCS_intGetNearestBitrate(maxcombinedbitrate,
   5198                             0);
   5199                         else
   5200                             pRates->OutputAudioBitrate =
   5201                             M4MCS_intGetNearestBitrate(maxcombinedbitrate
   5202                             / 3, 0);
   5203 
   5204                         if( pRates->OutputAudioBitrate < minaudiobitrate )
   5205                             pRates->OutputAudioBitrate = minaudiobitrate;
   5206 
   5207                         if( pRates->OutputAudioBitrate
   5208                         > M4VIDEOEDITING_k96_KBPS )
   5209                         pRates->OutputAudioBitrate =
   5210                         M4VIDEOEDITING_k96_KBPS;
   5211                     }
   5212 
   5213                     if( fixed_video == M4OSA_FALSE )
   5214                     {
   5215                         pRates->OutputVideoBitrate =
   5216                             M4MCS_intGetNearestBitrate(maxcombinedbitrate
   5217                             - pRates->OutputAudioBitrate, 0);
   5218 
   5219                         if( pRates->OutputVideoBitrate < minvideobitrate )
   5220                             pRates->OutputVideoBitrate = minvideobitrate;
   5221 
   5222                         if( pRates->OutputVideoBitrate
   5223                         > M4VIDEOEDITING_k8_MBPS )
   5224                         pRates->OutputVideoBitrate =
   5225                         M4VIDEOEDITING_k8_MBPS; /*+ New Encoder
   5226                                                 bitrates */
   5227                     }
   5228                 }
   5229             }
   5230         }
   5231     }
   5232 
   5233     /* recompute max duration with final bitrates */
   5234     if( pRates->OutputFileSize > 0 )
   5235     {
   5236         maxduration = (M4OSA_UInt32)(pRates->OutputFileSize
   5237             / M4MCS_MOOV_OVER_FILESIZE_RATIO
   5238             / (pRates->OutputVideoBitrate + pRates->OutputAudioBitrate)
   5239             * 8000.0);
   5240     }
   5241     else
   5242     {
   5243         maxduration = pC->InputFileProperties.uiClipDuration;
   5244     }
   5245 
   5246     if( maxduration
   5247         + pRates->BeginCutTime > pC->InputFileProperties.uiClipDuration )
   5248     {
   5249         maxduration =
   5250             pC->InputFileProperties.uiClipDuration - pRates->BeginCutTime;
   5251     }
   5252 
   5253     if( pRates->EndCutTime == 0 )
   5254     {
   5255         pRates->EndCutTime = pRates->BeginCutTime + maxduration;
   5256     }
   5257     else
   5258     {
   5259         calcduration = pRates->EndCutTime - pRates->BeginCutTime;
   5260 
   5261         if( calcduration > maxduration )
   5262         {
   5263             pRates->EndCutTime = pRates->BeginCutTime + maxduration;
   5264         }
   5265     }
   5266 
   5267     /* Should never happen : constraints are too strong */
   5268     if( pRates->EndCutTime == pRates->BeginCutTime )
   5269     {
   5270         return M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT;
   5271     }
   5272 
   5273     /* estimated resulting file size */
   5274     pRates->OutputFileSize = (M4OSA_UInt32)(M4MCS_MOOV_OVER_FILESIZE_RATIO
   5275         * (pRates->OutputVideoBitrate + pRates->OutputAudioBitrate)
   5276         * (( pRates->EndCutTime - pRates->BeginCutTime) / 8000.0));
   5277 
   5278     return M4NO_ERROR;
   5279 }
   5280 
   5281 /**
   5282  ******************************************************************************
   5283  * M4OSA_ERR M4MCS_checkParamsAndStart(M4MCS_Context pContext)
   5284  * @brief   Check parameters to start
   5285  * @note
   5286  * @param   pContext           (IN) MCS context
   5287  * @return  M4NO_ERROR:         No error
   5288  * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
   5289  * @return  M4ERR_STATE:        MCS is not in an appropriate state for
   5290  *                              this function to be called
   5291  * @return  M4MCS_ERR_AUDIOBITRATE_TOO_HIGH:
   5292  *                              Audio bitrate too high (we limit to 96 kbps)
   5293  * @return  M4MCS_ERR_AUDIOBITRATE_TOO_LOW:
   5294  *                              Audio bitrate is too low (16 kbps min for aac,
   5295  *                              12.2 for amr, 8 for mp3)
   5296  * @return  M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT:
   5297  *                              Begin cut and End cut are equals
   5298  * @return  M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION:
   5299  *                              Begin cut time is larger than the input
   5300  *                              clip duration
   5301  * @return  M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT:
   5302  *                              End cut time is smaller than begin cut time
   5303  * @return  M4MCS_ERR_MAXFILESIZE_TOO_SMALL:
   5304  *                              Not enough space to store whole output
   5305  *                              file at given bitrates
   5306  * @return  M4MCS_ERR_VIDEOBITRATE_TOO_HIGH:
   5307  *                              Video bitrate too high (we limit to 800 kbps)
   5308  * @return  M4MCS_ERR_VIDEOBITRATE_TOO_LOW:
   5309  *                              Video bitrate too low
   5310  ******************************************************************************
   5311  */
   5312 M4OSA_ERR M4MCS_checkParamsAndStart( M4MCS_Context pContext )
   5313 {
   5314     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
   5315     M4MCS_EncodingParams VerifyRates;
   5316     M4OSA_ERR err;
   5317 
   5318     /**
   5319     * Check input parameters */
   5320     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
   5321         "M4MCS_checkParamsAndStart: pContext is M4OSA_NULL");
   5322 
   5323 #ifdef M4MCS_SUPPORT_STILL_PICTURE
   5324 
   5325     if( pC->m_bIsStillPicture )
   5326     {
   5327         /**
   5328         * Call the corresponding still picture MCS function*/
   5329         return M4MCS_stillPicCheckParamsAndStart(pC);
   5330     }
   5331 
   5332 #endif /*M4MCS_SUPPORT_STILL_PICTURE*/
   5333 
   5334     /**
   5335     * Check state automaton */
   5336 
   5337     if( M4MCS_kState_SET != pC->State )
   5338     {
   5339         M4OSA_TRACE1_1(
   5340             "M4MCS_checkParamsAndStart(): Wrong State (%d), returning M4ERR_STATE",
   5341             pC->State);
   5342         return M4ERR_STATE;
   5343     }
   5344 
   5345     /* Audio bitrate should not stay undefined at this point */
   5346     if( ( pC->noaudio == M4OSA_FALSE)
   5347         && (pC->AudioEncParams.Format != M4ENCODER_kAudioNULL)
   5348         && (pC->uiAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate) )
   5349     {
   5350         M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : undefined audio bitrate");
   5351         return M4MCS_ERR_AUDIOBITRATE_TOO_LOW;
   5352     }
   5353 
   5354     /* Video bitrate should not stay undefined at this point */
   5355     if( ( pC->novideo == M4OSA_FALSE)
   5356         && (pC->EncodingVideoFormat != M4ENCODER_kNULL)
   5357         && (pC->uiVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate) )
   5358     {
   5359         M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : undefined video bitrate");
   5360         return M4MCS_ERR_VIDEOBITRATE_TOO_LOW;
   5361     }
   5362 
   5363     /* Set end cut time if necessary (not an error) */
   5364     if( pC->uiEndCutTime == 0 )
   5365     {
   5366         pC->uiEndCutTime = pC->InputFileProperties.uiClipDuration;
   5367     }
   5368 
   5369     /* Force a re-set to check validity of parameters */
   5370     VerifyRates.OutputVideoBitrate = pC->uiVideoBitrate;
   5371     VerifyRates.OutputAudioBitrate = pC->uiAudioBitrate;
   5372     VerifyRates.BeginCutTime = pC->uiBeginCutTime;
   5373     VerifyRates.EndCutTime = pC->uiEndCutTime;
   5374     VerifyRates.OutputFileSize = pC->uiMaxFileSize;
   5375     VerifyRates.OutputVideoTimescale = pC->outputVideoTimescale;
   5376 
   5377     err = M4MCS_setEncodingParams(pContext, &VerifyRates);
   5378 
   5379     /**
   5380     * Check parameters consistency */
   5381     if( err != M4NO_ERROR )
   5382     {
   5383         M4OSA_TRACE1_0("M4MCS_checkParamsAndStart : invalid parameter found");
   5384         return err;
   5385     }
   5386 
   5387     /**
   5388     * All is OK : update state automaton */
   5389     pC->uiEncVideoBitrate = pC->uiVideoBitrate;
   5390     pC->AudioEncParams.Bitrate = pC->uiAudioBitrate;
   5391 
   5392 #ifdef M4MCS_WITH_FAST_OPEN
   5393     /**
   5394     * Remake the open if it was done in fast mode */
   5395 
   5396     if( M4OSA_TRUE == pC->bFileOpenedInFastMode )
   5397     {
   5398         /* Close the file opened in fast mode */
   5399         M4MCS_intCleanUp_ReadersDecoders(pC);
   5400 
   5401         pC->State = M4MCS_kState_CREATED;
   5402 
   5403         /* Reopen it in normal mode */
   5404         err = M4MCS_open(pContext, pC->pInputFile, pC->InputFileType,
   5405             pC->pOutputFile, pC->pTemporaryFile);
   5406 
   5407         if( err != M4NO_ERROR )
   5408         {
   5409             M4OSA_TRACE1_1(
   5410                 "M4MCS_checkParamsAndStart : M4MCS_Open returns 0x%x", err);
   5411             return err;
   5412         }
   5413     }
   5414 
   5415 #endif /* M4MCS_WITH_FAST_OPEN */
   5416 
   5417     pC->State = M4MCS_kState_READY;
   5418 
   5419     return M4NO_ERROR;
   5420 }
   5421 
   5422 /**
   5423  ******************************************************************************
   5424  * M4OSA_ERR M4MCS_intStepSet(M4MCS_InternalContext* pC)
   5425  ******************************************************************************
   5426  */
   5427 static M4OSA_ERR M4MCS_intStepSet( M4MCS_InternalContext *pC )
   5428 {
   5429     M4OSA_ERR err;
   5430     M4ENCODER_Header *encHeader;
   5431 
   5432     /**
   5433     * Prepare the video decoder */
   5434     err = M4MCS_intPrepareVideoDecoder(pC);
   5435 
   5436     if( M4NO_ERROR != err )
   5437     {
   5438         M4OSA_TRACE1_1(
   5439             "M4MCS_intStepSet(): M4MCS_intPrepareVideoDecoder() returns 0x%x",
   5440             err);
   5441         return err;
   5442     }
   5443 
   5444     if( ( pC->InputFileProperties.VideoStreamType == M4VIDEOEDITING_kH264)
   5445         && (pC->EncodingVideoFormat == M4ENCODER_kNULL) )
   5446     {
   5447         pC->bH264Trim = M4OSA_TRUE;
   5448     }
   5449 
   5450     /**
   5451     * Prepare the video encoder */
   5452     err = M4MCS_intPrepareVideoEncoder(pC);
   5453 
   5454     if( M4NO_ERROR != err )
   5455     {
   5456         M4OSA_TRACE1_1(
   5457             "M4MCS_intStepSet(): M4MCS_intPrepareVideoEncoder() returns 0x%x",
   5458             err);
   5459         return err;
   5460     }
   5461 
   5462     if( ( pC->uiBeginCutTime != 0)
   5463         && (pC->InputFileProperties.VideoStreamType == M4VIDEOEDITING_kH264)
   5464         && (pC->EncodingVideoFormat == M4ENCODER_kNULL) )
   5465     {
   5466 
   5467         err = pC->pVideoEncoderGlobalFcts->pFctSetOption(pC->pViEncCtxt,
   5468             M4ENCODER_kOptionID_H264ProcessNALUContext,
   5469             (M4OSA_DataOption)pC->m_pInstance);
   5470 
   5471         if( err != M4NO_ERROR )
   5472         {
   5473             M4OSA_TRACE1_1("M4MCS_intStetSet :pFctSetOption failed  (err 0x%x)",
   5474                 err);
   5475             return err;
   5476         }
   5477 
   5478         err = pC->pVideoEncoderGlobalFcts->pFctSetOption(pC->pViEncCtxt,
   5479             M4ENCODER_kOptionID_SetH264ProcessNALUfctsPtr,
   5480             (M4OSA_DataOption) &H264MCS_ProcessEncodedNALU);
   5481 
   5482         if( err != M4NO_ERROR )
   5483         {
   5484             M4OSA_TRACE1_1("M4MCS_intStetSet :pFctSetOption failed  (err 0x%x)",
   5485                 err);
   5486             return err;
   5487         }
   5488 
   5489         err = pC->pVideoEncoderGlobalFcts->pFctGetOption(pC->pViEncCtxt,
   5490             M4ENCODER_kOptionID_EncoderHeader,
   5491             (M4OSA_DataOption) &encHeader);
   5492 
   5493         if( ( M4NO_ERROR != err) || (M4OSA_NULL == encHeader->pBuf) )
   5494         {
   5495             M4OSA_TRACE1_1(
   5496                 "M4MCS_close: failed to get the encoder header (err 0x%x)",
   5497                 err);
   5498             /**< no return here, we still have stuff to deallocate after close, even if it fails.*/
   5499         }
   5500         else
   5501         {
   5502             // Handle DSI first bits
   5503 #define SPS_START_POS 6
   5504 
   5505             pC->m_pInstance->m_encoderSPSSize =
   5506                 ( encHeader->pBuf[SPS_START_POS] << 8)
   5507                 + encHeader->pBuf[SPS_START_POS + 1];
   5508             pC->m_pInstance->m_pEncoderSPS =
   5509                 (M4OSA_UInt8 *)(encHeader->pBuf) + SPS_START_POS + 2;
   5510 
   5511             pC->m_pInstance->m_encoderPPSSize =
   5512                 ( encHeader->pBuf[SPS_START_POS + 3
   5513                 + pC->m_pInstance->m_encoderSPSSize] << 8)
   5514                 + encHeader->pBuf[SPS_START_POS + 4
   5515                 + pC->m_pInstance->m_encoderSPSSize];
   5516             pC->m_pInstance->m_pEncoderPPS = (M4OSA_UInt8 *)encHeader->pBuf + SPS_START_POS + 5
   5517                 + pC->m_pInstance->m_encoderSPSSize;
   5518 
   5519             /* Check the DSI integrity */
   5520             if( encHeader->Size != (pC->m_pInstance->m_encoderSPSSize
   5521                 + pC->m_pInstance->m_encoderPPSSize + 5 + SPS_START_POS) )
   5522             {
   5523                 M4OSA_TRACE1_3(
   5524                     "!!! M4MCS_intStepSet ERROR : invalid SPS / PPS %d %d %d",
   5525                     encHeader->Size, pC->m_pInstance->m_encoderSPSSize,
   5526                     pC->m_pInstance->m_encoderPPSSize);
   5527                 return M4ERR_PARAMETER;
   5528             }
   5529         }
   5530     }
   5531 
   5532     /**
   5533     * Prepare audio processing */
   5534     err = M4MCS_intPrepareAudioProcessing(pC);
   5535 
   5536     if( M4NO_ERROR != err )
   5537     {
   5538         M4OSA_TRACE1_1(
   5539             "M4MCS_intStepSet(): M4MCS_intPrepareAudioProcessing() returns 0x%x",
   5540             err);
   5541         return err;
   5542     }
   5543 
   5544     /**
   5545     * Prepare the writer */
   5546     err = M4MCS_intPrepareWriter(pC);
   5547 
   5548     if( M4NO_ERROR != err )
   5549     {
   5550         M4OSA_TRACE1_1(
   5551             "M4MCS_intStepSet(): M4MCS_intPrepareWriter() returns 0x%x", err);
   5552         return err;
   5553     }
   5554 
   5555     /**
   5556     * Jump the audio stream to the begin cut time (all AUs are RAP)
   5557     * Must be done after the 3gpp writer init, because it may write the first
   5558     * audio AU in some cases */
   5559     err = M4MCS_intPrepareAudioBeginCut(pC);
   5560 
   5561     if( M4NO_ERROR != err )
   5562     {
   5563         M4OSA_TRACE1_1(
   5564             "M4MCS_intStepSet(): M4MCS_intPrepareAudioBeginCut() returns 0x%x",
   5565             err);
   5566         return err;
   5567     }
   5568 
   5569     /**
   5570     * Update state automaton */
   5571     if( 0 == pC->uiBeginCutTime )
   5572     {
   5573         pC->dViDecStartingCts = 0.0;
   5574         /**
   5575         * No begin cut, do the encoding */
   5576         pC->State = M4MCS_kState_PROCESSING;
   5577     }
   5578     else
   5579     {
   5580         /**
   5581         * Remember that we must start the decode/encode process at the begin cut time */
   5582         pC->dViDecStartingCts = (M4OSA_Double)pC->uiBeginCutTime;
   5583 
   5584         /**
   5585         * Jumping */
   5586         pC->State = M4MCS_kState_BEGINVIDEOJUMP;
   5587     }
   5588 
   5589     /**
   5590     * Return with no error */
   5591     M4OSA_TRACE3_0("M4MCS_intStepSet(): returning M4NO_ERROR");
   5592     return M4NO_ERROR;
   5593 }
   5594 
   5595 /**
   5596  ******************************************************************************
   5597  * M4OSA_ERR M4MCS_intPrepareVideoDecoder(M4MCS_InternalContext* pC);
   5598  * @brief    Prepare the video decoder.
   5599  * @param    pC          (IN) MCS private context
   5600  * @return   M4NO_ERROR  No error
   5601  * @return   M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED
   5602  * @return   Any error returned by an underlaying module
   5603  ******************************************************************************
   5604  */
   5605 static M4OSA_ERR M4MCS_intPrepareVideoDecoder( M4MCS_InternalContext *pC )
   5606 {
   5607     M4OSA_ERR err;
   5608     M4OSA_Void *decoderUserData;
   5609     M4DECODER_OutputFilter FilterOption;
   5610 
   5611     if( pC->novideo )
   5612         return M4NO_ERROR;
   5613 
   5614     /**
   5615     * Create the decoder, if it has not been created yet (to get video properties for example) */
   5616     if( M4OSA_NULL == pC->pViDecCtxt )
   5617     {
   5618 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
   5619 
   5620         decoderUserData = pC->m_pCurrentVideoDecoderUserData;
   5621 
   5622 #else
   5623 
   5624         decoderUserData = M4OSA_NULL;
   5625 
   5626 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS ? */
   5627 
   5628         err = pC->m_pVideoDecoder->m_pFctCreate(&pC->pViDecCtxt,
   5629             &pC->pReaderVideoStream->m_basicProperties, pC->m_pReader,
   5630             pC->m_pReaderDataIt, &pC->ReaderVideoAU, decoderUserData);
   5631 
   5632         if( (M4OSA_UInt32)(M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED) == err )
   5633         {
   5634             /**
   5635             * Our decoder is not compatible with H263 profile other than 0.
   5636             * So it returns this internal error code.
   5637             * We translate it to our own error code */
   5638             M4OSA_TRACE1_0("M4MCS_intPrepareVideoDecoder:\
   5639                            returning M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED");
   5640             return M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED;
   5641         }
   5642         else if( M4NO_ERROR != err )
   5643         {
   5644             M4OSA_TRACE1_1("M4MCS_intPrepareVideoDecoder:\
   5645                            m_pVideoDecoder->m_pFctCreate returns 0x%x", err);
   5646             return err;
   5647         }
   5648 
   5649         if( M4VIDEOEDITING_kH264 == pC->InputFileProperties.VideoStreamType )
   5650         {
   5651             FilterOption.m_pFilterFunction =
   5652                 (M4OSA_Void *) &M4VIFI_ResizeBilinearYUV420toYUV420;
   5653             FilterOption.m_pFilterUserData = M4OSA_NULL;
   5654             err = pC->m_pVideoDecoder->m_pFctSetOption(pC->pViDecCtxt,
   5655                 M4DECODER_kOptionID_OutputFilter,
   5656                 (M4OSA_DataOption) &FilterOption);
   5657 
   5658             if( M4NO_ERROR != err )
   5659             {
   5660                 M4OSA_TRACE1_1("M4MCS_intPrepareVideoDecoder:\
   5661                                m_pVideoDecoder->m_pFctSetOption returns 0x%x", err);
   5662                 return err;
   5663             }
   5664         }
   5665     }
   5666 
   5667     /**
   5668     * Return with no error */
   5669     M4OSA_TRACE3_0("M4MCS_intPrepareVideoDecoder(): returning M4NO_ERROR");
   5670     return M4NO_ERROR;
   5671 }
   5672 
   5673 /**
   5674  ******************************************************************************
   5675  * M4OSA_ERR M4MCS_intPrepareVideoEncoder(M4MCS_InternalContext* pC);
   5676  * @brief    Prepare the video encoder.
   5677  * @param    pC          (IN) MCS private context
   5678  * @return   M4NO_ERROR  No error
   5679  * @return   Any error returned by an underlaying module
   5680  ******************************************************************************
   5681  */
   5682 static M4OSA_ERR M4MCS_intPrepareVideoEncoder( M4MCS_InternalContext *pC )
   5683 {
   5684     M4OSA_ERR err;
   5685     M4ENCODER_AdvancedParams EncParams; /**< Encoder advanced parameters */
   5686     M4ENCODER_Params EncParams1;
   5687     M4OSA_Double dFrameRate;            /**< tmp variable */
   5688 
   5689     if( pC->novideo )
   5690         return M4NO_ERROR;
   5691 
   5692     if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
   5693     {
   5694         /* Approximative cts increment */
   5695         pC->dCtsIncrement = 1000.0 / pC->pReaderVideoStream->m_averageFrameRate;
   5696 
   5697         if( pC->uiBeginCutTime == 0 )
   5698         {
   5699             M4OSA_TRACE3_0(
   5700                 "M4MCS_intPrepareVideoEncoder(): Null encoding, do nothing.");
   5701             return M4NO_ERROR;
   5702         }
   5703         else
   5704         {
   5705             M4OSA_TRACE3_0(
   5706                 "M4MCS_intPrepareVideoEncoder(): Null encoding, I-frame defaults.");
   5707 
   5708             /* Set useful parameters to encode the first I-frame */
   5709             EncParams.InputFormat = M4ENCODER_kIYUV420;
   5710             EncParams.videoProfile = pC->encodingVideoProfile;
   5711             EncParams.videoLevel= pC->encodingVideoLevel;
   5712 
   5713             switch( pC->InputFileProperties.VideoStreamType )
   5714             {
   5715                 case M4VIDEOEDITING_kH263:
   5716                     EncParams.Format = M4ENCODER_kH263;
   5717                     break;
   5718 
   5719                 case M4VIDEOEDITING_kMPEG4:
   5720                     EncParams.Format = M4ENCODER_kMPEG4;
   5721                     break;
   5722 
   5723                 case M4VIDEOEDITING_kH264:
   5724                     EncParams.Format = M4ENCODER_kH264;
   5725                     break;
   5726 
   5727                 default:
   5728                     M4OSA_TRACE1_1("M4MCS_intPrepareVideoEncoder: unknown encoding video format\
   5729                                    (%d), returning M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED",
   5730                                    pC->InputFileProperties.VideoStreamType);
   5731                     return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
   5732             }
   5733 
   5734             EncParams.FrameWidth = pC->EncodingWidth;
   5735             EncParams.FrameHeight = pC->EncodingHeight;
   5736             EncParams.Bitrate = pC->uiEncVideoBitrate;
   5737             EncParams.bInternalRegulation =
   5738                 M4OSA_FALSE; /* do not constrain the I-frame */
   5739             EncParams.FrameRate = pC->EncodingVideoFramerate;
   5740 
   5741             /* Other encoding settings (quite all dummy...) */
   5742             EncParams.uiHorizontalSearchRange = 0;    /* use default */
   5743             EncParams.uiVerticalSearchRange = 0;      /* use default */
   5744             EncParams.bErrorResilience = M4OSA_FALSE; /* no error resilience */
   5745             EncParams.uiIVopPeriod = 0;               /* use default */
   5746             EncParams.uiMotionEstimationTools =
   5747                 0; /* M4V_MOTION_EST_TOOLS_ALL */
   5748             EncParams.bAcPrediction = M4OSA_TRUE;     /* use AC prediction */
   5749             EncParams.uiStartingQuantizerValue = 5;   /* initial QP = 5 */
   5750             EncParams.bDataPartitioning =
   5751                 M4OSA_FALSE; /* no data partitioning */
   5752 
   5753             /* Rate factor */
   5754             EncParams.uiTimeScale = pC->InputFileProperties.uiVideoTimeScale;
   5755             EncParams.uiRateFactor = 1;
   5756         }
   5757     }
   5758     else
   5759     {
   5760         M4OSA_TRACE3_0(
   5761             "M4MCS_intPrepareVideoEncoder(): Normal encoding, set full config.");
   5762 
   5763         /**
   5764         * Set encoder shell parameters according to MCS settings */
   5765         EncParams.Format = pC->EncodingVideoFormat;
   5766         EncParams.InputFormat = M4ENCODER_kIYUV420;
   5767         EncParams.videoProfile = pC->encodingVideoProfile;
   5768         EncParams.videoLevel= pC->encodingVideoLevel;
   5769 
   5770         /**
   5771         * Video frame size */
   5772         EncParams.FrameWidth = pC->EncodingWidth;
   5773         EncParams.FrameHeight = pC->EncodingHeight;
   5774 
   5775         /**
   5776         * Video bitrate has been previously computed */
   5777         EncParams.Bitrate = pC->uiEncVideoBitrate;
   5778 
   5779         /**
   5780         * MCS use the "true" core internal bitrate regulation */
   5781         EncParams.bInternalRegulation = M4OSA_TRUE;
   5782 
   5783         /**
   5784         * Other encoder settings */
   5785 
   5786         EncParams.uiHorizontalSearchRange = 0;    /* use default */
   5787         EncParams.uiVerticalSearchRange = 0;      /* use default */
   5788         EncParams.bErrorResilience = M4OSA_FALSE; /* no error resilience */
   5789         EncParams.uiIVopPeriod = 0;               /* use default */
   5790         EncParams.uiMotionEstimationTools =
   5791             0; /* M4V_MOTION_EST_TOOLS_ALL */
   5792         EncParams.bAcPrediction = M4OSA_TRUE;     /* use AC prediction */
   5793         EncParams.uiStartingQuantizerValue = 10;  /* initial QP = 10 */
   5794         EncParams.bDataPartitioning =
   5795             M4OSA_FALSE; /* no data partitioning */
   5796 
   5797 
   5798         /**
   5799         * Video encoder frame rate and rate factor */
   5800         EncParams.FrameRate = pC->EncodingVideoFramerate;
   5801         EncParams.uiTimeScale = pC->outputVideoTimescale;
   5802 
   5803         switch( pC->EncodingVideoFramerate )
   5804         {
   5805             case M4ENCODER_k5_FPS:
   5806                 dFrameRate = 5.0;
   5807                 break;
   5808 
   5809             case M4ENCODER_k7_5_FPS:
   5810                 dFrameRate = 7.5;
   5811                 break;
   5812 
   5813             case M4ENCODER_k10_FPS:
   5814                 dFrameRate = 10.0;
   5815                 break;
   5816 
   5817             case M4ENCODER_k12_5_FPS:
   5818                 dFrameRate = 12.5;
   5819                 break;
   5820 
   5821             case M4ENCODER_k15_FPS:
   5822                 dFrameRate = 15.0;
   5823                 break;
   5824 
   5825             case M4ENCODER_k20_FPS: /**< MPEG-4 only */
   5826                 dFrameRate = 20.0;
   5827                 break;
   5828 
   5829             case M4ENCODER_k25_FPS: /**< MPEG-4 only */
   5830                 dFrameRate = 25.0;
   5831                 break;
   5832 
   5833             case M4ENCODER_k30_FPS:
   5834                 dFrameRate = 30.0;
   5835                 break;
   5836 
   5837             default:
   5838                 M4OSA_TRACE1_1(
   5839                     "M4MCS_intPrepareVideoEncoder: unknown encoding video frame rate\
   5840                     (0x%x), returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE",
   5841                     pC->EncodingVideoFramerate);
   5842                 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE;
   5843         }
   5844 
   5845         /**
   5846         * Compute the number of milliseconds between two frames */
   5847         if( M4ENCODER_kH263 == EncParams.Format )
   5848         {
   5849             pC->dCtsIncrement = 1001.0 / dFrameRate;
   5850         }
   5851         else /**< MPEG4 or H.264 */
   5852         {
   5853             pC->dCtsIncrement = 1000.0 / dFrameRate;
   5854         }
   5855     }
   5856 
   5857     /**
   5858      * Limit the video bitrate according to encoder profile
   5859      * and level */
   5860     err = M4MCS_intLimitBitratePerCodecProfileLevel(&EncParams);
   5861     if (M4NO_ERROR != err) {
   5862         M4OSA_TRACE1_1(
   5863             "M4MCS_intPrepareVideoEncoder: limit bitrate returned err \
   5864              0x%x", err);
   5865         return err;
   5866     }
   5867 
   5868     /**
   5869     * Create video encoder */
   5870     err = pC->pVideoEncoderGlobalFcts->pFctInit(&pC->pViEncCtxt,
   5871         pC->pWriterDataFcts, \
   5872         M4MCS_intApplyVPP, pC, pC->pCurrentVideoEncoderExternalAPI, \
   5873         pC->pCurrentVideoEncoderUserData);
   5874 
   5875     /**< We put the MCS context in place of the VPP context */
   5876     if( M4NO_ERROR != err )
   5877     {
   5878         M4OSA_TRACE1_1(
   5879             "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctInit returns 0x%x",
   5880             err);
   5881         return err;
   5882     }
   5883 
   5884     pC->encoderState = M4MCS_kEncoderClosed;
   5885 
   5886     if( M4OSA_TRUE == pC->bH264Trim )
   5887         //if((M4ENCODER_kNULL == pC->EncodingVideoFormat)
   5888         //    && (M4VIDEOEDITING_kH264 == pC->InputFileProperties.VideoStreamType))
   5889     {
   5890         EncParams1.InputFormat = EncParams.InputFormat;
   5891         //EncParams1.InputFrameWidth = EncParams.InputFrameWidth;
   5892         //EncParams1.InputFrameHeight = EncParams.InputFrameHeight;
   5893         EncParams1.FrameWidth = EncParams.FrameWidth;
   5894         EncParams1.FrameHeight = EncParams.FrameHeight;
   5895         EncParams1.videoProfile= EncParams.videoProfile;
   5896         EncParams1.videoLevel= EncParams.videoLevel;
   5897         EncParams1.Bitrate = EncParams.Bitrate;
   5898         EncParams1.FrameRate = EncParams.FrameRate;
   5899         EncParams1.Format = M4ENCODER_kH264; //EncParams.Format;
   5900         M4OSA_TRACE1_2("mcs encoder open profile :%d, level %d",
   5901             EncParams1.videoProfile, EncParams1.videoLevel);
   5902         err = pC->pVideoEncoderGlobalFcts->pFctOpen(pC->pViEncCtxt,
   5903             &pC->WriterVideoAU, &EncParams1);
   5904     }
   5905     else
   5906     {
   5907         M4OSA_TRACE1_2("mcs encoder open Adv profile :%d, level %d",
   5908             EncParams.videoProfile, EncParams.videoLevel);
   5909         err = pC->pVideoEncoderGlobalFcts->pFctOpen(pC->pViEncCtxt,
   5910             &pC->WriterVideoAU, &EncParams);
   5911     }
   5912 
   5913     if( M4NO_ERROR != err )
   5914     {
   5915         M4OSA_TRACE1_1(
   5916             "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctOpen returns 0x%x",
   5917             err);
   5918         return err;
   5919     }
   5920 
   5921     pC->encoderState = M4MCS_kEncoderStopped;
   5922 
   5923     if( M4OSA_NULL != pC->pVideoEncoderGlobalFcts->pFctStart )
   5924     {
   5925         err = pC->pVideoEncoderGlobalFcts->pFctStart(pC->pViEncCtxt);
   5926 
   5927         if( M4NO_ERROR != err )
   5928         {
   5929             M4OSA_TRACE1_1(
   5930                 "M4MCS_intPrepareVideoEncoder: EncoderInt->pFctStart returns 0x%x",
   5931                 err);
   5932             return err;
   5933         }
   5934     }
   5935 
   5936     pC->encoderState = M4MCS_kEncoderRunning;
   5937 
   5938     /******************************/
   5939     /* Video resize management    */
   5940     /******************************/
   5941     /**
   5942     * Compare video input size and video output size to check if resize is needed */
   5943     if( ( (M4OSA_UInt32)EncParams.FrameWidth
   5944         != pC->pReaderVideoStream->m_videoWidth)
   5945         || ((M4OSA_UInt32)EncParams.FrameHeight
   5946         != pC->pReaderVideoStream->m_videoHeight) )
   5947     {
   5948         /**
   5949         * Allocate the intermediate video plane that will receive the decoded image before
   5950          resizing */
   5951         pC->pPreResizeFrame =
   5952             (M4VIFI_ImagePlane *)M4OSA_32bitAlignedMalloc(3 * sizeof(M4VIFI_ImagePlane),
   5953             M4MCS, (M4OSA_Char *)"m_pPreResizeFrame");
   5954 
   5955         if( M4OSA_NULL == pC->pPreResizeFrame )
   5956         {
   5957             M4OSA_TRACE1_0("M4MCS_intPrepareVideoEncoder():\
   5958                            unable to allocate m_pPreResizeFrame, returning M4ERR_ALLOC");
   5959             return M4ERR_ALLOC;
   5960         }
   5961 
   5962         pC->pPreResizeFrame[0].pac_data = M4OSA_NULL;
   5963         pC->pPreResizeFrame[1].pac_data = M4OSA_NULL;
   5964         pC->pPreResizeFrame[2].pac_data = M4OSA_NULL;
   5965 
   5966         /**
   5967         * Allocate the Y plane */
   5968         pC->pPreResizeFrame[0].u_topleft = 0;
   5969         pC->pPreResizeFrame[0].u_width = pC->pReaderVideoStream->
   5970             m_videoWidth; /**< input width */
   5971         pC->pPreResizeFrame[0].u_height = pC->pReaderVideoStream->
   5972             m_videoHeight; /**< input height */
   5973         pC->pPreResizeFrame[0].u_stride = pC->
   5974             pPreResizeFrame[0].u_width; /**< simple case: stride equals width */
   5975 
   5976         pC->pPreResizeFrame[0].pac_data =
   5977             (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[0].u_stride \
   5978             *pC->pPreResizeFrame[0].u_height, M4MCS,
   5979             (M4OSA_Char *)"m_pPreResizeFrame[0].pac_data");
   5980 
   5981         if( M4OSA_NULL == pC->pPreResizeFrame[0].pac_data )
   5982         {
   5983             M4OSA_TRACE1_0(
   5984                 "M4MCS_intPrepareVideoEncoder():\
   5985                      unable to allocate m_pPreResizeFrame[0].pac_data, returning M4ERR_ALLOC");
   5986             return M4ERR_ALLOC;
   5987         }
   5988 
   5989         /**
   5990         * Allocate the U plane */
   5991         pC->pPreResizeFrame[1].u_topleft = 0;
   5992         pC->pPreResizeFrame[1].u_width = pC->pPreResizeFrame[0].u_width
   5993             >> 1; /**< U width is half the Y width */
   5994         pC->pPreResizeFrame[1].u_height = pC->pPreResizeFrame[0].u_height
   5995             >> 1; /**< U height is half the Y height */
   5996         pC->pPreResizeFrame[1].u_stride = pC->
   5997             pPreResizeFrame[1].u_width; /**< simple case: stride equals width */
   5998 
   5999         pC->pPreResizeFrame[1].pac_data =
   6000             (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[1].u_stride \
   6001             *pC->pPreResizeFrame[1].u_height, M4MCS,
   6002             (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data");
   6003 
   6004         if( M4OSA_NULL == pC->pPreResizeFrame[1].pac_data )
   6005         {
   6006             M4OSA_TRACE1_0(
   6007                 "M4MCS_intPrepareVideoEncoder():\
   6008                  unable to allocate m_pPreResizeFrame[1].pac_data, returning M4ERR_ALLOC");
   6009             return M4ERR_ALLOC;
   6010         }
   6011 
   6012         /**
   6013         * Allocate the V plane */
   6014         pC->pPreResizeFrame[2].u_topleft = 0;
   6015         pC->pPreResizeFrame[2].u_width = pC->
   6016             pPreResizeFrame[1].u_width; /**< V width equals U width */
   6017         pC->pPreResizeFrame[2].u_height = pC->
   6018             pPreResizeFrame[1].u_height; /**< V height equals U height */
   6019         pC->pPreResizeFrame[2].u_stride = pC->
   6020             pPreResizeFrame[2].u_width; /**< simple case: stride equals width */
   6021 
   6022         pC->pPreResizeFrame[2].pac_data =
   6023             (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(pC->pPreResizeFrame[2].u_stride \
   6024             *pC->pPreResizeFrame[2].u_height, M4MCS,
   6025             (M4OSA_Char *)"m_pPreResizeFrame[1].pac_data");
   6026 
   6027         if( M4OSA_NULL == pC->pPreResizeFrame[2].pac_data )
   6028         {
   6029             M4OSA_TRACE1_0(
   6030                 "M4MCS_intPrepareVideoEncoder():\
   6031                  unable to allocate m_pPreResizeFrame[2].pac_data, returning M4ERR_ALLOC");
   6032             return M4ERR_ALLOC;
   6033         }
   6034     }
   6035 
   6036     /**
   6037     * Return with no error */
   6038     M4OSA_TRACE3_0("M4MCS_intPrepareVideoEncoder(): returning M4NO_ERROR");
   6039     return M4NO_ERROR;
   6040 }
   6041 
   6042 /**
   6043  ******************************************************************************
   6044  * M4OSA_ERR M4MCS_intPrepareAudioProcessing(M4MCS_InternalContext* pC);
   6045  * @brief    Prepare the AAC decoder, the SRC and the AMR-NB encoder and the MP3 encoder.
   6046  * @param    pC          (IN) MCS private context
   6047  * @return   M4NO_ERROR  No error
   6048  * @return   Any error returned by an underlaying module
   6049  ******************************************************************************
   6050  */
   6051 static M4OSA_ERR M4MCS_intPrepareAudioProcessing( M4MCS_InternalContext *pC )
   6052 {
   6053     M4OSA_ERR err;
   6054 
   6055     SSRC_ReturnStatus_en
   6056         ReturnStatus; /* Function return status                       */
   6057     LVM_INT16 NrSamplesMin =
   6058         0; /* Minimal number of samples on the input or on the output */
   6059     LVM_INT32 ScratchSize; /* The size of the scratch memory               */
   6060     LVM_INT16
   6061         *pInputInScratch; /* Pointer to input in the scratch buffer       */
   6062     LVM_INT16
   6063         *pOutputInScratch; /* Pointer to the output in the scratch buffer  */
   6064     SSRC_Params_t ssrcParams;          /* Memory for init parameters                    */
   6065 
   6066 #ifdef MCS_DUMP_PCM_TO_FILE
   6067 
   6068     file_au_reader = fopen("mcs_ReaderOutput.raw", "wb");
   6069     file_pcm_decoder = fopen("mcs_DecoderOutput.pcm", "wb");
   6070     file_pcm_encoder = fopen("mcs_EncoderInput.pcm", "wb");
   6071 
   6072 #endif
   6073 
   6074     if( pC->noaudio )
   6075         return M4NO_ERROR;
   6076 
   6077     if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
   6078     {
   6079         M4OSA_TRACE3_0(
   6080             "M4MCS_intPrepareAudioProcessing(): Null encoding, do nothing.");
   6081         return M4NO_ERROR;
   6082     }
   6083 
   6084     /* ________________________________ */
   6085     /*|                                |*/
   6086     /*| Create and "start" the decoder |*/
   6087     /*|________________________________|*/
   6088 
   6089     if( M4OSA_NULL == pC->m_pAudioDecoder )
   6090     {
   6091         M4OSA_TRACE1_0(
   6092             "M4MCS_intPrepareAudioProcessing(): Fails to initiate the audio decoder.");
   6093         return M4MCS_ERR_AUDIO_CONVERSION_FAILED;
   6094     }
   6095 
   6096     if( M4OSA_NULL == pC->pAudioDecCtxt )
   6097     {
   6098         err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(&pC->pAudioDecCtxt,
   6099             pC->pReaderAudioStream, pC->m_pCurrentAudioDecoderUserData);
   6100 
   6101         if( M4NO_ERROR != err )
   6102         {
   6103             M4OSA_TRACE1_1(
   6104                 "M4MCS_intPrepareVideoDecoder: m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x",
   6105                 err);
   6106             return err;
   6107         }
   6108     }
   6109 
   6110     if( M4VIDEOEDITING_kAMR_NB == pC->InputFileProperties.AudioStreamType ) {
   6111         /* AMR DECODER CONFIGURATION */
   6112 
   6113         /* nothing specific to do */
   6114     }
   6115     else if( M4VIDEOEDITING_kEVRC == pC->InputFileProperties.AudioStreamType ) {
   6116         /* EVRC DECODER CONFIGURATION */
   6117 
   6118         /* nothing specific to do */
   6119     }
   6120     else if( M4VIDEOEDITING_kMP3 == pC->InputFileProperties.AudioStreamType ) {
   6121         /* MP3 DECODER CONFIGURATION */
   6122 
   6123         /* nothing specific to do */
   6124     }
   6125     else
   6126     {
   6127         /* AAC DECODER CONFIGURATION */
   6128         M4_AacDecoderConfig AacDecParam;
   6129 
   6130         AacDecParam.m_AACDecoderProfile = AAC_kAAC;
   6131         AacDecParam.m_DownSamplingMode = AAC_kDS_OFF;
   6132 
   6133         if( pC->AudioEncParams.Format == M4ENCODER_kAMRNB )
   6134         {
   6135             AacDecParam.m_OutputMode = AAC_kMono;
   6136         }
   6137         else
   6138         {
   6139             /* For this version, we encode only in AAC */
   6140             if( M4ENCODER_kMono == pC->AudioEncParams.ChannelNum )
   6141             {
   6142                 AacDecParam.m_OutputMode = AAC_kMono;
   6143             }
   6144             else
   6145             {
   6146                 AacDecParam.m_OutputMode = AAC_kStereo;
   6147             }
   6148         }
   6149 
   6150         pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
   6151             M4AD_kOptionID_UserParam, (M4OSA_DataOption) &AacDecParam);
   6152     }
   6153 
   6154     pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
   6155            M4AD_kOptionID_3gpReaderInterface, (M4OSA_DataOption) pC->m_pReaderDataIt);
   6156 
   6157     pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
   6158            M4AD_kOptionID_AudioAU, (M4OSA_DataOption) &pC->ReaderAudioAU);
   6159 
   6160     if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL )
   6161     {
   6162         /* Not implemented in all decoders */
   6163         err = pC->m_pAudioDecoder->m_pFctStartAudioDec(pC->pAudioDecCtxt);
   6164 
   6165         if( M4NO_ERROR != err )
   6166         {
   6167             M4OSA_TRACE1_1(
   6168                 "M4MCS_intPrepareVideoDecoder: m_pAudioDecoder->m_pFctStartAudioDec returns 0x%x",
   6169                 err);
   6170             return err;
   6171         }
   6172     }
   6173 
   6174     /**
   6175     * Allocate output buffer for the audio decoder */
   6176     pC->InputFileProperties.uiDecodedPcmSize =
   6177         pC->pReaderAudioStream->m_byteFrameLength
   6178         * pC->pReaderAudioStream->m_byteSampleSize
   6179         * pC->pReaderAudioStream->m_nbChannels;
   6180 
   6181     if( pC->InputFileProperties.uiDecodedPcmSize > 0 )
   6182     {
   6183         pC->AudioDecBufferOut.m_bufferSize =
   6184             pC->InputFileProperties.uiDecodedPcmSize;
   6185         pC->AudioDecBufferOut.m_dataAddress =
   6186             (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->AudioDecBufferOut.m_bufferSize \
   6187             *sizeof(short), M4MCS, (M4OSA_Char *)"AudioDecBufferOut.m_bufferSize");
   6188     }
   6189 
   6190     if( M4OSA_NULL == pC->AudioDecBufferOut.m_dataAddress )
   6191     {
   6192         M4OSA_TRACE1_0(
   6193             "M4MCS_intPrepareVideoDecoder():\
   6194              unable to allocate AudioDecBufferOut.m_dataAddress, returning M4ERR_ALLOC");
   6195         return M4ERR_ALLOC;
   6196     }
   6197 
   6198     /* _________________________ */
   6199     /*|                         |*/
   6200     /*| Set the SSRC parameters |*/
   6201     /*|_________________________|*/
   6202 
   6203     switch( pC->pReaderAudioStream->m_samplingFrequency )
   6204     {
   6205         case 8000:
   6206             ssrcParams.SSRC_Fs_In = LVM_FS_8000;
   6207             break;
   6208 
   6209         case 11025:
   6210             ssrcParams.SSRC_Fs_In = LVM_FS_11025;
   6211             break;
   6212 
   6213         case 12000:
   6214             ssrcParams.SSRC_Fs_In = LVM_FS_12000;
   6215             break;
   6216 
   6217         case 16000:
   6218             ssrcParams.SSRC_Fs_In = LVM_FS_16000;
   6219             break;
   6220 
   6221         case 22050:
   6222             ssrcParams.SSRC_Fs_In = LVM_FS_22050;
   6223             break;
   6224 
   6225         case 24000:
   6226             ssrcParams.SSRC_Fs_In = LVM_FS_24000;
   6227             break;
   6228 
   6229         case 32000:
   6230             ssrcParams.SSRC_Fs_In = LVM_FS_32000;
   6231             break;
   6232 
   6233         case 44100:
   6234             ssrcParams.SSRC_Fs_In = LVM_FS_44100;
   6235             break;
   6236 
   6237         case 48000:
   6238             ssrcParams.SSRC_Fs_In = LVM_FS_48000;
   6239             break;
   6240 
   6241         default:
   6242             M4OSA_TRACE1_1(
   6243                 "M4MCS_intPrepareVideoDecoder: invalid input AAC sampling frequency (%d Hz),\
   6244                  returning M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY",
   6245                 pC->pReaderAudioStream->m_samplingFrequency);
   6246             return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY;
   6247     }
   6248 
   6249     if( 1 == pC->pReaderAudioStream->m_nbChannels )
   6250     {
   6251         ssrcParams.SSRC_NrOfChannels = LVM_MONO;
   6252     }
   6253     else
   6254     {
   6255         ssrcParams.SSRC_NrOfChannels = LVM_STEREO;
   6256     }
   6257 
   6258     /*FlB 26.02.2009: add mp3 as output format*/
   6259     if( pC->AudioEncParams.Format == M4ENCODER_kAAC
   6260         || pC->AudioEncParams.Format == M4ENCODER_kMP3 )
   6261     {
   6262         switch( pC->AudioEncParams.Frequency )
   6263         {
   6264             case M4ENCODER_k8000Hz:
   6265                 ssrcParams.SSRC_Fs_Out = LVM_FS_8000;
   6266                 break;
   6267 
   6268             case M4ENCODER_k11025Hz:
   6269                 ssrcParams.SSRC_Fs_Out = LVM_FS_11025;
   6270                 break;
   6271 
   6272             case M4ENCODER_k12000Hz:
   6273                 ssrcParams.SSRC_Fs_Out = LVM_FS_12000;
   6274                 break;
   6275 
   6276             case M4ENCODER_k16000Hz:
   6277                 ssrcParams.SSRC_Fs_Out = LVM_FS_16000;
   6278                 break;
   6279 
   6280             case M4ENCODER_k22050Hz:
   6281                 ssrcParams.SSRC_Fs_Out = LVM_FS_22050;
   6282                 break;
   6283 
   6284             case M4ENCODER_k24000Hz:
   6285                 ssrcParams.SSRC_Fs_Out = LVM_FS_24000;
   6286                 break;
   6287 
   6288             case M4ENCODER_k32000Hz:
   6289                 ssrcParams.SSRC_Fs_Out = LVM_FS_32000;
   6290                 break;
   6291 
   6292             case M4ENCODER_k44100Hz:
   6293                 ssrcParams.SSRC_Fs_Out = LVM_FS_44100;
   6294                 break;
   6295 
   6296             case M4ENCODER_k48000Hz:
   6297                 ssrcParams.SSRC_Fs_Out = LVM_FS_48000;
   6298                 break;
   6299 
   6300             default:
   6301                 M4OSA_TRACE1_1(
   6302                     "M4MCS_intPrepareAudioProcessing: invalid output AAC sampling frequency \
   6303                     (%d Hz), returning M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY",
   6304                     pC->AudioEncParams.Frequency);
   6305                 return M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY;
   6306                 break;
   6307         }
   6308     }
   6309     else
   6310     {
   6311         ssrcParams.SSRC_Fs_Out = LVM_FS_8000;
   6312     }
   6313 
   6314 
   6315 
   6316     ReturnStatus = 0;
   6317 
   6318     switch( ssrcParams.SSRC_Fs_In )
   6319     {
   6320         case LVM_FS_8000:
   6321             ssrcParams.NrSamplesIn = 320;
   6322             break;
   6323 
   6324         case LVM_FS_11025:
   6325             ssrcParams.NrSamplesIn = 441;
   6326             break;
   6327 
   6328         case LVM_FS_12000:
   6329             ssrcParams.NrSamplesIn = 480;
   6330             break;
   6331 
   6332         case LVM_FS_16000:
   6333             ssrcParams.NrSamplesIn = 640;
   6334             break;
   6335 
   6336         case LVM_FS_22050:
   6337             ssrcParams.NrSamplesIn = 882;
   6338             break;
   6339 
   6340         case LVM_FS_24000:
   6341             ssrcParams.NrSamplesIn = 960;
   6342             break;
   6343 
   6344         case LVM_FS_32000:
   6345             ssrcParams.NrSamplesIn = 1280;
   6346             break;
   6347 
   6348         case LVM_FS_44100:
   6349             ssrcParams.NrSamplesIn = 1764;
   6350             break;
   6351 
   6352         case LVM_FS_48000:
   6353             ssrcParams.NrSamplesIn = 1920;
   6354             break;
   6355 
   6356         default:
   6357             ReturnStatus = -1;
   6358             break;
   6359     }
   6360 
   6361     switch( ssrcParams.SSRC_Fs_Out )
   6362     {
   6363         case LVM_FS_8000:
   6364             ssrcParams.NrSamplesOut = 320;
   6365             break;
   6366 
   6367         case LVM_FS_11025:
   6368             ssrcParams.NrSamplesOut = 441;
   6369             break;
   6370 
   6371         case LVM_FS_12000:
   6372             ssrcParams.NrSamplesOut = 480;
   6373             break;
   6374 
   6375         case LVM_FS_16000:
   6376             ssrcParams.NrSamplesOut = 640;
   6377             break;
   6378 
   6379         case LVM_FS_22050:
   6380             ssrcParams.NrSamplesOut = 882;
   6381             break;
   6382 
   6383         case LVM_FS_24000:
   6384             ssrcParams.NrSamplesOut = 960;
   6385             break;
   6386 
   6387         case LVM_FS_32000:
   6388             ssrcParams.NrSamplesOut = 1280;
   6389             break;
   6390 
   6391         case LVM_FS_44100:
   6392             ssrcParams.NrSamplesOut = 1764;
   6393             break;
   6394 
   6395         case LVM_FS_48000:
   6396             ssrcParams.NrSamplesOut = 1920;
   6397             break;
   6398 
   6399         default:
   6400             ReturnStatus = -1;
   6401             break;
   6402     }
   6403 
   6404 
   6405 
   6406     if( ReturnStatus != SSRC_OK )
   6407     {
   6408         M4OSA_TRACE1_1(
   6409             "M4MCS_intPrepareAudioProcessing:\
   6410              Error code %d returned by the SSRC_GetNrSamples function",
   6411             ReturnStatus);
   6412         return M4MCS_ERR_AUDIO_CONVERSION_FAILED;
   6413     }
   6414 
   6415     NrSamplesMin =
   6416         (LVM_INT16)((ssrcParams.NrSamplesIn > ssrcParams.NrSamplesOut)
   6417         ? ssrcParams.NrSamplesOut : ssrcParams.NrSamplesIn);
   6418 
   6419     while( NrSamplesMin < M4MCS_SSRC_MINBLOCKSIZE )
   6420     { /* Don't take blocks smaller that the minimal block size */
   6421         ssrcParams.NrSamplesIn = (LVM_INT16)(ssrcParams.NrSamplesIn << 1);
   6422         ssrcParams.NrSamplesOut = (LVM_INT16)(ssrcParams.NrSamplesOut << 1);
   6423         NrSamplesMin = (LVM_INT16)(NrSamplesMin << 1);
   6424     }
   6425 
   6426 
   6427     pC->iSsrcNbSamplIn = (LVM_INT16)(
   6428         ssrcParams.
   6429         NrSamplesIn); /* multiplication by NrOfChannels is done below */
   6430     pC->iSsrcNbSamplOut = (LVM_INT16)(ssrcParams.NrSamplesOut);
   6431 
   6432     /**
   6433     * Allocate buffer for the input of the SSRC */
   6434     pC->pSsrcBufferIn =
   6435         (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->iSsrcNbSamplIn * sizeof(short) \
   6436         *pC->pReaderAudioStream->m_nbChannels, M4MCS,
   6437         (M4OSA_Char *)"pSsrcBufferIn");
   6438 
   6439     if( M4OSA_NULL == pC->pSsrcBufferIn )
   6440     {
   6441         M4OSA_TRACE1_0(
   6442             "M4MCS_intPrepareVideoDecoder():\
   6443              unable to allocate pSsrcBufferIn, returning M4ERR_ALLOC");
   6444         return M4ERR_ALLOC;
   6445     }
   6446     pC->pPosInSsrcBufferIn = (M4OSA_MemAddr8)pC->pSsrcBufferIn;
   6447 
   6448     /**
   6449     * Allocate buffer for the output of the SSRC */
   6450     pC->pSsrcBufferOut =
   6451         (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->iSsrcNbSamplOut * sizeof(short) \
   6452         *pC->pReaderAudioStream->m_nbChannels, M4MCS,
   6453         (M4OSA_Char *)"pSsrcBufferOut");
   6454 
   6455     if( M4OSA_NULL == pC->pSsrcBufferOut )
   6456     {
   6457         M4OSA_TRACE1_0(
   6458             "M4MCS_intPrepareVideoDecoder():\
   6459              unable to allocate pSsrcBufferOut, returning M4ERR_ALLOC");
   6460         return M4ERR_ALLOC;
   6461     }
   6462 
   6463 
   6464     pC->pLVAudioResampler = LVAudioResamplerCreate(
   6465         16, /*gInputParams.lvBTChannelCount*/
   6466         (M4OSA_Int16)pC->InputFileProperties.uiNbChannels/*ssrcParams.SSRC_NrOfChannels*/,
   6467         (M4OSA_Int32)(pC->AudioEncParams.Frequency)/*ssrcParams.SSRC_Fs_Out*/, 1);
   6468 
   6469      if( M4OSA_NULL == pC->pLVAudioResampler)
   6470      {
   6471          return M4ERR_ALLOC;
   6472      }
   6473 
   6474     LVAudiosetSampleRate(pC->pLVAudioResampler,
   6475         /*gInputParams.lvInSampleRate*/
   6476         /*pC->pAddedClipCtxt->pSettings->ClipProperties.uiSamplingFrequency*/
   6477         pC->InputFileProperties.uiSamplingFrequency/*ssrcParams.SSRC_Fs_In*/);
   6478 
   6479     LVAudiosetVolume(pC->pLVAudioResampler, (M4OSA_Int16)(0x1000 /* 0x7fff */),
   6480         (M4OSA_Int16)(0x1000/*0x7fff*/));
   6481 
   6482 
   6483     /* ________________________ */
   6484     /*|                        |*/
   6485     /*| Init the audio encoder |*/
   6486     /*|________________________|*/
   6487 
   6488     /* Initialise the audio encoder */
   6489 
   6490     err = pC->pAudioEncoderGlobalFcts->pFctInit(&pC->pAudioEncCtxt,
   6491         pC->pCurrentAudioEncoderUserData);
   6492 
   6493     if( M4NO_ERROR != err )
   6494     {
   6495         M4OSA_TRACE1_1(
   6496             "M4MCS_intPrepareAudioProcessing: pAudioEncoderGlobalFcts->pFctInit returns 0x%x",
   6497             err);
   6498         return err;
   6499     }
   6500 
   6501     /* Open the audio encoder */
   6502     err = pC->pAudioEncoderGlobalFcts->pFctOpen(pC->pAudioEncCtxt,
   6503         &pC->AudioEncParams, &pC->pAudioEncDSI,
   6504         M4OSA_NULL /* no grabbing */);
   6505 
   6506     if( M4NO_ERROR != err )
   6507     {
   6508         M4OSA_TRACE1_1(
   6509             "M4MCS_intPrepareAudioProcessing: pAudioEncoderGlobalFcts->pFctOpen returns 0x%x",
   6510             err);
   6511         return err;
   6512     }
   6513 
   6514     /* Allocate the input buffer for the audio encoder */
   6515     switch( pC->AudioEncParams.Format )
   6516     {
   6517         case M4ENCODER_kAMRNB:
   6518             pC->audioEncoderGranularity = M4MCS_PCM_AMR_GRANULARITY_SAMPLES;
   6519             break;
   6520 
   6521         case M4ENCODER_kAAC:
   6522             pC->audioEncoderGranularity = M4MCS_PCM_AAC_GRANULARITY_SAMPLES;
   6523             break;
   6524 
   6525             /*FlB 26.02.2009: add mp3 as output format*/
   6526         case M4ENCODER_kMP3:
   6527             pC->audioEncoderGranularity = M4MCS_PCM_MP3_GRANULARITY_SAMPLES;
   6528             break;
   6529 
   6530          default:
   6531          break;
   6532     }
   6533 
   6534     if( M4ENCODER_kMono == pC->AudioEncParams.ChannelNum )
   6535         pC->audioEncoderGranularity *= sizeof(short);
   6536     else
   6537         pC->audioEncoderGranularity *= sizeof(short) * 2;
   6538 
   6539     pC->pPosInAudioEncoderBuffer = M4OSA_NULL;
   6540     pC->pAudioEncoderBuffer =
   6541         (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->audioEncoderGranularity, M4MCS,
   6542         (M4OSA_Char *)"pC->pAudioEncoderBuffer");
   6543 
   6544     /**
   6545     * Return with no error */
   6546     M4OSA_TRACE3_0("M4MCS_intPrepareAudioProcessing(): returning M4NO_ERROR");
   6547     return M4NO_ERROR;
   6548 }
   6549 
   6550 /**
   6551  ******************************************************************************
   6552  * M4OSA_ERR M4MCS_intPrepareWriter(M4MCS_InternalContext* pC);
   6553  * @brief    Prepare the writer.
   6554  * @param    pC          (IN) MCS private context
   6555  * @return   M4NO_ERROR  No error
   6556  * @return   Any error returned by an underlaying module
   6557  ******************************************************************************
   6558  */
   6559 static M4OSA_ERR M4MCS_intPrepareWriter( M4MCS_InternalContext *pC )
   6560 {
   6561     M4OSA_ERR err;
   6562     M4OSA_UInt32 uiVersion; /**< To write component version in 3gp writer */
   6563     M4OSA_MemAddr8 pDSI = M4OSA_NULL; /**< To create the Decoder Specific Info */
   6564     M4SYS_StreamIDValue optionValue; /**< For the setoption calls */
   6565     M4OSA_UInt32 TargetedFileSize;
   6566     M4OSA_Bool bMULPPSSPS = M4OSA_FALSE;
   6567 
   6568     /**
   6569     * Init the writer */
   6570     err = pC->pWriterGlobalFcts->pFctOpen(&pC->pWriterContext, pC->pOutputFile,
   6571         pC->pOsaFileWritPtr, pC->pTemporaryFile, pC->pOsaFileReadPtr);
   6572 
   6573     if( M4NO_ERROR != err )
   6574     {
   6575         M4OSA_TRACE1_1(
   6576             "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctOpen returns 0x%x",
   6577             err);
   6578         return err;
   6579     }
   6580 
   6581     /**
   6582     * Link to the writer context in the writer interface */
   6583     pC->pWriterDataFcts->pWriterContext = pC->pWriterContext;
   6584 
   6585     /**
   6586     * Set the product description string in the written file */
   6587     err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
   6588         M4WRITER_kEmbeddedString, (M4OSA_DataOption)"NXP-SW : MCS    ");
   6589 
   6590     if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
   6591         != err) ) /* this option may not be implemented by some writers */
   6592     {
   6593         M4OSA_TRACE1_1(
   6594             "M4MCS_intPrepareWriter:\
   6595              pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedString) returns 0x%x",
   6596             err);
   6597         return err;
   6598     }
   6599 
   6600     /**
   6601     * Set the product version in the written file */
   6602     uiVersion =
   6603         M4VIDEOEDITING_VERSION_MAJOR * 100 + M4VIDEOEDITING_VERSION_MINOR * 10
   6604         + M4VIDEOEDITING_VERSION_REVISION;
   6605     err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
   6606         M4WRITER_kEmbeddedVersion, (M4OSA_DataOption) &uiVersion);
   6607 
   6608     if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
   6609         != err) ) /* this option may not be implemented by some writers */
   6610     {
   6611         M4OSA_TRACE1_1(
   6612             "M4MCS_intPrepareWriter: \
   6613             pWriterGlobalFcts->pFctSetOption(M4WRITER_kEmbeddedVersion) returns 0x%x",
   6614             err);
   6615         return err;
   6616     }
   6617 
   6618     /**
   6619     * If there is a video input, allocate and fill the video stream structures for the writer */
   6620     if( pC->novideo == M4OSA_FALSE )
   6621     {
   6622         /**
   6623         * Fill Video properties structure for the AddStream method */
   6624         pC->WriterVideoStreamInfo.height = pC->EncodingHeight;
   6625         pC->WriterVideoStreamInfo.width = pC->EncodingWidth;
   6626         pC->WriterVideoStreamInfo.fps =
   6627             0; /**< Not used by the shell/core writer */
   6628         pC->WriterVideoStreamInfo.Header.pBuf =
   6629             M4OSA_NULL; /**< Will be updated later */
   6630         pC->WriterVideoStreamInfo.Header.Size = 0; /**< Will be updated later */
   6631 
   6632         /**
   6633         * Fill Video stream description structure for the AddStream method */
   6634         switch( pC->EncodingVideoFormat )
   6635         {
   6636             case M4ENCODER_kMPEG4:
   6637                 pC->WriterVideoStream.streamType = M4SYS_kMPEG_4;
   6638                 break;
   6639 
   6640             case M4ENCODER_kH263:
   6641                 pC->WriterVideoStream.streamType = M4SYS_kH263;
   6642                 break;
   6643 
   6644             case M4ENCODER_kH264:
   6645                 pC->WriterVideoStream.streamType = M4SYS_kH264;
   6646                 break;
   6647 
   6648             case M4ENCODER_kNULL:
   6649                 switch( pC->InputFileProperties.VideoStreamType )
   6650                 {
   6651                     case M4VIDEOEDITING_kMPEG4:
   6652                         pC->WriterVideoStream.streamType = M4SYS_kMPEG_4;
   6653                         break;
   6654 
   6655                     case M4VIDEOEDITING_kH263:
   6656                         pC->WriterVideoStream.streamType = M4SYS_kH263;
   6657                         break;
   6658 
   6659                     case M4VIDEOEDITING_kH264:
   6660                         pC->WriterVideoStream.streamType = M4SYS_kH264;
   6661                         break;
   6662 
   6663                     default:
   6664                         M4OSA_TRACE1_1(
   6665                             "M4MCS_intPrepareWriter: case input=M4ENCODER_kNULL, \
   6666                             unknown format (0x%x),\
   6667                              returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT",
   6668                             pC->EncodingVideoFormat);
   6669                         return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT;
   6670                 }
   6671                 break;
   6672 
   6673             default: /**< It should never happen, already tested */
   6674                 M4OSA_TRACE1_1(
   6675                     "M4MCS_intPrepareWriter: unknown format (0x%x),\
   6676                      returning M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT",
   6677                     pC->EncodingVideoFormat);
   6678                 return M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT;
   6679         }
   6680 
   6681         /**
   6682         * Video bitrate value will be the real value */
   6683         pC->WriterVideoStream.averageBitrate =
   6684             (M4OSA_Int32)pC->uiEncVideoBitrate;
   6685         pC->WriterVideoStream.maxBitrate = (M4OSA_Int32)pC->uiEncVideoBitrate;
   6686 
   6687         /**
   6688         * most other parameters are "dummy" */
   6689         pC->WriterVideoStream.streamID = M4MCS_WRITER_VIDEO_STREAM_ID;
   6690         pC->WriterVideoStream.timeScale =
   6691             0; /**< Not used by the shell/core writer */
   6692         pC->WriterVideoStream.profileLevel =
   6693             0; /**< Not used by the shell/core writer */
   6694         pC->WriterVideoStream.duration =
   6695             0; /**< Not used by the shell/core writer */
   6696         pC->WriterVideoStream.decoderSpecificInfoSize =
   6697             sizeof(M4WRITER_StreamVideoInfos);
   6698         pC->WriterVideoStream.decoderSpecificInfo =
   6699             (M4OSA_MemAddr32) &(pC->WriterVideoStreamInfo);
   6700 
   6701         /**
   6702         * Update Encoder Header properties for Video stream if needed */
   6703         if( M4ENCODER_kH263 == pC->EncodingVideoFormat )
   6704         {
   6705             /**
   6706             * Creates the H263 DSI */
   6707             pC->WriterVideoStreamInfo.Header.Size =
   6708                 7; /**< H263 output DSI is always 7 bytes */
   6709             pDSI = (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(7, M4MCS, (M4OSA_Char
   6710                 *)"pC->WriterVideoStreamInfo.Header.pBuf (DSI H263)");
   6711 
   6712             if( M4OSA_NULL == pDSI )
   6713             {
   6714                 M4OSA_TRACE1_0("M4MCS_intPrepareWriter(): unable to allocate pDSI (H263),\
   6715                                returning M4ERR_ALLOC");
   6716                 return M4ERR_ALLOC;
   6717             }
   6718 
   6719             /**
   6720             * Vendor is NXP Software: N, X, P, S. */
   6721             pDSI[0] = 'N';
   6722             pDSI[1] = 'X';
   6723             pDSI[2] = 'P';
   6724             pDSI[3] = 'S';
   6725 
   6726             /**
   6727             * Decoder version is 0 */
   6728             pDSI[4] = 0;
   6729 
   6730             /**
   6731             * Level is the sixth byte of the DSI. */
   6732             switch( pC->EncodingWidth )
   6733             {
   6734                 case M4ENCODER_SQCIF_Width:
   6735                 case M4ENCODER_QCIF_Width:
   6736                     if( ( pC->uiEncVideoBitrate <= M4ENCODER_k64_KBPS)
   6737                         && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) )
   6738                     {
   6739                         pDSI[5] = 10;
   6740                     }
   6741                     else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS)
   6742                         && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) )
   6743                     {
   6744                         pDSI[5] = 45;
   6745                     }
   6746                     else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS)
   6747                         && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
   6748                     {
   6749                         pDSI[5] = 20;
   6750                     }
   6751                     else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k384_KBPS)
   6752                         && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
   6753                     {
   6754                         pDSI[5] = 30;
   6755                     }
   6756                     else if( ( pC->uiEncVideoBitrate
   6757                         <= M4ENCODER_k800_KBPS/*2048*/)
   6758                         && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
   6759                     {
   6760                         pDSI[5] = 40;
   6761                     }
   6762                     break;
   6763 
   6764                 case M4ENCODER_CIF_Width:
   6765                     if( ( pC->uiEncVideoBitrate <= M4ENCODER_k128_KBPS)
   6766                         && (pC->EncodingVideoFramerate <= M4ENCODER_k15_FPS) )
   6767                     {
   6768                         pDSI[5] = 20;
   6769                     }
   6770                     else if( ( pC->uiEncVideoBitrate <= M4ENCODER_k384_KBPS)
   6771                         && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
   6772                     {
   6773                         pDSI[5] = 30;
   6774                     }
   6775                     else if( ( pC->uiEncVideoBitrate
   6776                         <= M4ENCODER_k800_KBPS/*2048*/)
   6777                         && (pC->EncodingVideoFramerate <= M4ENCODER_k30_FPS) )
   6778                     {
   6779                         pDSI[5] = 40;
   6780                     }
   6781                     break;
   6782 
   6783                     default:
   6784                     break;
   6785             }
   6786 
   6787             /**
   6788             * Profile is the seventh byte of the DSI. */
   6789             pDSI[6] = 0;
   6790 
   6791             pC->WriterVideoStreamInfo.Header.pBuf = pDSI;
   6792         }
   6793         else if( M4ENCODER_kNULL == pC->EncodingVideoFormat )
   6794         {
   6795             /* If we copy the stream from the input, we copy its DSI */
   6796 
   6797             pC->WriterVideoStreamInfo.Header.Size = pC->pReaderVideoStream->
   6798                 m_basicProperties.m_decoderSpecificInfoSize;
   6799             pC->WriterVideoStreamInfo.Header.pBuf =
   6800                 (M4OSA_MemAddr8)pC->pReaderVideoStream->
   6801                 m_basicProperties.m_pDecoderSpecificInfo;
   6802 
   6803         }
   6804         /* otherwise (MPEG4), the DSI will be recovered from the encoder later on. */
   6805 
   6806         /*+CRLV6775 - H.264 Trimming  */
   6807         if( pC->bH264Trim == M4OSA_TRUE )
   6808         {
   6809             bMULPPSSPS = M4OSA_TRUE;
   6810             err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
   6811                 (M4OSA_UInt32)M4WRITER_kMUL_PPS_SPS,
   6812                 (M4OSA_DataOption) &bMULPPSSPS);
   6813 
   6814             if( ( M4NO_ERROR != err)
   6815                 && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
   6816                 != err) ) /* this option may not be implemented by some writers */
   6817             {
   6818                 M4OSA_TRACE1_1(
   6819                     "M4MCS_intPrepareWriter:\
   6820                      pWriterGlobalFcts->pFctSetOption(M4WRITER_kMUL_PPS_SPS) returns 0x%x",
   6821                     err);
   6822                 return err;
   6823             }
   6824         }
   6825         /*-CRLV6775 - H.264 Trimming  */
   6826         /**
   6827         * Add the video stream */
   6828         err = pC->pWriterGlobalFcts->pFctAddStream(pC->pWriterContext,
   6829             &pC->WriterVideoStream);
   6830 
   6831         if( M4NO_ERROR != err )
   6832         {
   6833             M4OSA_TRACE1_1(
   6834                 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctAddStream(video) returns 0x%x!",
   6835                 err);
   6836             return err;
   6837         }
   6838 
   6839         /**
   6840         * Update AU properties for video stream */
   6841         pC->WriterVideoAU.stream = &(pC->WriterVideoStream);
   6842         pC->WriterVideoAU.dataAddress = M4OSA_NULL;
   6843         pC->WriterVideoAU.size = 0;
   6844         pC->WriterVideoAU.CTS = 0; /** Reset time */
   6845         pC->WriterVideoAU.DTS = 0;
   6846         pC->WriterVideoAU.attribute = AU_RAP;
   6847         pC->WriterVideoAU.nbFrag = 0; /** No fragment */
   6848         pC->WriterVideoAU.frag = M4OSA_NULL;
   6849 
   6850         /**
   6851         * Set the writer max video AU size */
   6852         optionValue.streamID = M4MCS_WRITER_VIDEO_STREAM_ID;
   6853         optionValue.value = pC->uiVideoMaxAuSize;
   6854         err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
   6855             (M4OSA_UInt32)M4WRITER_kMaxAUSize,
   6856             (M4OSA_DataOption) &optionValue);
   6857 
   6858         if( M4NO_ERROR != err )
   6859         {
   6860             M4OSA_TRACE1_1(
   6861                 "M4MCS_intPrepareWriter: \
   6862                 pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!",
   6863                 err);
   6864             return err;
   6865         }
   6866 
   6867         /**
   6868         * Set the writer max video chunk size */
   6869         optionValue.value = pC->uiVideoMaxChunckSize;
   6870         err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
   6871             (M4OSA_UInt32)M4WRITER_kMaxChunckSize,
   6872             (M4OSA_DataOption) &optionValue);
   6873 
   6874         if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
   6875             != err) ) /* this option may not be implemented by some writers */
   6876         {
   6877             M4OSA_TRACE1_1(
   6878                 "M4MCS_intPrepareWriter:\
   6879                  pWriterGlobalFcts->pFctSetOption(M4WRITER_kMaxAUSize, video) returns 0x%x!",
   6880                 err);
   6881             return err;
   6882         }
   6883     }
   6884 
   6885     /**
   6886     * If there is an audio input, allocate and fill the audio stream structures for the writer */
   6887     if( pC->noaudio == M4OSA_FALSE )
   6888     {
   6889         M4WRITER_StreamAudioInfos streamAudioInfo;
   6890 
   6891         streamAudioInfo.nbSamplesPerSec = 0; /**< unused by our shell writer */
   6892         streamAudioInfo.nbBitsPerSample = 0; /**< unused by our shell writer */
   6893         streamAudioInfo.nbChannels = 1;      /**< unused by our shell writer */
   6894 
   6895         pC->WriterAudioStream.averageBitrate =
   6896             0; /**< It is not used by the shell, the DSI is taken into account instead */
   6897         pC->WriterAudioStream.maxBitrate =
   6898             0; /**< Not used by the shell/core writer */
   6899 
   6900         /**
   6901         * Fill Audio stream description structure for the AddStream method */
   6902         switch( pC->AudioEncParams.Format )
   6903         {
   6904             case M4ENCODER_kAMRNB:
   6905                 pC->WriterAudioStream.streamType = M4SYS_kAMR;
   6906                 break;
   6907 
   6908             case M4ENCODER_kAAC:
   6909                 pC->WriterAudioStream.streamType = M4SYS_kAAC;
   6910                 pC->WriterAudioStream.averageBitrate =
   6911                     pC->AudioEncParams.Bitrate;
   6912                 pC->WriterAudioStream.maxBitrate = pC->AudioEncParams.Bitrate;
   6913                 break;
   6914 
   6915                 /*FlB 26.02.2009: add mp3 as output format*/
   6916             case M4ENCODER_kMP3:
   6917                 pC->WriterAudioStream.streamType = M4SYS_kMP3;
   6918                 break;
   6919 
   6920             case M4ENCODER_kAudioNULL:
   6921                 switch( pC->InputFileProperties.AudioStreamType )
   6922                 {
   6923                 case M4VIDEOEDITING_kAMR_NB:
   6924                     pC->WriterAudioStream.streamType = M4SYS_kAMR;
   6925                     break;
   6926                     /*FlB 26.02.2009: add mp3 as output format*/
   6927                 case M4VIDEOEDITING_kMP3:
   6928                     pC->WriterAudioStream.streamType = M4SYS_kMP3;
   6929                     break;
   6930 
   6931                 case M4VIDEOEDITING_kAAC:
   6932                 case M4VIDEOEDITING_kAACplus:
   6933                 case M4VIDEOEDITING_keAACplus:
   6934                     pC->WriterAudioStream.streamType = M4SYS_kAAC;
   6935                     pC->WriterAudioStream.averageBitrate =
   6936                         pC->AudioEncParams.Bitrate;
   6937                     pC->WriterAudioStream.maxBitrate =
   6938                         pC->AudioEncParams.Bitrate;
   6939                     break;
   6940 
   6941                 case M4VIDEOEDITING_kEVRC:
   6942                     pC->WriterAudioStream.streamType = M4SYS_kEVRC;
   6943                     break;
   6944 
   6945                 case M4VIDEOEDITING_kNoneAudio:
   6946                 case M4VIDEOEDITING_kPCM:
   6947                 case M4VIDEOEDITING_kNullAudio:
   6948                 case M4VIDEOEDITING_kUnsupportedAudio:
   6949                     break;
   6950                 }
   6951                 break;
   6952 
   6953             default: /**< It should never happen, already tested */
   6954                 M4OSA_TRACE1_1(
   6955                     "M4MCS_intPrepareWriter: \
   6956                     unknown format (0x%x), returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT",
   6957                     pC->AudioEncParams.Format);
   6958                 return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT;
   6959         }
   6960 
   6961         /**
   6962         * MCS produces only AMR-NB output */
   6963         pC->WriterAudioStream.streamID = M4MCS_WRITER_AUDIO_STREAM_ID;
   6964         pC->WriterAudioStream.duration =
   6965             0; /**< Not used by the shell/core writer */
   6966         pC->WriterAudioStream.profileLevel =
   6967             0; /**< Not used by the shell/core writer */
   6968         pC->WriterAudioStream.timeScale = pC->AudioEncParams.Frequency;
   6969 
   6970         if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
   6971         {
   6972             /* If we copy the stream from the input, we copy its DSI */
   6973             streamAudioInfo.Header.Size = pC->pReaderAudioStream->
   6974                 m_basicProperties.m_decoderSpecificInfoSize;
   6975             streamAudioInfo.Header.pBuf =
   6976                 (M4OSA_MemAddr8)pC->pReaderAudioStream->
   6977                 m_basicProperties.m_pDecoderSpecificInfo;
   6978         }
   6979         else
   6980         {
   6981             if( pC->pAudioEncDSI.pInfo != M4OSA_NULL )
   6982             {
   6983                 /* Use the DSI given by the encoder open() */
   6984                 streamAudioInfo.Header.Size = pC->pAudioEncDSI.infoSize;
   6985                 streamAudioInfo.Header.pBuf = pC->pAudioEncDSI.pInfo;
   6986             }
   6987             else
   6988             {
   6989                 /* Writer will put a default Philips DSI */
   6990                 streamAudioInfo.Header.Size = 0;
   6991                 streamAudioInfo.Header.pBuf = M4OSA_NULL;
   6992             }
   6993         }
   6994 
   6995         /**
   6996         * Our writer shell interface is a little tricky: we put M4WRITER_StreamAudioInfos
   6997          in the DSI pointer... */
   6998         pC->WriterAudioStream.decoderSpecificInfo =
   6999             (M4OSA_MemAddr32) &streamAudioInfo;
   7000 
   7001         /**
   7002         * Add the audio stream to the writer */
   7003         err = pC->pWriterGlobalFcts->pFctAddStream(pC->pWriterContext,
   7004             &pC->WriterAudioStream);
   7005 
   7006         if( M4NO_ERROR != err )
   7007         {
   7008             M4OSA_TRACE1_1(
   7009                 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctAddStream(audio) returns 0x%x",
   7010                 err);
   7011             return err;
   7012         }
   7013 
   7014         /**
   7015         * Link the AU and the stream */
   7016         pC->WriterAudioAU.stream = &(pC->WriterAudioStream);
   7017         pC->WriterAudioAU.dataAddress = M4OSA_NULL;
   7018         pC->WriterAudioAU.size = 0;
   7019         pC->WriterAudioAU.CTS = 0; /** Reset time */
   7020         pC->WriterAudioAU.DTS = 0;
   7021         pC->WriterAudioAU.attribute = 0;
   7022         pC->WriterAudioAU.nbFrag = 0; /** No fragment */
   7023         pC->WriterAudioAU.frag = M4OSA_NULL;
   7024 
   7025         /**
   7026         * Set the writer audio max AU size */
   7027         /* As max bitrate is now 320kbps instead of 128kbps, max AU
   7028          * size has to be increased adapt the max AU size according to the stream type and the
   7029          * channels numbers*/
   7030         /* After tests, a margin of 3 is taken (2 was not enough and raises to memory overwrite)
   7031          */
   7032         //pC->uiAudioMaxAuSize = M4MCS_AUDIO_MAX_AU_SIZE;
   7033         switch( pC->WriterAudioStream.streamType )
   7034         {
   7035             case M4SYS_kAMR:
   7036                 pC->uiAudioMaxAuSize = M4MCS_PCM_AMR_GRANULARITY_SAMPLES
   7037                     * (( pC->InputFileProperties.uiNbChannels
   7038                     * sizeof(short)) + 3);
   7039                 break;
   7040 
   7041             case M4SYS_kMP3:
   7042                 pC->uiAudioMaxAuSize = M4MCS_PCM_MP3_GRANULARITY_SAMPLES
   7043                     * (( pC->InputFileProperties.uiNbChannels
   7044                     * sizeof(short)) + 3);
   7045                 break;
   7046 
   7047             case M4SYS_kAAC:
   7048                 pC->uiAudioMaxAuSize = M4MCS_PCM_AAC_GRANULARITY_SAMPLES
   7049                     * (( pC->InputFileProperties.uiNbChannels
   7050                     * sizeof(short)) + 3);
   7051                 break;
   7052                 /*case M4SYS_kEVRC:
   7053                 pC->uiAudioMaxAuSize = M4MCS_PCM_EVRC_GRANULARITY_SAMPLES*
   7054                 ((pC->InputFileProperties.uiNbChannels * sizeof(short))+3);
   7055                 break;*/
   7056             default: /**< It should never happen, already tested */
   7057                 M4OSA_TRACE1_1(
   7058                     "M4MCS_intPrepareWriter: unknown format (0x%x),\
   7059                      returning M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT",
   7060                     pC->WriterAudioStream.streamType);
   7061                 return M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT;
   7062         }
   7063 
   7064         optionValue.streamID = M4MCS_WRITER_AUDIO_STREAM_ID;
   7065         optionValue.value = pC->uiAudioMaxAuSize;
   7066         err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
   7067             (M4OSA_UInt32)M4WRITER_kMaxAUSize,
   7068             (M4OSA_DataOption) &optionValue);
   7069 
   7070         if( M4NO_ERROR != err )
   7071         {
   7072             M4OSA_TRACE1_1(
   7073                 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption(audio,\
   7074                 M4WRITER_kMaxAUSize) returns 0x%x",
   7075                 err);
   7076             return err;
   7077         }
   7078 
   7079         optionValue.value = M4MCS_AUDIO_MAX_CHUNK_SIZE;
   7080         err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
   7081             (M4OSA_UInt32)M4WRITER_kMaxChunckSize,
   7082             (M4OSA_DataOption) &optionValue);
   7083 
   7084         if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
   7085             != err) ) /* this option may not be implemented by some writers */
   7086         {
   7087             M4OSA_TRACE1_1(
   7088                 "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption(audio,\
   7089                 M4WRITER_kMaxChunckSize) returns 0x%x",
   7090                 err);
   7091             return err;
   7092         }
   7093     }
   7094 
   7095     /*
   7096     * Set the limitation size of the writer */
   7097     TargetedFileSize = pC->uiMaxFileSize;
   7098     /* add 1 kB margin */
   7099     if( TargetedFileSize > 8192 )
   7100         TargetedFileSize -= 1024;
   7101 
   7102     err = pC->pWriterGlobalFcts->pFctSetOption(pC->pWriterContext,
   7103         (M4OSA_UInt32)M4WRITER_kMaxFileSize,
   7104         (M4OSA_DataOption) &TargetedFileSize);
   7105 
   7106     if( ( M4NO_ERROR != err) && (( (M4OSA_UInt32)M4ERR_BAD_OPTION_ID)
   7107         != err) ) /* this option may not be implemented by some writers */
   7108     {
   7109         M4OSA_TRACE1_1(
   7110             "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctSetOption\
   7111             (M4WRITER_kMaxFileSize) returns 0x%x!",
   7112             err);
   7113         return err;
   7114     }
   7115 
   7116     /**
   7117     * Close the stream registering in order to be ready to write data */
   7118     err = pC->pWriterGlobalFcts->pFctStartWriting(pC->pWriterContext);
   7119 
   7120     if( M4NO_ERROR != err )
   7121     {
   7122         M4OSA_TRACE1_1(
   7123             "M4MCS_intPrepareWriter: pWriterGlobalFcts->pFctStartWriting returns 0x%x",
   7124             err);
   7125         return err;
   7126     }
   7127 
   7128     /**
   7129     * Return with no error */
   7130     M4OSA_TRACE3_0("M4MCS_intPrepareWriter(): returning M4NO_ERROR");
   7131     return M4NO_ERROR;
   7132 }
   7133 
   7134 /**
   7135  ******************************************************************************
   7136  * M4OSA_ERR M4MCS_intPrepareAudioBeginCut(M4MCS_InternalContext* pC);
   7137  * @brief    DO the audio begin cut.
   7138  * @param    pC          (IN) MCS private context
   7139  * @return   M4NO_ERROR  No error
   7140  * @return   Any error returned by an underlaying module
   7141  ******************************************************************************
   7142  */
   7143 static M4OSA_ERR M4MCS_intPrepareAudioBeginCut( M4MCS_InternalContext *pC )
   7144 {
   7145     M4OSA_ERR err;
   7146     M4OSA_Int32 iCts;
   7147     M4OSA_UInt32 uiFrameSize;
   7148 
   7149     if( pC->noaudio )
   7150         return M4NO_ERROR;
   7151 
   7152     /**
   7153     * Check if an audio begin cut is needed */
   7154     if( ( M4OSA_NULL == pC->pReaderAudioStream) || (0 == pC->uiBeginCutTime) )
   7155     {
   7156         /**
   7157         * Return with no error */
   7158         M4OSA_TRACE3_0(
   7159             "M4MCS_intPrepareAudioBeginCut(): returning M4NO_ERROR (a)");
   7160         return M4NO_ERROR;
   7161     }
   7162 
   7163     /**
   7164     * Jump at the begin cut time */
   7165     iCts = pC->uiBeginCutTime;
   7166     err = pC->m_pReader->m_pFctJump(pC->pReaderContext,
   7167         (M4_StreamHandler *)pC->pReaderAudioStream, &iCts);
   7168 
   7169     if( M4NO_ERROR != err )
   7170     {
   7171         M4OSA_TRACE1_1(
   7172             "M4MCS_intPrepareAudioBeginCut: m_pFctJump(Audio) returns 0x%x!",
   7173             err);
   7174         return err;
   7175     }
   7176 
   7177     /**
   7178     * Remember audio begin cut offset */
   7179     pC->iAudioCtsOffset = iCts;
   7180 
   7181     /**
   7182     * AMR-NB & EVRC: there may be many frames per AU.
   7183     * In that case we need to slice the first AU to keep the 20 ms cut precision */
   7184     if( ( M4DA_StreamTypeAudioAmrNarrowBand
   7185         == pC->pReaderAudioStream->m_basicProperties.m_streamType)
   7186         || (M4DA_StreamTypeAudioEvrc
   7187         == pC->pReaderAudioStream->m_basicProperties.m_streamType) )
   7188     {
   7189         /**
   7190         * If the next frame CTS is lower than the begin cut time,
   7191         * we must read the AU and parse its frames to reach the
   7192         * nearest to the begin cut */
   7193         if( ( iCts + 20) < (M4OSA_Int32)pC->uiBeginCutTime )
   7194         {
   7195             /**
   7196             * Read the first audio AU after the jump */
   7197             err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
   7198                 (M4_StreamHandler *)pC->pReaderAudioStream,
   7199                 &pC->ReaderAudioAU);
   7200 
   7201             if( M4WAR_NO_MORE_AU == err )
   7202             {
   7203                 M4OSA_TRACE1_0(
   7204                     "M4MCS_intPrepareAudioBeginCut(): m_pReaderDataIt->m_pFctGetNextAu(audio)\
   7205                      returns M4WAR_NO_MORE_AU! Returning M4NO_ERROR");
   7206                 return
   7207                     M4NO_ERROR; /**< no fatal error here, we should be able to pursue */
   7208             }
   7209             else if( M4NO_ERROR != err )
   7210             {
   7211                 M4OSA_TRACE1_1(
   7212                     "M4MCS_intPrepareAudioBeginCut(): m_pReaderDataIt->m_pFctGetNextAu(Audio)\
   7213                      returns 0x%x",
   7214                     err);
   7215                 return err;
   7216             }
   7217 
   7218             /**
   7219             * While the next AU has a lower CTS than the begin cut time, we advance to
   7220             the next frame */
   7221             while( ( iCts + 20) <= (M4OSA_Int32)pC->uiBeginCutTime )
   7222             {
   7223                 /**
   7224                 * Get the size of the frame */
   7225                 switch( pC->pReaderAudioStream->m_basicProperties.m_streamType )
   7226                 {
   7227                     case M4DA_StreamTypeAudioAmrNarrowBand:
   7228                         uiFrameSize = M4MCS_intGetFrameSize_AMRNB(
   7229                             pC->ReaderAudioAU.m_dataAddress);
   7230                         break;
   7231 
   7232                     case M4DA_StreamTypeAudioEvrc:
   7233                         uiFrameSize = M4MCS_intGetFrameSize_EVRC(
   7234                             pC->ReaderAudioAU.m_dataAddress);
   7235                         break;
   7236 
   7237                     default:
   7238                         uiFrameSize = 0;
   7239                         break;
   7240                 }
   7241 
   7242                 if( 0 == uiFrameSize )
   7243                 {
   7244                     /**
   7245                     * Corrupted frame! We get out of this mess!
   7246                     * We don't want to crash here... */
   7247                     M4OSA_TRACE1_0(
   7248                         "M4MCS_intPrepareAudioBeginCut(): \
   7249                         M4MCS_intGetFrameSize_xxx returns 0! Returning M4NO_ERROR");
   7250                     return
   7251                         M4NO_ERROR; /**< no fatal error here, we should be able to pursue */
   7252                 }
   7253 
   7254                 /**
   7255                 * Go to the next frame */
   7256                 pC->ReaderAudioAU.m_dataAddress += uiFrameSize;
   7257                 pC->ReaderAudioAU.m_size -= uiFrameSize;
   7258 
   7259                 /**
   7260                 * Get the CTS of the next frame */
   7261                 iCts += 20; /**< AMR, EVRC frame duration is always 20 ms */
   7262                 pC->ReaderAudioAU.m_CTS = iCts;
   7263                 pC->ReaderAudioAU.m_DTS = iCts;
   7264             }
   7265 
   7266             /**
   7267             * Update the audio begin cut offset */
   7268             pC->iAudioCtsOffset = iCts;
   7269         }
   7270     }
   7271 
   7272     /**
   7273     * Return with no error */
   7274     M4OSA_TRACE3_0("M4MCS_intPrepareAudioBeginCut(): returning M4NO_ERROR");
   7275     return M4NO_ERROR;
   7276 }
   7277 
   7278 /**
   7279  ******************************************************************************
   7280  * M4OSA_ERR M4MCS_intStepEncoding(M4MCS_InternalContext* pC, M4OSA_UInt8* pProgress)
   7281  ******************************************************************************
   7282  */
   7283 static M4OSA_ERR M4MCS_intStepEncoding( M4MCS_InternalContext *pC,
   7284                                        M4OSA_UInt8 *pProgress )
   7285 {
   7286     M4OSA_ERR err;
   7287     M4OSA_UInt32 uiAudioStepCount = 0;
   7288 
   7289     /* ---------- VIDEO TRANSCODING ---------- */
   7290 
   7291     if( ( pC->novideo == M4OSA_FALSE) && (M4MCS_kStreamState_STARTED
   7292         == pC->VideoState) ) /**< If the video encoding is going on */
   7293     {
   7294         if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
   7295         {
   7296             err = M4MCS_intVideoNullEncoding(pC);
   7297         }
   7298         else
   7299         {
   7300             err = M4MCS_intVideoTranscoding(pC);
   7301         }
   7302 
   7303         /**
   7304         * No more space, quit properly */
   7305         if( M4WAR_WRITER_STOP_REQ == err )
   7306         {
   7307             *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->dViDecCurrentCts
   7308                 - pC->uiBeginCutTime) * 100)
   7309                 / (pC->uiEndCutTime - pC->uiBeginCutTime));
   7310 
   7311             pC->State = M4MCS_kState_FINISHED;
   7312 
   7313             /* bad file produced on very short 3gp file */
   7314             if( pC->dViDecCurrentCts - pC->uiBeginCutTime == 0 )
   7315             {
   7316                 /* Nothing has been encoded -> bad produced file -> error returned */
   7317                 M4OSA_TRACE2_0(
   7318                     "M4MCS_intStepEncoding(): video transcoding returns\
   7319                      M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL");
   7320                 return M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL;
   7321             }
   7322             else
   7323             {
   7324 #ifndef M4MCS_AUDIOONLY
   7325                 /* clean AIR context needed to keep media aspect ratio*/
   7326 
   7327                 if( M4OSA_NULL != pC->m_air_context )
   7328                 {
   7329                     err = M4AIR_cleanUp(pC->m_air_context);
   7330 
   7331                     if( err != M4NO_ERROR )
   7332                     {
   7333                         M4OSA_TRACE1_1(
   7334                             "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x",
   7335                             err);
   7336                         return err;
   7337                     }
   7338                     pC->m_air_context = M4OSA_NULL;
   7339                 }
   7340 
   7341 #endif /*M4MCS_AUDIOONLY*/
   7342 
   7343                 M4OSA_TRACE2_0(
   7344                     "M4MCS_intStepEncoding(): video transcoding returns M4MCS_ERR_NOMORE_SPACE");
   7345                 return M4MCS_ERR_NOMORE_SPACE;
   7346             }
   7347         }
   7348 
   7349         /**< The input plane is null because the input image will be obtained by the
   7350         VPP filter from the context */
   7351         if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err) )
   7352         {
   7353             M4OSA_TRACE1_1(
   7354                 "M4MCS_intStepEncoding(): video transcoding returns 0x%x!",
   7355                 err);
   7356             return err;
   7357         }
   7358     }
   7359 
   7360     /* ---------- AUDIO TRANSCODING ---------- */
   7361 
   7362     if( ( pC->noaudio == M4OSA_FALSE) && (M4MCS_kStreamState_STARTED
   7363         == pC->AudioState) ) /**< If there is an audio stream */
   7364     {
   7365         while(
   7366             /**< If the video encoding is running, encode audio until we reach video time */
   7367             ( ( pC->novideo == M4OSA_FALSE)
   7368             && (M4MCS_kStreamState_STARTED == pC->VideoState)
   7369             && (pC->ReaderAudioAU.m_CTS
   7370             + pC->m_audioAUDuration < pC->ReaderVideoAU.m_CTS)) ||
   7371             /**< If the video encoding is not running, perform 1 step of audio encoding */
   7372             (( M4MCS_kStreamState_STARTED == pC->AudioState)
   7373             && (uiAudioStepCount < 1)) )
   7374         {
   7375             uiAudioStepCount++;
   7376 
   7377             /**< check if an adio effect has to be applied*/
   7378             err = M4MCS_intCheckAudioEffects(pC);
   7379 
   7380             if( M4NO_ERROR != err )
   7381             {
   7382                 M4OSA_TRACE1_1(
   7383                     "M4MCS_intStepEncoding(): M4MCS_intCheckAudioEffects returns err: 0x%x",
   7384                     err);
   7385                 return err;
   7386             }
   7387 
   7388             if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
   7389             {
   7390                 err = M4MCS_intAudioNullEncoding(pC);
   7391             }
   7392             else /**< Audio transcoding */
   7393             {
   7394                 err = M4MCS_intAudioTranscoding(pC);
   7395             }
   7396 
   7397             /**
   7398             * No more space, quit properly */
   7399             if( M4WAR_WRITER_STOP_REQ == err )
   7400             {
   7401                 *pProgress =
   7402                     (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS
   7403                     - pC->uiBeginCutTime) * 100)
   7404                     / (pC->uiEndCutTime - pC->uiBeginCutTime));
   7405 
   7406                 pC->State = M4MCS_kState_FINISHED;
   7407 
   7408                 /* bad file produced on very short 3gp file */
   7409                 if( pC->ReaderAudioAU.m_CTS - pC->uiBeginCutTime == 0 )
   7410                 {
   7411                     /* Nothing has been encoded -> bad produced file -> error returned */
   7412                     M4OSA_TRACE2_0(
   7413                         "M4MCS_intStepEncoding():\
   7414                          audio transcoding returns M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL");
   7415                     return M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL;
   7416                 }
   7417                 else
   7418                 {
   7419 #ifndef M4MCS_AUDIOONLY
   7420                     /* clean AIR context needed to keep media aspect ratio*/
   7421 
   7422                     if( M4OSA_NULL != pC->m_air_context )
   7423                     {
   7424                         err = M4AIR_cleanUp(pC->m_air_context);
   7425 
   7426                         if( err != M4NO_ERROR )
   7427                         {
   7428                             M4OSA_TRACE1_1(
   7429                                 "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x",
   7430                                 err);
   7431                             return err;
   7432                         }
   7433                         pC->m_air_context = M4OSA_NULL;
   7434                     }
   7435 
   7436 #endif /*M4MCS_AUDIOONLY*/
   7437 
   7438                     M4OSA_TRACE2_0(
   7439                         "M4MCS_intStepEncoding(): \
   7440                         audio transcoding returns M4MCS_ERR_NOMORE_SPACE");
   7441                     return M4MCS_ERR_NOMORE_SPACE;
   7442                 }
   7443             }
   7444 
   7445             if( M4WAR_NO_MORE_AU == err )
   7446             {
   7447                 pC->AudioState = M4MCS_kStreamState_FINISHED;
   7448                 M4OSA_TRACE3_0(
   7449                     "M4MCS_intStepEncoding(): audio transcoding returns M4WAR_NO_MORE_AU");
   7450                 break;
   7451             }
   7452             else if( M4NO_ERROR != err )
   7453             {
   7454                 M4OSA_TRACE1_1(
   7455                     "M4MCS_intStepEncoding(): audio transcoding returns 0x%x",
   7456                     err);
   7457                 return err;
   7458             }
   7459 
   7460             /**
   7461             * Check for end cut */
   7462             /* We absolutely want to have less or same audio duration as video ->
   7463             (2*pC->m_audioAUDuration) */
   7464             if( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS
   7465                 + (2 *pC->m_audioAUDuration) > pC->uiEndCutTime )
   7466             {
   7467                 pC->AudioState = M4MCS_kStreamState_FINISHED;
   7468                 break;
   7469             }
   7470         }
   7471     }
   7472 
   7473     /* ---------- PROGRESS MANAGEMENT ---------- */
   7474 
   7475     /**
   7476     * Compute progress */
   7477     if( pC->novideo )
   7478     {
   7479         if( pC->ReaderAudioAU.m_CTS < pC->uiBeginCutTime )
   7480         {
   7481             *pProgress = 0;
   7482         }
   7483         else
   7484         {
   7485             *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS
   7486                 - pC->uiBeginCutTime) * 100)
   7487                 / (pC->uiEndCutTime - pC->uiBeginCutTime));
   7488         }
   7489         //printf(": %6.0f\b\b\b\b\b\b\b\b", pC->ReaderAudioAU.m_CTS);
   7490 
   7491     }
   7492     else
   7493     {
   7494         if( pC->dViDecCurrentCts < pC->uiBeginCutTime )
   7495         {
   7496             *pProgress = 0;
   7497         }
   7498         else
   7499         {
   7500             *pProgress = (M4OSA_UInt8)(( ( (M4OSA_UInt32)pC->dViDecCurrentCts
   7501                 - pC->uiBeginCutTime) * 100)
   7502                 / (pC->uiEndCutTime - pC->uiBeginCutTime));
   7503         }
   7504         //printf(": %6.0f\b\b\b\b\b\b\b\b", pC->dViDecCurrentCts);
   7505     }
   7506 
   7507     /**
   7508     * Sanity check */
   7509     if( *pProgress > 99 )
   7510     {
   7511         *pProgress = 99;
   7512     }
   7513 
   7514     /**
   7515     * Increment CTS for next step */
   7516     if( pC->novideo == M4OSA_FALSE )
   7517     {
   7518         if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
   7519         {
   7520            pC->dViDecCurrentCts +=  1;
   7521         }
   7522         else
   7523         {
   7524             pC->dViDecCurrentCts += pC->dCtsIncrement;
   7525         }
   7526     }
   7527 
   7528     /**
   7529     * The transcoding is finished when no stream is being encoded anymore */
   7530     if( ( ( pC->novideo) || (M4MCS_kStreamState_FINISHED == pC->VideoState))
   7531         && (( pC->noaudio) || (M4MCS_kStreamState_FINISHED == pC->AudioState)) )
   7532     {
   7533         /* the AIR part can only be used when video codecs are compiled*/
   7534 #ifndef M4MCS_AUDIOONLY
   7535         /* clean AIR context needed to keep media aspect ratio*/
   7536 
   7537         if( M4OSA_NULL != pC->m_air_context )
   7538         {
   7539             err = M4AIR_cleanUp(pC->m_air_context);
   7540 
   7541             if( err != M4NO_ERROR )
   7542             {
   7543                 M4OSA_TRACE1_1(
   7544                     "M4xVSS_PictureCallbackFct: Error when cleaning AIR: 0x%x",
   7545                     err);
   7546                 return err;
   7547             }
   7548             pC->m_air_context = M4OSA_NULL;
   7549         }
   7550 
   7551 #endif /*M4MCS_AUDIOONLY*/
   7552         /**/
   7553 
   7554         *pProgress = 100;
   7555         pC->State = M4MCS_kState_FINISHED;
   7556         M4OSA_TRACE2_0(
   7557             "M4MCS_intStepEncoding(): transcoding finished, returning M4MCS_WAR_TRANSCODING_DONE");
   7558         return M4MCS_WAR_TRANSCODING_DONE;
   7559     }
   7560 
   7561     /**
   7562     * Return with no error */
   7563     M4OSA_TRACE3_0("M4MCS_intStepEncoding(): returning M4NO_ERROR");
   7564     return M4NO_ERROR;
   7565 }
   7566 
   7567 /**
   7568  ******************************************************************************
   7569  * M4OSA_ERR M4MCS_intStepBeginVideoJump(M4MCS_InternalContext* pC)
   7570  ******************************************************************************
   7571  */
   7572 static M4OSA_ERR M4MCS_intStepBeginVideoJump( M4MCS_InternalContext *pC )
   7573 {
   7574     M4OSA_ERR err;
   7575     M4OSA_Int32 iCts;
   7576 
   7577     if( pC->novideo )
   7578     {
   7579         pC->State = M4MCS_kState_BEGINVIDEODECODE;
   7580         return M4NO_ERROR;
   7581     }
   7582 
   7583     /**
   7584     * Jump to the previous RAP in the clip (first get the time, then jump) */
   7585     iCts = (M4OSA_Int32)pC->dViDecStartingCts;
   7586     err = pC->m_pReader->m_pFctGetPrevRapTime(pC->pReaderContext,
   7587         (M4_StreamHandler *)pC->pReaderVideoStream, &iCts);
   7588 
   7589     if( M4WAR_READER_INFORMATION_NOT_PRESENT == err )
   7590     {
   7591         /* No RAP table, jump backward and predecode */
   7592         iCts = (M4OSA_Int32)pC->dViDecStartingCts - M4MCS_NO_STSS_JUMP_POINT;
   7593 
   7594         if( iCts < 0 )
   7595             iCts = 0;
   7596     }
   7597     else if( M4NO_ERROR != err )
   7598     {
   7599         M4OSA_TRACE1_1(
   7600             "M4MCS_intStepBeginVideoJump: m_pFctGetPrevRapTime returns 0x%x!",
   7601             err);
   7602         return err;
   7603     }
   7604 
   7605     /* + CRLV6775 -H.264 Trimming */
   7606 
   7607     if( M4OSA_TRUE == pC->bH264Trim )
   7608     {
   7609 
   7610         // Save jump time for safety, this fix should be generic
   7611 
   7612         M4OSA_Int32 iCtsOri = iCts;
   7613 
   7614 
   7615         err = pC->m_pReader->m_pFctJump(pC->pReaderContext,
   7616             (M4_StreamHandler *)pC->pReaderVideoStream, &iCts);
   7617 
   7618         if( M4NO_ERROR != err )
   7619         {
   7620             M4OSA_TRACE1_1(
   7621                 "M4MCS_intStepBeginVideoJump: m_pFctJump(V) returns 0x%x!",
   7622                 err);
   7623             return err;
   7624         }
   7625 
   7626         if( pC->ReaderVideoAU1.m_structSize == 0 )
   7627         {
   7628             /**
   7629             * Initializes an access Unit */
   7630             err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
   7631                 (M4_StreamHandler *)pC->pReaderVideoStream,
   7632                 &pC->ReaderVideoAU1);
   7633 
   7634             if( M4NO_ERROR != err )
   7635             {
   7636                 M4OSA_TRACE1_1(
   7637                     "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
   7638                     err);
   7639                 return err;
   7640             }
   7641             err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
   7642                 (M4_StreamHandler *)pC->pReaderVideoStream,
   7643                 &pC->ReaderVideoAU1);
   7644 
   7645             if( M4WAR_NO_MORE_AU == err )
   7646             {
   7647                 M4OSA_TRACE2_0(
   7648                     "M4MCS_intVideoNullEncoding(): \
   7649                     m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU");
   7650                 /* The audio transcoding is finished */
   7651                 pC->VideoState = M4MCS_kStreamState_FINISHED;
   7652                 return err;
   7653             }
   7654             else if( M4NO_ERROR != err )
   7655             {
   7656                 M4OSA_TRACE1_1(
   7657                     "M4MCS_intVideoNullEncoding():\
   7658                      m_pReaderDataIt->m_pFctGetNextAu(video) returns 0x%x",
   7659                     err);
   7660                 return err;
   7661             }
   7662 
   7663             pC->ReaderVideoAU1.m_structSize = 0;
   7664         }
   7665 
   7666         err = H264MCS_ProcessSPS_PPS(pC->m_pInstance,
   7667             (M4OSA_UInt8 *)pC->ReaderVideoAU1.m_dataAddress, pC->ReaderVideoAU1.m_size);
   7668 
   7669         if( M4NO_ERROR != err )
   7670         {
   7671             M4OSA_TRACE1_1(
   7672                 "M4MCS_intStepBeginVideoJump: H264MCS_ProcessSPS_PPS returns 0x%x!",
   7673                 err);
   7674             return err;
   7675         }
   7676 
   7677 
   7678         // Restore jump time for safety, this fix should be generic
   7679 
   7680         iCts = iCtsOri;
   7681 
   7682 
   7683     }
   7684     /* - CRLV6775 -H.264 Trimming */
   7685 
   7686     /**
   7687     * Decode one step */
   7688     pC->dViDecCurrentCts = (M4OSA_Double)(iCts + pC->iVideoBeginDecIncr);
   7689 
   7690     /**
   7691     * Be sure we don't decode too far */
   7692     if( pC->dViDecCurrentCts > pC->dViDecStartingCts )
   7693     {
   7694         pC->dViDecCurrentCts = pC->dViDecStartingCts;
   7695     }
   7696 
   7697     /**
   7698     * Decode at least once with the bJump flag to true */
   7699     M4OSA_TRACE3_1(
   7700         "M4VSS3GPP_intClipDecodeVideoUpToCts: Decoding upTo CTS %.3f",
   7701         pC->dViDecCurrentCts);
   7702     pC->isRenderDup = M4OSA_FALSE;
   7703     err =
   7704         pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &pC->dViDecCurrentCts,
   7705         M4OSA_TRUE, 0);
   7706 
   7707     if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err)
   7708         && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) )
   7709     {
   7710         M4OSA_TRACE1_1(
   7711             "M4MCS_intStepBeginVideoJump: m_pFctDecode returns 0x%x!", err);
   7712         return err;
   7713     }
   7714 
   7715     if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME )
   7716     {
   7717         M4OSA_TRACE2_0("Decoding output the same frame as before 1");
   7718         pC->isRenderDup = M4OSA_TRUE;
   7719     }
   7720 
   7721     /**
   7722     * Increment decoding cts for the next step */
   7723     pC->dViDecCurrentCts += (M4OSA_Double)pC->iVideoBeginDecIncr;
   7724 
   7725     /**
   7726     * Update state automaton */
   7727     if( pC->dViDecCurrentCts > pC->dViDecStartingCts )
   7728     {
   7729         /**
   7730         * Be sure we don't decode too far */
   7731         pC->dViDecCurrentCts = pC->dViDecStartingCts;
   7732         pC->State = M4MCS_kState_PROCESSING;
   7733     }
   7734     else
   7735     {
   7736         pC->State = M4MCS_kState_BEGINVIDEODECODE;
   7737     }
   7738 
   7739     /**
   7740     * Return with no error */
   7741     M4OSA_TRACE3_0("M4MCS_intStepBeginVideoJump(): returning M4NO_ERROR");
   7742     return M4NO_ERROR;
   7743 }
   7744 
   7745 /**
   7746  ******************************************************************************
   7747  * M4OSA_ERR M4MCS_intStepBeginVideoDecode(M4MCS_InternalContext* pC)
   7748  ******************************************************************************
   7749  */
   7750 static M4OSA_ERR M4MCS_intStepBeginVideoDecode( M4MCS_InternalContext *pC )
   7751 {
   7752     M4OSA_ERR err;
   7753     M4_MediaTime dDecTarget;
   7754 
   7755     if( pC->novideo )
   7756     {
   7757         pC->State = M4MCS_kState_PROCESSING;
   7758         return M4NO_ERROR;
   7759     }
   7760 
   7761     /**
   7762     * Decode */
   7763     dDecTarget = pC->dViDecCurrentCts;
   7764     M4OSA_TRACE3_1("M4MCS_intStepBeginDecode: Decoding upTo CTS %.3f",
   7765         pC->dViDecCurrentCts);
   7766     pC->isRenderDup = M4OSA_FALSE;
   7767     err = pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &dDecTarget,
   7768         M4OSA_FALSE, 0);
   7769 
   7770     if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err)
   7771         && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) )
   7772     {
   7773         M4OSA_TRACE1_1(
   7774             "M4MCS_intStepBeginVideoDecode: m_pFctDecode returns 0x%x!", err);
   7775         return err;
   7776     }
   7777 
   7778     if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME )
   7779     {
   7780         M4OSA_TRACE2_0("Decoding output the same frame as before 2");
   7781         pC->isRenderDup = M4OSA_TRUE;
   7782     }
   7783 
   7784     /**
   7785     * Increment decoding cts for the next step */
   7786     pC->dViDecCurrentCts += (M4OSA_Double)pC->iVideoBeginDecIncr;
   7787 
   7788     /**
   7789     * Update state automaton, if needed */
   7790     if( ( (M4OSA_UInt32)pC->dViDecCurrentCts > pC->dViDecStartingCts)
   7791         || (M4WAR_NO_MORE_AU == err) )
   7792     {
   7793         /**
   7794         * Be sure we don't decode too far */
   7795         pC->dViDecCurrentCts = (M4OSA_Double)pC->dViDecStartingCts;
   7796         pC->State = M4MCS_kState_PROCESSING;
   7797     }
   7798 
   7799     /**
   7800     * Return with no error */
   7801     M4OSA_TRACE3_0("M4MCS_intStepBeginVideoDecode(): returning M4NO_ERROR");
   7802     return M4NO_ERROR;
   7803 }
   7804 
   7805 /*****************************/
   7806 /* define AMR silence frames */
   7807 /*****************************/
   7808 
   7809 #define M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE 13
   7810 #define M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_DURATION 160
   7811 
   7812 #ifdef M4VSS3GPP_SILENCE_FRAMES
   7813 
   7814 const M4OSA_UInt8 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048[
   7815     M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE] =
   7816     {
   7817         0x04, 0xFF, 0x18, 0xC7, 0xF0, 0x0D, 0x04, 0x33, 0xFF, 0xE0, 0x00, 0x00, 0x00
   7818     };
   7819 #else
   7820 
   7821 extern
   7822 const
   7823 M4OSA_UInt8
   7824 M4VSS3GPP_AMR_AU_SILENCE_FRAME_048[M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE];
   7825 
   7826 #endif
   7827 
   7828 /*****************************/
   7829 /* define AAC silence frames */
   7830 /*****************************/
   7831 
   7832 #define M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE      4
   7833 
   7834 #ifdef M4VSS3GPP_SILENCE_FRAMES
   7835 
   7836 const M4OSA_UInt8 M4VSS3GPP_AAC_AU_SILENCE_MONO[
   7837     M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE] =
   7838     {
   7839         0x00, 0xC8, 0x20, 0x07
   7840     };
   7841 #else
   7842 
   7843 extern const M4OSA_UInt8
   7844 M4VSS3GPP_AAC_AU_SILENCE_MONO[M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE];
   7845 
   7846 #endif
   7847 
   7848 #define M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE        6
   7849 
   7850 #ifdef M4VSS3GPP_SILENCE_FRAMES
   7851 
   7852 const M4OSA_UInt8 M4VSS3GPP_AAC_AU_SILENCE_STEREO[
   7853     M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE] =
   7854     {
   7855         0x21, 0x10, 0x03, 0x20, 0x54, 0x1C
   7856     };
   7857 #else
   7858 
   7859 extern const
   7860 M4OSA_UInt8
   7861 M4VSS3GPP_AAC_AU_SILENCE_STEREO[M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE];
   7862 
   7863 #endif
   7864 
   7865 /**
   7866  ******************************************************************************
   7867  * M4OSA_ERR M4MCS_intAudioNullEncoding(M4MCS_InternalContext* pC)
   7868  * @return   M4NO_ERROR:         No error
   7869  ******************************************************************************
   7870  */
   7871 
   7872 static M4OSA_ERR M4MCS_intAudioNullEncoding( M4MCS_InternalContext *pC )
   7873 {
   7874     M4OSA_ERR err;
   7875 
   7876     if( pC->noaudio )
   7877         return M4NO_ERROR;
   7878 
   7879     /* Check if all audio frame has been written (happens at begin cut) */
   7880     if( pC->ReaderAudioAU.m_size == 0 )
   7881     {
   7882         /**
   7883         * Initializes a new AU if needed */
   7884         if( pC->ReaderAudioAU1.m_structSize == 0 )
   7885         {
   7886             /**
   7887             * Initializes an access Unit */
   7888             err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
   7889                 (M4_StreamHandler *)pC->pReaderAudioStream,
   7890                 &pC->ReaderAudioAU1);
   7891 
   7892             if( M4NO_ERROR != err )
   7893             {
   7894                 M4OSA_TRACE1_1(
   7895                     "M4MCS_open(): m_pReader->m_pFctFillAuStruct(audio) returns 0x%x",
   7896                     err);
   7897                 return err;
   7898             }
   7899 
   7900             pC->m_pDataAddress1 =
   7901                 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderAudioAU1.m_maxsize,
   7902                 M4MCS, (M4OSA_Char *)"Temporary AU1 buffer");
   7903 
   7904             if( pC->m_pDataAddress1 == M4OSA_NULL )
   7905             {
   7906                 M4OSA_TRACE1_0(
   7907                     "M4MCS_intAudioNullEncoding(): allocation error");
   7908                 return M4ERR_ALLOC;
   7909             }
   7910 
   7911             err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
   7912                 (M4_StreamHandler *)pC->pReaderAudioStream,
   7913                 &pC->ReaderAudioAU1);
   7914 
   7915             if( M4WAR_NO_MORE_AU == err )
   7916             {
   7917                 M4OSA_TRACE2_0(
   7918                     "M4MCS_intAudioNullEncoding():\
   7919                      m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU");
   7920                 /* The audio transcoding is finished */
   7921                 pC->AudioState = M4MCS_kStreamState_FINISHED;
   7922                 return err;
   7923             }
   7924             else if( M4NO_ERROR != err )
   7925             {
   7926                 M4OSA_TRACE1_1(
   7927                     "M4MCS_intAudioNullEncoding(): \
   7928                     m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x",
   7929                     err);
   7930                 return err;
   7931             }
   7932             /*FB 2009.04.02: PR surnxp#616: Crash in MCS while Audio AU copying ,
   7933              constant memory reader case*/
   7934             if( pC->ReaderAudioAU1.m_maxsize
   7935         > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize )
   7936             {
   7937                 /* Constant memory reader case, we need to reallocate the temporary buffers */
   7938                 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
   7939                     *) &(pC->m_pDataAddress1), pC->ReaderAudioAU1.m_maxsize);
   7940                 /* pC->m_pDataAddress1 and
   7941                 pC->m_pDataAddress2 must be reallocated at the same time */
   7942                 /* because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take
   7943                  maximum value. Then the test "if(pC->ReaderAudioAU?.m_maxsize >
   7944                   pC->pReaderAudioStream->m_basicProperties.m_maxAUSize)" is never true */
   7945                 /* and the size of the second buffer is never changed. */
   7946                 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
   7947                     *) &(pC->m_pDataAddress2), pC->ReaderAudioAU1.m_maxsize);
   7948                 /* pC->m_pDataAddress1 and
   7949                 pC->m_pDataAddress2 must be reallocated at the same time */
   7950                 /* Update stream properties */
   7951                 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize =
   7952                     pC->ReaderAudioAU1.m_maxsize;
   7953             }
   7954             /**/
   7955             memcpy((void *)pC->m_pDataAddress1,
   7956                 (void *)pC->ReaderAudioAU1.m_dataAddress,
   7957                 pC->ReaderAudioAU1.m_size);
   7958         }
   7959 
   7960         if( pC->ReaderAudioAU2.m_structSize == 0 )
   7961         {
   7962             /**
   7963             * Initializes an access Unit */
   7964             err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
   7965                 (M4_StreamHandler *)pC->pReaderAudioStream,
   7966                 &pC->ReaderAudioAU2);
   7967 
   7968             if( M4NO_ERROR != err )
   7969             {
   7970                 M4OSA_TRACE1_1(
   7971                     "M4MCS_open(): m_pReader->m_pFctFillAuStruct(audio) returns 0x%x",
   7972                     err);
   7973                 return err;
   7974             }
   7975             pC->m_pDataAddress2 =
   7976                 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderAudioAU2.m_maxsize,
   7977                 M4MCS, (M4OSA_Char *)"Temporary AU buffer");
   7978 
   7979             if( pC->m_pDataAddress2 == M4OSA_NULL )
   7980             {
   7981                 M4OSA_TRACE1_0(
   7982                     "M4MCS_intAudioNullEncoding(): allocation error");
   7983                 return M4ERR_ALLOC;
   7984             }
   7985         }
   7986         /**
   7987         * Read the next audio AU in the input file */
   7988         if( pC->ReaderAudioAU2.m_CTS > pC->ReaderAudioAU1.m_CTS )
   7989         {
   7990             memcpy((void *) &pC->ReaderAudioAU,
   7991                 (void *) &pC->ReaderAudioAU2, sizeof(M4_AccessUnit));
   7992             err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
   7993                 (M4_StreamHandler *)pC->pReaderAudioStream,
   7994                 &pC->ReaderAudioAU1);
   7995 
   7996             if( pC->ReaderAudioAU1.m_maxsize
   7997                 > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize )
   7998             {
   7999                 /* Constant memory reader case, we need to reallocate the temporary buffers */
   8000                 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
   8001                     *) &(pC->m_pDataAddress1), pC->ReaderAudioAU1.m_maxsize);
   8002                 /*   pC->m_pDataAddress1
   8003                  * and pC->m_pDataAddress2 must be reallocated at the same time *
   8004                  * because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take
   8005                  * maximum value. Then the test "if(pC->ReaderAudioAU?.m_maxsize >
   8006                  * pC->pReaderAudioStream->m_basicProperties.m_maxAUSize)" is never true *
   8007                  * and the size of the second buffer is never changed.
   8008                  */
   8009                 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
   8010                     *) &(pC->m_pDataAddress2), pC->ReaderAudioAU1.m_maxsize);
   8011                 /* pC->m_pDataAddress1 and
   8012                  * pC->m_pDataAddress2 must be reallocated at the same time
   8013                  * Update stream properties
   8014                  */
   8015                 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize =
   8016                     pC->ReaderAudioAU1.m_maxsize;
   8017             }
   8018             /**/
   8019             memcpy((void *)pC->m_pDataAddress1,
   8020                 (void *)pC->ReaderAudioAU1.m_dataAddress,
   8021                 pC->ReaderAudioAU1.m_size);
   8022             pC->m_audioAUDuration =
   8023                 pC->ReaderAudioAU1.m_CTS - pC->ReaderAudioAU2.m_CTS;
   8024             pC->ReaderAudioAU.m_dataAddress = pC->m_pDataAddress2;
   8025         }
   8026         else
   8027         {
   8028             memcpy((void *) &pC->ReaderAudioAU,
   8029                 (void *) &pC->ReaderAudioAU1, sizeof(M4_AccessUnit));
   8030             err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
   8031                 (M4_StreamHandler *)pC->pReaderAudioStream,
   8032                 &pC->ReaderAudioAU2);
   8033             /* Crash in MCS while Audio AU copying ,
   8034              * constant memory reader case
   8035              */
   8036             if( pC->ReaderAudioAU2.m_maxsize
   8037                 > pC->pReaderAudioStream->m_basicProperties.m_maxAUSize )
   8038             {
   8039                 /* Constant memory reader case, we need to reallocate the temporary buffers */
   8040                 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
   8041                     *) &(pC->m_pDataAddress2), pC->ReaderAudioAU2.m_maxsize);
   8042                 /* pC->m_pDataAddress1 and
   8043                  * pC->m_pDataAddress2 must be reallocated at the same time
   8044                  * because pC->pReaderAudioStream->m_basicProperties.m_maxAUSize take maximum
   8045                  * value. Then the test "if(pC->ReaderAudioAU?.m_maxsize > pC->pReaderAudioStream->
   8046                  * m_basicProperties.m_maxAUSize)" is never true
   8047                  * and the size of the second buffer is never changed.
   8048                  */
   8049                 M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
   8050                     *) &(pC->m_pDataAddress1), pC->ReaderAudioAU2.m_maxsize);
   8051                 /* [ END ] 20091008  JFV PR fix surnxpsw#1071: pC->m_pDataAddress1 and
   8052                  pC->m_pDataAddress2 must be reallocated at the same time */
   8053                 /* Update stream properties */
   8054                 pC->pReaderAudioStream->m_basicProperties.m_maxAUSize =
   8055                     pC->ReaderAudioAU2.m_maxsize;
   8056             }
   8057             /**/
   8058             memcpy((void *)pC->m_pDataAddress2,
   8059                 (void *)pC->ReaderAudioAU2.m_dataAddress,
   8060                 pC->ReaderAudioAU2.m_size);
   8061             pC->m_audioAUDuration =
   8062                 pC->ReaderAudioAU2.m_CTS - pC->ReaderAudioAU1.m_CTS;
   8063             pC->ReaderAudioAU.m_dataAddress = pC->m_pDataAddress1;
   8064         }
   8065 
   8066         if( M4WAR_NO_MORE_AU == err )
   8067         {
   8068             M4OSA_TRACE2_0(
   8069                 "M4MCS_intAudioNullEncoding(): \
   8070                 m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU");
   8071             /* The audio transcoding is finished */
   8072             pC->AudioState = M4MCS_kStreamState_FINISHED;
   8073             return err;
   8074         }
   8075         else if( M4NO_ERROR != err )
   8076         {
   8077             M4OSA_TRACE1_1(
   8078                 "M4MCS_intAudioNullEncoding(): \
   8079                 m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x",
   8080                 err);
   8081             return err;
   8082         }
   8083     }
   8084 
   8085     /**
   8086     * Prepare the writer AU */
   8087     err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext,
   8088         M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
   8089 
   8090     if( M4NO_ERROR != err )
   8091     {
   8092         M4OSA_TRACE1_1(
   8093             "M4MCS_intAudioNullEncoding(): pWriterDataFcts->pStartAU(Audio) returns 0x%x",
   8094             err);
   8095         return err;
   8096     }
   8097 
   8098     if( pC->uiAudioAUCount
   8099         == 0 ) /* If it is the first AU, we set it to silence
   8100         (else, errors 0x3841, 0x3847 in our AAC decoder) */
   8101     {
   8102         if( pC->InputFileProperties.AudioStreamType == M4VIDEOEDITING_kAAC
   8103             || pC->InputFileProperties.AudioStreamType
   8104             == M4VIDEOEDITING_kAACplus
   8105             || pC->InputFileProperties.AudioStreamType
   8106             == M4VIDEOEDITING_keAACplus )
   8107         {
   8108             if( pC->InputFileProperties.uiNbChannels == 1 )
   8109             {
   8110                 pC->WriterAudioAU.size = M4VSS3GPP_AAC_AU_SILENCE_MONO_SIZE;
   8111                 memcpy((void *)pC->WriterAudioAU.dataAddress,
   8112                     (void *)M4VSS3GPP_AAC_AU_SILENCE_MONO,
   8113                     pC->WriterAudioAU.size);
   8114             }
   8115             else if( pC->InputFileProperties.uiNbChannels == 2 )
   8116             {
   8117                 pC->WriterAudioAU.size = M4VSS3GPP_AAC_AU_SILENCE_STEREO_SIZE;
   8118                 memcpy((void *)pC->WriterAudioAU.dataAddress,
   8119                     (void *)M4VSS3GPP_AAC_AU_SILENCE_STEREO,
   8120                     pC->WriterAudioAU.size);
   8121             }
   8122             else
   8123             {
   8124                 /* Must never happen ...*/
   8125                 M4OSA_TRACE1_0(
   8126                     "M4MCS_intAudioNullEncoding: Bad number of channels in audio input");
   8127                 return M4MCS_ERR_INVALID_INPUT_FILE;
   8128             }
   8129         }
   8130         else if( pC->InputFileProperties.AudioStreamType
   8131             == M4VIDEOEDITING_kAMR_NB )
   8132         {
   8133             pC->WriterAudioAU.size = M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE;
   8134             memcpy((void *)pC->WriterAudioAU.dataAddress,
   8135                 (void *)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048,
   8136                 pC->WriterAudioAU.size);
   8137             /* Some remaining AMR AU needs to be copied */
   8138             if( pC->ReaderAudioAU.m_size != 0 )
   8139             {
   8140                 /* Update Writer AU */
   8141                 pC->WriterAudioAU.size += pC->ReaderAudioAU.m_size;
   8142                 memcpy((void *)(pC->WriterAudioAU.dataAddress
   8143                     + M4VSS3GPP_AMR_AU_SILENCE_FRAME_048_SIZE),
   8144                     (void *)pC->ReaderAudioAU.m_dataAddress,
   8145                     pC->ReaderAudioAU.m_size);
   8146             }
   8147         }
   8148         else
   8149         {
   8150             /*MP3 case: copy the AU*/
   8151             M4OSA_TRACE3_1(
   8152                 "M4MCS_intAudioNullEncoding(): Copying audio AU: size=%d",
   8153                 pC->ReaderAudioAU.m_size);
   8154             memcpy((void *)pC->WriterAudioAU.dataAddress,
   8155                 (void *)pC->ReaderAudioAU.m_dataAddress,
   8156                 pC->ReaderAudioAU.m_size);
   8157             pC->WriterAudioAU.size = pC->ReaderAudioAU.m_size;
   8158         }
   8159     }
   8160     else
   8161     {
   8162         /**
   8163         * Copy audio data from reader AU to writer AU */
   8164         M4OSA_TRACE3_1(
   8165             "M4MCS_intAudioNullEncoding(): Copying audio AU: size=%d",
   8166             pC->ReaderAudioAU.m_size);
   8167         memcpy((void *)pC->WriterAudioAU.dataAddress,
   8168             (void *)pC->ReaderAudioAU.m_dataAddress,
   8169             pC->ReaderAudioAU.m_size);
   8170         pC->WriterAudioAU.size = pC->ReaderAudioAU.m_size;
   8171     }
   8172 
   8173     /**
   8174     * Convert CTS unit from milliseconds to timescale */
   8175     pC->WriterAudioAU.CTS =
   8176         (M4OSA_Time)((( pC->ReaderAudioAU.m_CTS - pC->iAudioCtsOffset)
   8177         * (pC->WriterAudioStream.timeScale / 1000.0)));
   8178 
   8179     if( pC->InputFileProperties.AudioStreamType == M4VIDEOEDITING_kAMR_NB
   8180         && pC->uiAudioAUCount == 0 )
   8181     {
   8182         pC->iAudioCtsOffset -=
   8183             20; /* Duration of a silence AMR AU, to handle the duration of the added
   8184                 silence frame */
   8185     }
   8186     pC->WriterAudioAU.nbFrag = 0;
   8187     M4OSA_TRACE3_1("M4MCS_intAudioNullEncoding(): audio AU: CTS=%d ms",
   8188         pC->WriterAudioAU.CTS);
   8189 
   8190     /**
   8191     * Write it to the output file */
   8192     pC->uiAudioAUCount++;
   8193     err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext,
   8194         M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
   8195 
   8196     if( M4NO_ERROR != err )
   8197     {
   8198         M4OSA_TRACE1_1(
   8199             "M4MCS_intAudioNullEncoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x",
   8200             err);
   8201         return err;
   8202     }
   8203 
   8204     /* All the audio has been written */
   8205     pC->ReaderAudioAU.m_size = 0;
   8206 
   8207     /**
   8208     * Return with no error */
   8209     M4OSA_TRACE3_0("M4MCS_intAudioNullEncoding(): returning M4NO_ERROR");
   8210     return M4NO_ERROR;
   8211 }
   8212 
   8213 /**
   8214  ******************************************************************************
   8215  * @brief    Init Audio Transcoding
   8216  * @return   M4NO_ERROR:         No error
   8217  ******************************************************************************
   8218  */
   8219 static M4OSA_ERR M4MCS_intAudioTranscoding( M4MCS_InternalContext *pC )
   8220 {
   8221     M4OSA_ERR err;                        /**< General error */
   8222 
   8223     M4OSA_UInt32
   8224         uiBytesDec; /**< Nb of bytes available in the decoder OUT buffer */
   8225     M4OSA_UInt32
   8226         uiDecoder2Ssrc_NbBytes; /**< Nb of bytes copied into the ssrc IN buffer */
   8227 
   8228     int ssrcErr;                          /**< Error while ssrc processing */
   8229     M4OSA_UInt32 uiSsrcInSize; /**< Size in bytes of ssrc intput buffer */
   8230     M4OSA_UInt32
   8231         uiSsrcInRoom; /**< Nb of bytes available in the ssrc IN buffer */
   8232     M4OSA_MemAddr8
   8233         pSsrcInput; /**< Pointer to the good buffer location for ssrc input */
   8234     M4OSA_UInt32 uiSsrcOutSize; /**< Size in bytes of ssrc output buffer */
   8235     M4OSA_UInt32
   8236         uiBytesSsrc; /**< Nb of bytes available in the ssrc OUT buffer */
   8237 
   8238     M4OSA_UInt8
   8239         needChannelConversion; /**< Flag to indicate if a stereo <-> mono conversion is needed */
   8240     M4OSA_UInt32
   8241         uiChannelConvertorCoeff; /**< Multiplicative coefficient if stereo
   8242                                     <-> mono conversion is applied */
   8243     M4OSA_MemAddr8 pChannelConvertorInput =
   8244         M4OSA_NULL; /**< Pointer to the good buffer location for channel convertor input */
   8245     M4OSA_UInt32 uiChannelConvertorNbSamples =
   8246         0; /**< Nb of pcm samples to convert in channel convertor */
   8247     M4OSA_MemAddr8 pChannelConvertorOutput =
   8248         M4OSA_NULL; /**< Pointer to the good buffer location for channel convertor output */
   8249 
   8250     M4OSA_Time
   8251         frameTimeDelta; /**< Duration of the encoded (then written) data */
   8252     M4OSA_UInt32
   8253         uiEncoderInRoom; /**< Nb of bytes available in the encoder IN buffer */
   8254     M4OSA_UInt32
   8255         uiSsrc2Encoder_NbBytes; /**< Nb of bytes copied from the ssrc OUT buffer */
   8256     M4OSA_MemAddr8
   8257         pEncoderInput; /**< Pointer to the good buffer location for encoder input */
   8258     M4ENCODER_AudioBuffer pEncInBuffer;   /**< Encoder input buffer for api */
   8259     M4ENCODER_AudioBuffer pEncOutBuffer;  /**< Encoder output buffer for api */
   8260 
   8261     M4OSA_Int16 *tempBuffOut = M4OSA_NULL;
   8262     /*FlB 2009.03.04: apply audio effects if an effect is active*/
   8263     M4OSA_Int8 *pActiveEffectNumber = &(pC->pActiveEffectNumber);
   8264 
   8265     uint32_t errCode = M4NO_ERROR;
   8266 
   8267     if( pC->noaudio )
   8268         return M4NO_ERROR;
   8269 
   8270     /* _________________ */
   8271     /*|                 |*/
   8272     /*| READ AND DECODE |*/
   8273     /*|_________________|*/
   8274 
   8275     /* Check if we have to empty the decoder out buffer first */
   8276     if( M4OSA_NULL != pC->pPosInDecBufferOut )
   8277     {
   8278         goto m4mcs_intaudiotranscoding_feed_resampler;
   8279     }
   8280 
   8281     err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt,
   8282         M4OSA_NULL, &pC->AudioDecBufferOut, M4OSA_FALSE);
   8283 
   8284 
   8285     if( M4NO_ERROR != err )
   8286     {
   8287         M4OSA_TRACE1_1(
   8288             "M4MCS_intAudioTranscoding(): m_pAudioDecoder->m_pFctStepAudio returns 0x%x",
   8289             err);
   8290         return err;
   8291     }
   8292 
   8293 #ifdef MCS_DUMP_PCM_TO_FILE
   8294 
   8295     fwrite(pC->AudioDecBufferOut.m_dataAddress,
   8296         pC->AudioDecBufferOut.m_bufferSize, 1, file_pcm_decoder);
   8297 
   8298 #endif
   8299 
   8300     pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt,
   8301            M4AD_kOptionID_GetAudioAUErrCode, (M4OSA_DataOption) &errCode);
   8302 
   8303     if ( M4WAR_NO_MORE_AU == errCode ) {
   8304         pC->AudioState = M4MCS_kStreamState_FINISHED;
   8305             M4OSA_TRACE2_0(
   8306                 "M4MCS_intAudioTranscoding():\
   8307                  m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU");
   8308             return errCode;
   8309    }
   8310 
   8311     /* Set the current position in the decoder out buffer */
   8312     pC->pPosInDecBufferOut = pC->AudioDecBufferOut.m_dataAddress;
   8313 
   8314     /* ________________ */
   8315     /*|                |*/
   8316     /*| FEED RESAMPLER |*/
   8317     /*|________________|*/
   8318 
   8319 m4mcs_intaudiotranscoding_feed_resampler:
   8320 
   8321     /* Check if we have to empty the ssrc out buffer first */
   8322     if( M4OSA_NULL != pC->pPosInSsrcBufferOut )
   8323     {
   8324         goto m4mcs_intaudiotranscoding_prepare_input_buffer;
   8325     }
   8326 
   8327     /* Compute number of bytes remaining in the decoder buffer */
   8328     uiSsrcInSize = pC->iSsrcNbSamplIn * sizeof(short)
   8329         * pC->pReaderAudioStream->m_nbChannels;
   8330     uiBytesDec = ( pC->AudioDecBufferOut.m_dataAddress
   8331         + pC->AudioDecBufferOut.m_bufferSize) - pC->pPosInDecBufferOut;
   8332 
   8333     /* Check if we can feed directly the Ssrc with the decoder out buffer */
   8334     if( ( pC->pPosInSsrcBufferIn == pC->pSsrcBufferIn)
   8335         && (uiBytesDec >= uiSsrcInSize) )
   8336     {
   8337         pSsrcInput = pC->pPosInDecBufferOut;
   8338 
   8339         /* update data consumed into decoder buffer after resampling */
   8340         if( uiBytesDec == uiSsrcInSize )
   8341             pC->pPosInDecBufferOut = M4OSA_NULL;
   8342         else
   8343             pC->pPosInDecBufferOut += uiSsrcInSize;
   8344 
   8345         goto m4mcs_intaudiotranscoding_do_resampling;
   8346     }
   8347 
   8348     /**
   8349     * Compute remaining space in Ssrc buffer in */
   8350     uiSsrcInRoom = ( pC->pSsrcBufferIn + uiSsrcInSize) - pC->pPosInSsrcBufferIn;
   8351 
   8352     /**
   8353     * Nb of bytes copied is the minimum between nb of bytes remaining in
   8354     * decoder out buffer and space remaining in ssrc in buffer */
   8355     uiDecoder2Ssrc_NbBytes =
   8356         (uiSsrcInRoom < uiBytesDec) ? uiSsrcInRoom : uiBytesDec;
   8357 
   8358     /**
   8359     * Copy from the decoder out buffer into the Ssrc in buffer */
   8360     memcpy((void *)pC->pPosInSsrcBufferIn, (void *)pC->pPosInDecBufferOut,
   8361         uiDecoder2Ssrc_NbBytes);
   8362 
   8363     /**
   8364     * Update the position in the decoder out buffer */
   8365     pC->pPosInDecBufferOut += uiDecoder2Ssrc_NbBytes;
   8366 
   8367     /**
   8368     * Update the position in the Ssrc in buffer */
   8369     pC->pPosInSsrcBufferIn += uiDecoder2Ssrc_NbBytes;
   8370 
   8371     /**
   8372     * Check if the decoder buffer out is empty */
   8373     if( ( pC->pPosInDecBufferOut - pC->AudioDecBufferOut.m_dataAddress)
   8374         == (M4OSA_Int32)pC->AudioDecBufferOut.m_bufferSize )
   8375     {
   8376         pC->pPosInDecBufferOut = M4OSA_NULL;
   8377     }
   8378 
   8379     /* Check if the Ssrc in buffer is ready (= full) */
   8380     if( ( pC->pPosInSsrcBufferIn - pC->pSsrcBufferIn)
   8381         < (M4OSA_Int32)uiSsrcInSize )
   8382     {
   8383         goto m4mcs_intaudiotranscoding_end;
   8384     }
   8385 
   8386     pSsrcInput = pC->pSsrcBufferIn;
   8387 
   8388     /* update data consumed into ssrc buffer in after resampling (empty) */
   8389     pC->pPosInSsrcBufferIn = pC->pSsrcBufferIn;
   8390 
   8391     /* ___________________ */
   8392     /*|                   |*/
   8393     /*| DO THE RESAMPLING |*/
   8394     /*|___________________|*/
   8395 
   8396 m4mcs_intaudiotranscoding_do_resampling:
   8397 
   8398     /**
   8399     * No need for memcopy, we can feed Ssrc directly with the data in the audio
   8400     decoder out buffer*/
   8401 
   8402     ssrcErr = 0;
   8403 
   8404     if( pC->pReaderAudioStream->m_nbChannels == 1 )
   8405     {
   8406         tempBuffOut =
   8407             (short *)M4OSA_32bitAlignedMalloc((pC->iSsrcNbSamplOut * sizeof(short) * 2
   8408             * ((*pC).InputFileProperties).uiNbChannels),
   8409             M4VSS3GPP,(M4OSA_Char *) "tempBuffOut");
   8410         memset((void *)tempBuffOut, 0,(pC->iSsrcNbSamplOut * sizeof(short) * 2
   8411             * ((*pC).InputFileProperties).uiNbChannels));
   8412 
   8413         LVAudioresample_LowQuality((short *)tempBuffOut, (short *)pSsrcInput,
   8414             pC->iSsrcNbSamplOut, pC->pLVAudioResampler);
   8415     }
   8416     else
   8417     {
   8418         memset((void *)pC->pSsrcBufferOut, 0, (pC->iSsrcNbSamplOut * sizeof(short)
   8419             * ((*pC).InputFileProperties).uiNbChannels));
   8420 
   8421         LVAudioresample_LowQuality((short *)pC->pSsrcBufferOut,
   8422             (short *)pSsrcInput, pC->iSsrcNbSamplOut, pC->pLVAudioResampler);
   8423     }
   8424 
   8425     if( pC->pReaderAudioStream->m_nbChannels == 1 )
   8426     {
   8427         From2iToMono_16((short *)tempBuffOut, (short *)pC->pSsrcBufferOut,
   8428             (short)pC->iSsrcNbSamplOut);
   8429         free(tempBuffOut);
   8430     }
   8431 
   8432 
   8433     if( 0 != ssrcErr )
   8434     {
   8435         M4OSA_TRACE1_1(
   8436             "M4MCS_intAudioTranscoding: SSRC_Process returns 0x%x, \
   8437             returning M4MCS_ERR_AUDIO_CONVERSION_FAILED",
   8438             ssrcErr);
   8439         return M4MCS_ERR_AUDIO_CONVERSION_FAILED;
   8440     }
   8441 
   8442     pC->pPosInSsrcBufferOut = pC->pSsrcBufferOut;
   8443 
   8444     /* ______________________ */
   8445     /*|                      |*/
   8446     /*| PREPARE INPUT BUFFER |*/
   8447     /*|______________________|*/
   8448 
   8449 m4mcs_intaudiotranscoding_prepare_input_buffer:
   8450 
   8451     /* Set the flag for channel conversion requirement */
   8452     if( ( pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
   8453         && (pC->pReaderAudioStream->m_nbChannels == 2) )
   8454     {
   8455         needChannelConversion = 1;
   8456         uiChannelConvertorCoeff = 4;
   8457     }
   8458     else if( ( pC->AudioEncParams.ChannelNum == M4ENCODER_kStereo)
   8459         && (pC->pReaderAudioStream->m_nbChannels == 1) )
   8460     {
   8461         needChannelConversion = 2;
   8462         uiChannelConvertorCoeff = 1;
   8463     }
   8464     else
   8465     {
   8466         needChannelConversion = 0;
   8467         uiChannelConvertorCoeff = 2;
   8468     }
   8469 
   8470     /* Compute number of bytes remaining in the Ssrc buffer */
   8471     uiSsrcOutSize = pC->iSsrcNbSamplOut * sizeof(short)
   8472         * pC->pReaderAudioStream->m_nbChannels;
   8473     uiBytesSsrc =
   8474         ( pC->pSsrcBufferOut + uiSsrcOutSize) - pC->pPosInSsrcBufferOut;
   8475 
   8476     /* Check if the ssrc buffer is full */
   8477     if( pC->pPosInSsrcBufferOut == pC->pSsrcBufferOut )
   8478     {
   8479         uiSsrc2Encoder_NbBytes =
   8480             pC->audioEncoderGranularity * uiChannelConvertorCoeff / 2;
   8481 
   8482         /* Check if we can feed directly the encoder with the ssrc out buffer */
   8483         if( ( pC->pPosInAudioEncoderBuffer == M4OSA_NULL)
   8484             && (uiBytesSsrc >= uiSsrc2Encoder_NbBytes) )
   8485         {
   8486             /* update position in ssrc out buffer after encoding */
   8487             if( uiBytesSsrc == uiSsrc2Encoder_NbBytes )
   8488                 pC->pPosInSsrcBufferOut = M4OSA_NULL;
   8489             else
   8490                 pC->pPosInSsrcBufferOut += uiSsrc2Encoder_NbBytes;
   8491 
   8492             /* mark the encoder buffer ready (= full) */
   8493             pC->pPosInAudioEncoderBuffer =
   8494                 pC->pAudioEncoderBuffer + pC->audioEncoderGranularity;
   8495 
   8496             if( needChannelConversion > 0 )
   8497             {
   8498                 /* channel convertor writes directly into encoder buffer */
   8499                 pEncoderInput = pC->pAudioEncoderBuffer;
   8500 
   8501                 pChannelConvertorInput = pC->pSsrcBufferOut;
   8502                 pChannelConvertorOutput = pC->pAudioEncoderBuffer;
   8503                 uiChannelConvertorNbSamples =
   8504                     uiSsrc2Encoder_NbBytes / sizeof(short);
   8505 
   8506                 goto m4mcs_intaudiotranscoding_channel_convertor;
   8507             }
   8508             else
   8509             {
   8510                 /* encode directly from ssrc out buffer */
   8511                 pEncoderInput = pC->pSsrcBufferOut;
   8512 
   8513                 goto m4mcs_intaudiotranscoding_encode_and_write;
   8514             }
   8515         }
   8516     }
   8517 
   8518     /**
   8519     * Compute remaining space in encoder buffer in */
   8520     if( pC->pPosInAudioEncoderBuffer == M4OSA_NULL )
   8521     {
   8522         pC->pPosInAudioEncoderBuffer = pC->pAudioEncoderBuffer;
   8523     }
   8524 
   8525     uiEncoderInRoom = ( pC->pAudioEncoderBuffer + pC->audioEncoderGranularity)
   8526         - pC->pPosInAudioEncoderBuffer;
   8527     pEncoderInput = pC->pAudioEncoderBuffer;
   8528 
   8529     /**
   8530     * Nb of bytes copied is the minimum between nb of bytes remaining in
   8531     * decoder out buffer and space remaining in ssrc in buffer */
   8532     uiSsrc2Encoder_NbBytes =
   8533         (( uiEncoderInRoom * uiChannelConvertorCoeff / 2) < uiBytesSsrc)
   8534         ? (uiEncoderInRoom * uiChannelConvertorCoeff / 2) : uiBytesSsrc;
   8535 
   8536     if( needChannelConversion > 0 )
   8537     {
   8538         /* channel convertor writes directly into encoder buffer */
   8539         pChannelConvertorInput = pC->pPosInSsrcBufferOut;
   8540         pChannelConvertorOutput = pC->pPosInAudioEncoderBuffer;
   8541         uiChannelConvertorNbSamples = uiSsrc2Encoder_NbBytes / sizeof(short);
   8542     }
   8543     else
   8544     {
   8545         /* copy from the ssrc out buffer into the encoder in buffer */
   8546         memcpy((void *)pC->pPosInAudioEncoderBuffer, (void *)pC->pPosInSsrcBufferOut,
   8547             uiSsrc2Encoder_NbBytes);
   8548     }
   8549 
   8550     /* Update position in ssrc out buffer after encoding */
   8551     pC->pPosInSsrcBufferOut += uiSsrc2Encoder_NbBytes;
   8552 
   8553     /* Update the position in the encoder in buffer */
   8554     pC->pPosInAudioEncoderBuffer +=
   8555         uiSsrc2Encoder_NbBytes * 2 / uiChannelConvertorCoeff;
   8556 
   8557     /* Check if the ssrc buffer out is empty */
   8558     if( ( pC->pPosInSsrcBufferOut - pC->pSsrcBufferOut)
   8559         == (M4OSA_Int32)uiSsrcOutSize )
   8560     {
   8561         pC->pPosInSsrcBufferOut = M4OSA_NULL;
   8562     }
   8563 
   8564     /* go to next statement */
   8565     if( needChannelConversion > 0 )
   8566         goto m4mcs_intaudiotranscoding_channel_convertor;
   8567     else
   8568         goto m4mcs_intaudiotranscoding_encode_and_write;
   8569 
   8570     /* _________________ */
   8571     /*|                 |*/
   8572     /*| STEREO <-> MONO |*/
   8573     /*|_________________|*/
   8574 
   8575 m4mcs_intaudiotranscoding_channel_convertor:
   8576 
   8577     /* convert the input pcm stream to mono or to stereo */
   8578     switch( needChannelConversion )
   8579     {
   8580         case 1: /* stereo to mono */
   8581             From2iToMono_16((short *)pChannelConvertorInput,
   8582                 (short *)pChannelConvertorOutput,
   8583                 (short)(uiChannelConvertorNbSamples / 2));
   8584             break;
   8585 
   8586         case 2: /* mono to stereo */
   8587             MonoTo2I_16((short *)pChannelConvertorInput,
   8588                 (short *)pChannelConvertorOutput,
   8589                 (short)uiChannelConvertorNbSamples);
   8590             break;
   8591     }
   8592 
   8593     /* __________________ */
   8594     /*|                  |*/
   8595     /*| ENCODE AND WRITE |*/
   8596     /*|__________________|*/
   8597 
   8598 m4mcs_intaudiotranscoding_encode_and_write:
   8599 
   8600     /* Check if the encoder in buffer is ready (= full) */
   8601     if( ( pC->pPosInAudioEncoderBuffer - pC->pAudioEncoderBuffer)
   8602         < (M4OSA_Int32)pC->audioEncoderGranularity )
   8603     {
   8604         goto m4mcs_intaudiotranscoding_end;
   8605     }
   8606 
   8607     /* [Mono] or [Stereo interleaved] : all is in one buffer */
   8608     pEncInBuffer.pTableBuffer[0] = pEncoderInput;
   8609     pEncInBuffer.pTableBufferSize[0] = pC->audioEncoderGranularity;
   8610     pEncInBuffer.pTableBuffer[1] = M4OSA_NULL;
   8611     pEncInBuffer.pTableBufferSize[1] = 0;
   8612 
   8613     /* Time in ms from data size, because it is PCM16 samples */
   8614     frameTimeDelta =
   8615         ( pEncInBuffer.pTableBufferSize[0] * uiChannelConvertorCoeff / 2)
   8616         / sizeof(short) / pC->pReaderAudioStream->m_nbChannels;
   8617 
   8618     /**
   8619     * Prepare the writer AU */
   8620     err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext,
   8621         M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
   8622 
   8623     if( M4NO_ERROR != err )
   8624     {
   8625         M4OSA_TRACE1_1(
   8626             "M4MCS_intAudioTranscoding(): pWriterDataFcts->pStartAU(Audio) returns 0x%x",
   8627             err);
   8628         return err;
   8629     }
   8630 
   8631     /*FlB 2009.03.04: apply audio effects if an effect is active*/
   8632     if( *pActiveEffectNumber >= 0 && *pActiveEffectNumber < pC->nbEffects )
   8633     {
   8634         if( pC->pEffects[*pActiveEffectNumber].ExtAudioEffectFct != M4OSA_NULL )
   8635         {
   8636             M4MCS_ExternalProgress pProgress;
   8637             M4OSA_UInt32 tempProgress = 0;
   8638             pProgress.uiClipTime = (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS;
   8639 
   8640             pProgress.uiOutputTime = ( pC->WriterAudioAU.CTS * 1000)
   8641                 / pC->WriterAudioStream.timeScale;
   8642             tempProgress = ( (M4OSA_UInt32)pC->ReaderAudioAU.m_CTS
   8643                 - pC->pEffects[*pActiveEffectNumber].uiStartTime
   8644                 - pC->uiBeginCutTime) * 1000;
   8645             pProgress.uiProgress =
   8646                 (M4OSA_UInt32)(tempProgress / (M4OSA_UInt32)pC->pEffects[
   8647                     *pActiveEffectNumber].uiDuration);
   8648 
   8649                     err = pC->pEffects[*pActiveEffectNumber].ExtAudioEffectFct(
   8650                         pC->pEffects[*pActiveEffectNumber].pExtAudioEffectFctCtxt,
   8651                         (M4OSA_Int16 *)pEncInBuffer.pTableBuffer[0],
   8652                         pEncInBuffer.pTableBufferSize[0], &pProgress);
   8653 
   8654                     if( err != M4NO_ERROR )
   8655                     {
   8656                         M4OSA_TRACE1_1(
   8657                             "M4MCS_intAudioTranscoding(): ExtAudioEffectFct() returns 0x%x",
   8658                             err);
   8659                         return err;
   8660                     }
   8661         }
   8662     }
   8663 
   8664     /**
   8665     * Prepare output buffer */
   8666     pEncOutBuffer.pTableBuffer[0] =
   8667         (M4OSA_MemAddr8)pC->WriterAudioAU.dataAddress;
   8668     pEncOutBuffer.pTableBufferSize[0] = 0;
   8669 
   8670 #ifdef MCS_DUMP_PCM_TO_FILE
   8671 
   8672     fwrite(pEncInBuffer.pTableBuffer[0], pEncInBuffer.pTableBufferSize[0], 1,
   8673         file_pcm_encoder);
   8674 
   8675 #endif
   8676 
   8677     if( M4OSA_FALSE == pC->b_isRawWriter )
   8678     {
   8679         /* This allow to write PCM data to file and to encode AMR data,
   8680          when output file is not RAW */
   8681         if( pC->pOutputPCMfile != M4OSA_NULL )
   8682         {
   8683             pC->pOsaFileWritPtr->writeData(pC->pOutputPCMfile,
   8684                 pEncInBuffer.pTableBuffer[0], pEncInBuffer.pTableBufferSize[0]);
   8685         }
   8686 
   8687         /**
   8688         * Encode the PCM audio */
   8689         err = pC->pAudioEncoderGlobalFcts->pFctStep(pC->pAudioEncCtxt,
   8690             &pEncInBuffer, &pEncOutBuffer);
   8691 
   8692         if( M4NO_ERROR != err )
   8693         {
   8694             M4OSA_TRACE1_1(
   8695                 "M4MCS_intAudioTranscoding(): pAudioEncoderGlobalFcts->pFctStep returns 0x%x",
   8696                 err);
   8697             return err;
   8698         }
   8699 
   8700         /* update data consumed into encoder buffer in after encoding (empty) */
   8701         pC->pPosInAudioEncoderBuffer = M4OSA_NULL;
   8702 
   8703         /**
   8704         * Set AU cts and size */
   8705         pC->WriterAudioAU.size =
   8706             pEncOutBuffer.
   8707             pTableBufferSize[0]; /**< Get the size of encoded data */
   8708         pC->WriterAudioAU.CTS += frameTimeDelta;
   8709 
   8710         /**
   8711         * Update duration of the encoded AU */
   8712         pC->m_audioAUDuration =
   8713             ( frameTimeDelta * 1000) / pC->WriterAudioStream.timeScale;
   8714 
   8715         /**
   8716         * Write the encoded AU to the output file */
   8717         pC->uiAudioAUCount++;
   8718         err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext,
   8719             M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
   8720 
   8721         if( M4NO_ERROR != err )
   8722         {
   8723             M4OSA_TRACE1_1(
   8724                 "M4MCS_intAudioTranscoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x",
   8725                 err);
   8726             return err;
   8727         }
   8728     }
   8729     else
   8730     {
   8731         /* update data consumed into encoder buffer in after encoding (empty) */
   8732         pC->pPosInAudioEncoderBuffer = M4OSA_NULL;
   8733 
   8734         pC->WriterAudioAU.dataAddress =
   8735             (M4OSA_MemAddr32)
   8736             pEncoderInput; /* will be converted back to u8* in file write */
   8737         pC->WriterAudioAU.size = pC->audioEncoderGranularity;
   8738         pC->uiAudioAUCount++;
   8739 
   8740         err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext,
   8741             M4MCS_WRITER_AUDIO_STREAM_ID, &pC->WriterAudioAU);
   8742 
   8743         if( M4NO_ERROR != err )
   8744         {
   8745             M4OSA_TRACE1_1(
   8746                 "M4MCS_intAudioTranscoding(): pWriterDataFcts->pProcessAU(Audio) returns 0x%x",
   8747                 err);
   8748             return err;
   8749         }
   8750     }
   8751 
   8752     /* _______________ */
   8753     /*|               |*/
   8754     /*| ONE PASS DONE |*/
   8755     /*|_______________|*/
   8756 
   8757 m4mcs_intaudiotranscoding_end:
   8758 
   8759     /**
   8760     * Return with no error */
   8761     M4OSA_TRACE3_0("M4MCS_intAudioTranscoding(): returning M4NO_ERROR");
   8762     return M4NO_ERROR;
   8763 }
   8764 
   8765 /**
   8766  ******************************************************************************
   8767  * M4OSA_ERR M4MCS_intReallocTemporaryAU(M4OSA_MemAddr8* addr, M4OSA_UInt32 newSize)
   8768  * Used only in case of 3GP constant memory reader, to be able to realloc temporary AU
   8769  * because max AU size can be reevaluated during reading
   8770  * @return   M4NO_ERROR:         No error
   8771  ******************************************************************************
   8772  */
   8773 static M4OSA_ERR M4MCS_intReallocTemporaryAU( M4OSA_MemAddr8 *addr,
   8774                                              M4OSA_UInt32 newSize )
   8775 {
   8776     if( *addr != M4OSA_NULL )
   8777     {
   8778         free(*addr);
   8779         *addr = (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(newSize, M4MCS,
   8780             (M4OSA_Char *)"Reallocation of temporary AU buffer");
   8781 
   8782         if( *addr == M4OSA_NULL )
   8783         {
   8784             return M4ERR_ALLOC;
   8785         }
   8786     }
   8787 
   8788     return M4NO_ERROR;
   8789 }
   8790 
   8791 /**
   8792  ******************************************************************************
   8793  * M4OSA_ERR M4MCS_intVideoNullEncoding(M4MCS_InternalContext* pC)
   8794  * @author   Alexis Vapillon (NXP Software Vision)
   8795  * @return   M4NO_ERROR:         No error
   8796  ******************************************************************************
   8797  */
   8798 static M4OSA_ERR M4MCS_intVideoNullEncoding( M4MCS_InternalContext *pC )
   8799 {
   8800     M4OSA_ERR err = M4NO_ERROR;
   8801     /* Duration of the AU (find the next AU duration
   8802      * to obtain a more precise video end cut)
   8803      */
   8804     M4OSA_UInt32 videoAUDuration = 0;
   8805 
   8806     M4OSA_MemAddr8 WritebufferAdd = M4OSA_NULL;
   8807     M4OSA_Int32 lastdecodedCTS = 0;
   8808     M4_AccessUnit lReaderVideoAU; /**< Read video access unit */
   8809 
   8810     if( pC->novideo )
   8811         return M4NO_ERROR;
   8812 
   8813     /* H.264 Trimming */
   8814     if( ( ( pC->bH264Trim == M4OSA_TRUE)
   8815         && (pC->uiVideoAUCount < pC->m_pInstance->clip_sps.num_ref_frames)
   8816         && (pC->uiBeginCutTime > 0))
   8817         || (( pC->uiVideoAUCount == 0) && (pC->uiBeginCutTime > 0)) )
   8818     {
   8819         err = M4MCS_intVideoTranscoding(pC);
   8820         return err;
   8821     }
   8822 
   8823 
   8824     if((pC->bLastDecodedFrameCTS == M4OSA_FALSE) && (pC->uiBeginCutTime > 0))
   8825     {
   8826         // StageFright encoder does prefetch, the one frame we requested will not be written until
   8827         // the encoder is closed, so do it now rather than in MCS_close
   8828         if( ( M4NO_ERROR != err)
   8829             || (M4MCS_kEncoderRunning != pC->encoderState) )
   8830         {
   8831             M4OSA_TRACE1_2(
   8832                 "!!! M4MCS_intVideoNullEncoding ERROR : M4MCS_intVideoTranscoding "
   8833                 "returns 0x%X w/ encState=%d", err, pC->encoderState);
   8834 
   8835             return err;
   8836         }
   8837 
   8838         /* Stop and close the encoder now to flush the frame (prefetch) */
   8839         if( pC->pVideoEncoderGlobalFcts->pFctStop != M4OSA_NULL )
   8840         {
   8841             err = pC->pVideoEncoderGlobalFcts->pFctStop(pC->pViEncCtxt);
   8842 
   8843             if( M4NO_ERROR != err )
   8844             {
   8845                 M4OSA_TRACE1_1(
   8846                     "!!! M4MCS_intVideoNullEncoding ERROR : encoder stop returns 0x%X",
   8847                     err);
   8848                 return err;
   8849             }
   8850         }
   8851         pC->encoderState = M4MCS_kEncoderStopped;
   8852         err = pC->pVideoEncoderGlobalFcts->pFctClose(pC->pViEncCtxt);
   8853 
   8854         if( M4NO_ERROR != err )
   8855         {
   8856             M4OSA_TRACE1_1(
   8857                 "!!! M4MCS_intVideoNullEncoding ERROR : encoder close returns 0x%X",
   8858                 err);
   8859             return err;
   8860         }
   8861         pC->encoderState = M4MCS_kEncoderClosed;
   8862     }
   8863 
   8864 
   8865     if ((pC->EncodingVideoFormat = M4ENCODER_kNULL)
   8866         && (pC->bLastDecodedFrameCTS == M4OSA_FALSE)
   8867         && (pC->uiBeginCutTime > 0)) {
   8868 
   8869         pC->bLastDecodedFrameCTS = M4OSA_TRUE;
   8870         err = pC->m_pVideoDecoder->m_pFctGetOption(pC->pViDecCtxt,
   8871             M4DECODER_kOptionID_AVCLastDecodedFrameCTS, &lastdecodedCTS);
   8872 
   8873         if (M4NO_ERROR != err) {
   8874             M4OSA_TRACE1_1(
   8875                 "M4MCS_intVideoNullEncoding: m_pVideoDecoder->m_pFctGetOption returns 0x%x!",
   8876                 err);
   8877             return err;
   8878         }
   8879         /* Do not need video decoder any more, need to destroy it. Otherwise it
   8880          * will call reader function which will cause frame lost during triming,
   8881          * since the 3gp reader is shared between MCS and decoder.*/
   8882         if (M4OSA_NULL != pC->pViDecCtxt) {
   8883             err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt);
   8884             pC->pViDecCtxt = M4OSA_NULL;
   8885 
   8886             if (M4NO_ERROR != err) {
   8887                 M4OSA_TRACE1_1(
   8888                     "M4MCS_intVideoNullEncoding: decoder pFctDestroy returns 0x%x",
   8889                     err);
   8890                 return err;
   8891             }
   8892         }
   8893 
   8894         err = pC->m_pReader->m_pFctJump(pC->pReaderContext,
   8895             (M4_StreamHandler *)pC->pReaderVideoStream, &lastdecodedCTS);
   8896 
   8897         if (M4NO_ERROR != err) {
   8898             M4OSA_TRACE1_1(
   8899                 "M4MCS_intVideoNullEncoding: m_pFctJump(V) returns 0x%x!",
   8900                 err);
   8901             return err;
   8902         }
   8903 
   8904 
   8905         /* Initializes an access Unit */
   8906 
   8907         err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
   8908             (M4_StreamHandler *)pC->pReaderVideoStream, &lReaderVideoAU);
   8909 
   8910         if (M4NO_ERROR != err) {
   8911             M4OSA_TRACE1_1(
   8912                 "M4MCS_intVideoNullEncoding:m_pReader->m_pFctFillAuStruct(video)\
   8913                 returns 0x%x", err);
   8914             return err;
   8915         }
   8916 
   8917         err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
   8918             (M4_StreamHandler *)pC->pReaderVideoStream, &lReaderVideoAU);
   8919 
   8920         if (M4WAR_NO_MORE_AU == err) {
   8921             M4OSA_TRACE2_0(
   8922                 "M4MCS_intVideoNullEncoding():\
   8923                  m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU");
   8924             /* The audio transcoding is finished */
   8925             pC->VideoState = M4MCS_kStreamState_FINISHED;
   8926             return err;
   8927         }
   8928         else if (M4NO_ERROR != err) {
   8929             M4OSA_TRACE1_1(
   8930                 "M4MCS_intVideoNullEncoding():\
   8931                  m_pReaderDataIt->m_pFctGetNextAu(video) returns 0x%x",
   8932                 err);
   8933             return err;
   8934         }
   8935 
   8936         M4OSA_TRACE1_1(
   8937             "### [TS_CHECK] M4MCS_intVideoNullEncoding  video AU CTS: %d ",
   8938             lReaderVideoAU.m_CTS);
   8939 
   8940 
   8941     }
   8942 
   8943 
   8944     pC->bLastDecodedFrameCTS = M4OSA_TRUE;
   8945 
   8946 
   8947     /* Find the next AU duration to obtain a more precise video end cut*/
   8948     /**
   8949     * Initializes a new AU if needed */
   8950 
   8951     if (pC->ReaderVideoAU1.m_structSize == 0) {
   8952         /**
   8953         * Initializes an access Unit */
   8954         err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
   8955             (M4_StreamHandler *)pC->pReaderVideoStream,
   8956             &pC->ReaderVideoAU1);
   8957 
   8958         if (M4NO_ERROR != err) {
   8959             M4OSA_TRACE1_1(
   8960                 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
   8961                 err);
   8962             return err;
   8963         }
   8964 
   8965         pC->m_pDataVideoAddress1 =
   8966             (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderVideoAU1.m_maxsize, M4MCS,
   8967             (M4OSA_Char *)"Temporary video AU1 buffer");
   8968 
   8969         if (pC->m_pDataVideoAddress1 == M4OSA_NULL) {
   8970             M4OSA_TRACE1_0("M4MCS_intVideoNullEncoding(): allocation error");
   8971             return M4ERR_ALLOC;
   8972         }
   8973 
   8974         err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
   8975             (M4_StreamHandler *)pC->pReaderVideoStream,
   8976             &pC->ReaderVideoAU1);
   8977 
   8978         if( M4WAR_NO_MORE_AU == err )
   8979         {
   8980             M4OSA_TRACE2_0(
   8981                 "M4MCS_intVideoNullEncoding():\
   8982                  m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU");
   8983             /* The audio transcoding is finished */
   8984             pC->VideoState = M4MCS_kStreamState_FINISHED;
   8985             return err;
   8986         }
   8987         else if( M4NO_ERROR != err )
   8988         {
   8989             M4OSA_TRACE1_1(
   8990                 "M4MCS_intVideoNullEncoding(): m_pReaderDataIt->m_pFctGetNextAu(video)\
   8991                  returns 0x%x", err);
   8992             return err;
   8993         }
   8994 
   8995         if( pC->ReaderVideoAU1.m_maxsize
   8996             > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize )
   8997         {
   8998             /* Constant memory reader case, we need to reallocate the temporary buffers */
   8999             M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
   9000                 *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU1.m_maxsize);
   9001             /* pC->m_pDataVideoAddress1
   9002             and pC->m_pDataVideoAddress2 must be reallocated at the same time */
   9003             /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value.
   9004              Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream->
   9005              m_basicProperties.m_maxAUSize)" is never true */
   9006             /* and the size of the second buffer is never changed. */
   9007             M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
   9008                 *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU1.m_maxsize);
   9009             /* pC->m_pDataVideoAddress1 and
   9010             pC->m_pDataVideoAddress2 must be reallocated at the same time */
   9011             /* Update stream properties */
   9012             pC->pReaderVideoStream->m_basicProperties.m_maxAUSize =
   9013                 pC->ReaderVideoAU1.m_maxsize;
   9014         }
   9015         memcpy((void *)pC->m_pDataVideoAddress1,
   9016             (void *)pC->ReaderVideoAU1.m_dataAddress,
   9017             pC->ReaderVideoAU1.m_size);
   9018     }
   9019 
   9020     if( pC->ReaderVideoAU2.m_structSize == 0 )
   9021     {
   9022         /**
   9023         * Initializes an access Unit */
   9024         err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext,
   9025             (M4_StreamHandler *)pC->pReaderVideoStream,
   9026             &pC->ReaderVideoAU2);
   9027 
   9028         if( M4NO_ERROR != err )
   9029         {
   9030             M4OSA_TRACE1_1(
   9031                 "M4MCS_open(): m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
   9032                 err);
   9033             return err;
   9034         }
   9035         pC->m_pDataVideoAddress2 =
   9036             (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pC->ReaderVideoAU2.m_maxsize, M4MCS,
   9037             (M4OSA_Char *)"Temporary video AU buffer");
   9038 
   9039         if( pC->m_pDataVideoAddress2 == M4OSA_NULL )
   9040         {
   9041             M4OSA_TRACE1_0("M4MCS_intVideoNullEncoding(): allocation error");
   9042             return M4ERR_ALLOC;
   9043         }
   9044     }
   9045     /**
   9046     * Read the next video AU in the input file */
   9047     if( pC->ReaderVideoAU2.m_CTS > pC->ReaderVideoAU1.m_CTS )
   9048     {
   9049         memcpy((void *) &pC->ReaderVideoAU,
   9050             (void *) &pC->ReaderVideoAU2, sizeof(M4_AccessUnit));
   9051         err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
   9052             (M4_StreamHandler *)pC->pReaderVideoStream,
   9053             &pC->ReaderVideoAU1);
   9054 
   9055         if( pC->ReaderVideoAU1.m_maxsize
   9056             > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize )
   9057         {
   9058             /* Constant memory reader case, we need to reallocate the temporary buffers */
   9059             M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
   9060                 *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU1.m_maxsize);
   9061             /* pC->m_pDataVideoAddress1 and
   9062              pC->m_pDataVideoAddress2 must be reallocated at the same time */
   9063             /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value.
   9064              Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream->
   9065              m_basicProperties.m_maxAUSize)" is never true */
   9066             /* and the size of the second buffer is never changed. */
   9067             M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
   9068                 *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU1.m_maxsize);
   9069             /* pC->m_pDataVideoAddress1 and
   9070             pC->m_pDataVideoAddress2 must be reallocated at the same time */
   9071             /* Update stream properties */
   9072             pC->pReaderVideoStream->m_basicProperties.m_maxAUSize =
   9073                 pC->ReaderVideoAU1.m_maxsize;
   9074         }
   9075         memcpy((void *)pC->m_pDataVideoAddress1,
   9076             (void *)pC->ReaderVideoAU1.m_dataAddress,
   9077             pC->ReaderVideoAU1.m_size);
   9078         videoAUDuration = pC->ReaderVideoAU1.m_CTS - pC->ReaderVideoAU2.m_CTS;
   9079         pC->ReaderVideoAU.m_dataAddress = pC->m_pDataVideoAddress2;
   9080     }
   9081     else
   9082     {
   9083         memcpy((void *) &pC->ReaderVideoAU,
   9084             (void *) &pC->ReaderVideoAU1, sizeof(M4_AccessUnit));
   9085         err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext,
   9086             (M4_StreamHandler *)pC->pReaderVideoStream,
   9087             &pC->ReaderVideoAU2);
   9088 
   9089         if( pC->ReaderVideoAU2.m_maxsize
   9090             > pC->pReaderVideoStream->m_basicProperties.m_maxAUSize )
   9091         {
   9092             /* Constant memory reader case, we need to reallocate the temporary buffers */
   9093             M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
   9094                 *) &(pC->m_pDataVideoAddress2), pC->ReaderVideoAU2.m_maxsize);
   9095             /* pC->m_pDataVideoAddress1 and
   9096              pC->m_pDataVideoAddress2 must be reallocated at the same time */
   9097             /* because pC->pReaderVideoStream->m_basicProperties.m_maxAUSize take maximum value.
   9098              Then the test "if(pC->ReaderVideoAU?.m_maxsize > pC->pReaderVideoStream->
   9099              m_basicProperties.m_maxAUSize)" is never true */
   9100             /* and the size of the second buffer is never changed. */
   9101             M4MCS_intReallocTemporaryAU((M4OSA_MemAddr8
   9102                 *) &(pC->m_pDataVideoAddress1), pC->ReaderVideoAU2.m_maxsize);
   9103             /* pC->m_pDataVideoAddress1 and
   9104             pC->m_pDataVideoAddress2 must be reallocated at the same time */
   9105             /* Update stream properties */
   9106             pC->pReaderVideoStream->m_basicProperties.m_maxAUSize =
   9107                 pC->ReaderVideoAU2.m_maxsize;
   9108         }
   9109         memcpy((void *)pC->m_pDataVideoAddress2,
   9110             (void *)pC->ReaderVideoAU2.m_dataAddress,
   9111             pC->ReaderVideoAU2.m_size);
   9112         videoAUDuration = pC->ReaderVideoAU2.m_CTS - pC->ReaderVideoAU1.m_CTS;
   9113         pC->ReaderVideoAU.m_dataAddress = pC->m_pDataVideoAddress1;
   9114     }
   9115 
   9116     if( M4WAR_NO_MORE_AU == err )
   9117     {
   9118         M4OSA_TRACE2_0(
   9119             "M4MCS_intVideoNullEncoding():\
   9120              m_pReaderDataIt->m_pFctGetNextAu(video) returns M4WAR_NO_MORE_AU");
   9121         /* The video transcoding is finished */
   9122         pC->VideoState = M4MCS_kStreamState_FINISHED;
   9123         return err;
   9124     }
   9125     else if( M4NO_ERROR != err )
   9126     {
   9127         M4OSA_TRACE1_1(
   9128             "M4MCS_intVideoNullEncoding(): m_pReaderDataIt->m_pFctGetNextAu(Video) returns 0x%x",
   9129             err);
   9130         return err;
   9131     }
   9132     else
   9133     {
   9134         /**
   9135         * Prepare the writer AU */
   9136         err = pC->pWriterDataFcts->pStartAU(pC->pWriterContext,
   9137             M4MCS_WRITER_VIDEO_STREAM_ID, &pC->WriterVideoAU);
   9138 
   9139         if( M4NO_ERROR != err )
   9140         {
   9141             M4OSA_TRACE1_1(
   9142                 "M4MCS_intVideoNullEncoding(): pWriterDataFcts->pStartAU(Video) returns 0x%x",
   9143                 err);
   9144             return err;
   9145         }
   9146             /**
   9147             * Copy video data from reader AU to writer AU */
   9148             M4OSA_TRACE3_1(
   9149                 "M4MCS_intVideoNullEncoding(): Copying video AU: size=%d",
   9150                 pC->ReaderVideoAU.m_size);
   9151             /* + CRLV6775 -H.264 Trimming */
   9152             if( M4OSA_TRUE == pC->bH264Trim )
   9153             {
   9154                 if( pC->H264MCSTempBufferSize
   9155                     < (pC->ReaderVideoAU.m_size + 2048) )
   9156                 {
   9157                     pC->H264MCSTempBufferSize =
   9158                         (pC->ReaderVideoAU.m_size + 2048);
   9159 
   9160                     if( pC->H264MCSTempBuffer != M4OSA_NULL )
   9161                     {
   9162                         free(pC->H264MCSTempBuffer);
   9163                     }
   9164                     pC->H264MCSTempBuffer =
   9165                         (M4OSA_UInt8 *)M4OSA_32bitAlignedMalloc(pC->H264MCSTempBufferSize,
   9166                         M4MCS, (M4OSA_Char *)"pC->H264MCSTempBuffer");
   9167 
   9168                     if( pC->H264MCSTempBuffer == M4OSA_NULL )
   9169                     {
   9170                         M4OSA_TRACE1_0(
   9171                             "M4MCS_intVideoNullEncoding(): allocation error");
   9172                         return M4ERR_ALLOC;
   9173                     }
   9174                 }
   9175 
   9176                 pC->H264MCSTempBufferDataSize = pC->H264MCSTempBufferSize;
   9177 
   9178                 err = H264MCS_ProcessNALU(pC->m_pInstance,
   9179                     (M4OSA_UInt8 *)pC->ReaderVideoAU.m_dataAddress,
   9180                     pC->ReaderVideoAU.m_size, pC->H264MCSTempBuffer,
   9181                     (M4OSA_Int32 *)&pC->H264MCSTempBufferDataSize);
   9182 
   9183                 if( pC->m_pInstance->is_done == 1 )
   9184                 {
   9185                     M4MCS_convetFromByteStreamtoNALStream(
   9186                         (M4OSA_UInt8 *)pC->ReaderVideoAU.m_dataAddress ,
   9187                         pC->ReaderVideoAU.m_size);
   9188 
   9189                     memcpy((void *)pC->WriterVideoAU.dataAddress,
   9190                         (void *)(pC->ReaderVideoAU.m_dataAddress + 4),
   9191                         pC->ReaderVideoAU.m_size - 4);
   9192                     pC->WriterVideoAU.size = pC->ReaderVideoAU.m_size - 4;
   9193                     WritebufferAdd =
   9194                         (M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress;
   9195                 }
   9196                 else
   9197                 {
   9198                     memcpy((void *)pC->WriterVideoAU.dataAddress,
   9199                         (void *)(pC->H264MCSTempBuffer + 4),
   9200                         pC->H264MCSTempBufferDataSize - 4);
   9201                     pC->WriterVideoAU.size = pC->H264MCSTempBufferDataSize - 4;
   9202                     WritebufferAdd =
   9203                         (M4OSA_MemAddr8)pC->WriterVideoAU.dataAddress;
   9204                 }
   9205             }
   9206             /* H.264 Trimming */
   9207             else
   9208             {
   9209                 memcpy((void *)pC->WriterVideoAU.dataAddress,
   9210                     (void *)pC->ReaderVideoAU.m_dataAddress,
   9211                     pC->ReaderVideoAU.m_size);
   9212                 pC->WriterVideoAU.size = pC->ReaderVideoAU.m_size;
   9213             }
   9214             /**
   9215             * Convert CTS unit from milliseconds to timescale */
   9216             pC->WriterVideoAU.CTS =
   9217                 (M4OSA_Time)((( pC->ReaderVideoAU.m_CTS - pC->dViDecStartingCts)
   9218                 * (pC->WriterVideoStream.timeScale / 1000.0)));
   9219             pC->WriterVideoAU.nbFrag = 0;
   9220             pC->WriterVideoAU.attribute = pC->ReaderVideoAU.m_attribute;
   9221 
   9222             M4OSA_TRACE3_1("M4MCS_intVideoNullEncoding(): video AU: CTS=%d ms",
   9223                 pC->WriterVideoAU.CTS);
   9224 
   9225         /**
   9226         * Write it to the output file */
   9227         pC->uiVideoAUCount++;
   9228         err = pC->pWriterDataFcts->pProcessAU(pC->pWriterContext,
   9229             M4MCS_WRITER_VIDEO_STREAM_ID, &pC->WriterVideoAU);
   9230 
   9231         if( M4NO_ERROR != err )
   9232         {
   9233             M4OSA_TRACE1_1(
   9234                 "M4MCS_intVideoNullEncoding(): pWriterDataFcts->pProcessAU(Video) returns 0x%x",
   9235                 err);
   9236             return err;
   9237         }
   9238         /* + CRLV6775 -H.264 Trimming */
   9239         if( M4OSA_TRUE == pC->bH264Trim )
   9240         {
   9241             if( pC->m_pInstance->is_done == 1 )
   9242             {
   9243                 memcpy((void *)(WritebufferAdd - 4),
   9244                     (void *)(pC->ReaderVideoAU.m_dataAddress), 4);
   9245             }
   9246             else
   9247             {
   9248                 memcpy((void *)(WritebufferAdd - 4),
   9249                     (void *)(pC->H264MCSTempBuffer), 4);
   9250             }
   9251         } /* H.264 Trimming */
   9252     }
   9253     /**
   9254     * Check for end cut. */
   9255     /* Bug fix 11/12/2008: We absolutely want to have less or same video duration ->
   9256     (2*videoAUDuration) to have a more precise end cut*/
   9257     if( pC->ReaderVideoAU.m_CTS + (2 *videoAUDuration) > pC->uiEndCutTime )
   9258     {
   9259         pC->VideoState = M4MCS_kStreamState_FINISHED;
   9260     }
   9261 
   9262     /**
   9263     * Return with no error */
   9264     M4OSA_TRACE3_0("M4MCS_intVideoNullEncoding(): returning M4NO_ERROR");
   9265     return M4NO_ERROR;
   9266 }
   9267 
   9268 /**
   9269  ******************************************************************************
   9270  * M4OSA_ERR M4MCS_intVideoTranscoding(M4MCS_InternalContext* pC)
   9271  * @author   Alexis Vapillon (NXP Software Vision)
   9272  * @return   M4NO_ERROR:         No error
   9273  ******************************************************************************
   9274  */
   9275 static M4OSA_ERR M4MCS_intVideoTranscoding( M4MCS_InternalContext *pC )
   9276 {
   9277     M4OSA_ERR err = M4NO_ERROR;
   9278     M4_MediaTime mtTranscodedTime = 0.0;
   9279     M4ENCODER_FrameMode FrameMode;
   9280     M4OSA_Int32 derive = 0;
   9281 
   9282     /**
   9283     * Get video CTS to decode */
   9284     mtTranscodedTime = pC->dViDecCurrentCts;
   9285     FrameMode = M4ENCODER_kNormalFrame;
   9286 
   9287     /**
   9288     * Decode video */
   9289     M4OSA_TRACE3_1(
   9290         "M4MCS_intVideoTranscoding(): Calling m_pVideoDecoder->m_pFctDecode(%.2f)",
   9291         mtTranscodedTime);
   9292     pC->isRenderDup = M4OSA_FALSE;
   9293     err = pC->m_pVideoDecoder->m_pFctDecode(pC->pViDecCtxt, &mtTranscodedTime,
   9294         M4OSA_FALSE, 0);
   9295 
   9296     if( M4WAR_NO_MORE_AU == err )
   9297     {
   9298         FrameMode =
   9299             M4ENCODER_kLastFrame; /**< We will give this value to the encoder to
   9300             ask for the end of the encoding */
   9301         pC->VideoState = M4MCS_kStreamState_FINISHED;
   9302     }
   9303     else if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME )
   9304     {
   9305         M4OSA_TRACE2_0("Decoding output the same frame as before 3");
   9306         pC->isRenderDup = M4OSA_TRUE;
   9307     }
   9308     else if( M4NO_ERROR != err )
   9309     {
   9310         M4OSA_TRACE1_1(
   9311             "M4MCS_intVideoTranscoding(): m_pVideoDecoder->m_pFctDecode returns 0x%x!",
   9312             err);
   9313         return err;
   9314     }
   9315 
   9316     /**
   9317     * Check for end cut.
   9318     * We must check here if the end cut is reached, because in that case we must
   9319     * call the last encode step (-> bLastFrame set to true) */
   9320     if( ( pC->dViDecCurrentCts + pC->dCtsIncrement ) >= (pC->uiEndCutTime
   9321         + M4MCS_ABS(pC->dViDecStartingCts - pC->uiBeginCutTime)) )
   9322     {
   9323         FrameMode =
   9324             M4ENCODER_kLastFrame; /**< We will give this value to the encoder to
   9325             ask for the end of the encoding */
   9326         pC->VideoState = M4MCS_kStreamState_FINISHED;
   9327         derive = (M4OSA_Int32)(( pC->dViDecCurrentCts + pC->dCtsIncrement + 0.5)
   9328             - (pC->uiEndCutTime
   9329             + M4MCS_ABS(pC->dViDecStartingCts - pC->uiBeginCutTime)));
   9330     }
   9331 
   9332     /* Update starting CTS to have a more precise value (
   9333     the begin cut is not a real CTS)*/
   9334     if( pC->uiVideoAUCount == 0 )
   9335     {
   9336         pC->dViDecStartingCts = mtTranscodedTime;
   9337         pC->dViDecCurrentCts = pC->dViDecStartingCts;
   9338     }
   9339 
   9340     /**
   9341     * Encode video */
   9342     M4OSA_TRACE3_1(
   9343         "M4MCS_intVideoTranscoding(): Calling pVideoEncoderGlobalFcts->pFctEncode with videoCts\
   9344          = %.2f",pC->ReaderVideoAU.m_CTS);
   9345     pC->uiVideoAUCount++;
   9346     /* update the given duration (the begin cut is not a real CTS)*/
   9347     err = pC->pVideoEncoderGlobalFcts->pFctEncode(pC->pViEncCtxt, M4OSA_NULL,
   9348         (pC->dViDecCurrentCts - pC->dViDecStartingCts - (derive >> 1)),
   9349         FrameMode);
   9350 
   9351     return err;
   9352 }
   9353 
   9354 /**
   9355  ******************************************************************************
   9356  * M4OSA_ERR M4MCS_intGetInputClipProperties(M4MCS_InternalContext* pContext)
   9357  * @author   Dounya Manai (NXP Software Vision)
   9358  * @brief    Retrieve the properties of the audio and video streams from the input file.
   9359  * @param    pContext            (IN) MCS context
   9360  * @return   M4NO_ERROR:         No error
   9361  * @return   M4ERR_PARAMETER:    pContext is M4OSA_NULL (If Debug Level >= 2)
   9362  ******************************************************************************
   9363  */
   9364 static M4OSA_ERR M4MCS_intGetInputClipProperties( M4MCS_InternalContext *pC )
   9365 {
   9366     M4DECODER_MPEG4_DecoderConfigInfo DecConfInfo;
   9367     M4READER_3GP_H263Properties H263prop;
   9368     M4OSA_ERR err;
   9369     M4OSA_UInt32 videoBitrate;
   9370     M4DECODER_VideoSize videoSize;
   9371     M4_AACType iAacType = 0;
   9372 
   9373     /**
   9374     * Check input parameters */
   9375     M4OSA_DEBUG_IF2(M4OSA_NULL == pC, M4ERR_PARAMETER,
   9376         "M4MCS_intGetInputClipProperties: pC is M4OSA_NULL");
   9377 
   9378     /**
   9379     * Reset common characteristics */
   9380     pC->InputFileProperties.bAnalysed = M4OSA_FALSE;
   9381     pC->InputFileProperties.FileType = 0;
   9382     pC->InputFileProperties.Version[0] = M4VIDEOEDITING_VERSION_MAJOR;
   9383     pC->InputFileProperties.Version[1] = M4VIDEOEDITING_VERSION_MINOR;
   9384     pC->InputFileProperties.Version[2] = M4VIDEOEDITING_VERSION_REVISION;
   9385     pC->InputFileProperties.uiClipDuration = 0;
   9386 
   9387     memset((void *) &pC->InputFileProperties.ftyp,
   9388         0, sizeof(M4VIDEOEDITING_FtypBox));
   9389 
   9390     /**
   9391     * Reset video characteristics */
   9392     pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo;
   9393     pC->InputFileProperties.uiClipVideoDuration = 0;
   9394     pC->InputFileProperties.uiVideoBitrate = 0;
   9395     pC->InputFileProperties.uiVideoMaxAuSize = 0;
   9396     pC->InputFileProperties.uiVideoWidth = 0;
   9397     pC->InputFileProperties.uiVideoHeight = 0;
   9398     pC->InputFileProperties.uiVideoTimeScale = 0;
   9399     pC->InputFileProperties.fAverageFrameRate = 0.0;
   9400     pC->InputFileProperties.uiVideoLevel =
   9401         M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL;
   9402     pC->InputFileProperties.uiVideoProfile =
   9403         M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE;
   9404     pC->InputFileProperties.bMPEG4dataPartition = M4OSA_FALSE;
   9405     pC->InputFileProperties.bMPEG4rvlc = M4OSA_FALSE;
   9406     pC->InputFileProperties.bMPEG4resynchMarker = M4OSA_FALSE;
   9407 
   9408     /**
   9409     * Reset audio characteristics */
   9410     pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio;
   9411     pC->InputFileProperties.uiClipAudioDuration = 0;
   9412     pC->InputFileProperties.uiAudioBitrate = 0;
   9413     pC->InputFileProperties.uiAudioMaxAuSize = 0;
   9414     pC->InputFileProperties.uiNbChannels = 0;
   9415     pC->InputFileProperties.uiSamplingFrequency = 0;
   9416     pC->InputFileProperties.uiExtendedSamplingFrequency = 0;
   9417     pC->InputFileProperties.uiDecodedPcmSize = 0;
   9418 
   9419     /* Reset compatibility chart (not used in MCS) */
   9420     pC->InputFileProperties.bVideoIsEditable = M4OSA_FALSE;
   9421     pC->InputFileProperties.bAudioIsEditable = M4OSA_FALSE;
   9422     pC->InputFileProperties.bVideoIsCompatibleWithMasterClip = M4OSA_FALSE;
   9423     pC->InputFileProperties.bAudioIsCompatibleWithMasterClip = M4OSA_FALSE;
   9424 
   9425     /**
   9426     * Video stream properties */
   9427     if( M4OSA_NULL != pC->pReaderVideoStream )
   9428     {
   9429         switch( pC->pReaderVideoStream->m_basicProperties.m_streamType )
   9430         {
   9431             case M4DA_StreamTypeVideoMpeg4:
   9432                 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kMPEG4;
   9433                 break;
   9434 
   9435             case M4DA_StreamTypeVideoH263:
   9436                 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kH263;
   9437                 break;
   9438 
   9439             case M4DA_StreamTypeVideoMpeg4Avc:
   9440                 pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kH264;
   9441                 break;
   9442 
   9443             case M4DA_StreamTypeUnknown:
   9444             default:
   9445                 pC->InputFileProperties.VideoStreamType =
   9446                     M4VIDEOEDITING_kUnsupportedVideo;
   9447                 break;
   9448         }
   9449 
   9450         /* if bitrate not available retrieve an estimation of the overall bitrate */
   9451         pC->InputFileProperties.uiVideoBitrate =
   9452             pC->pReaderVideoStream->m_basicProperties.m_averageBitRate;
   9453 
   9454         if( 0 == pC->InputFileProperties.uiVideoBitrate )
   9455         {
   9456             pC->m_pReader->m_pFctGetOption(pC->pReaderContext,
   9457                 M4READER_kOptionID_Bitrate, &videoBitrate);
   9458 
   9459             if( M4OSA_NULL != pC->pReaderAudioStream )
   9460             {
   9461                 /* we get the overall bitrate, substract the audio bitrate if any */
   9462                 videoBitrate -=
   9463                     pC->pReaderAudioStream->m_basicProperties.m_averageBitRate;
   9464             }
   9465             pC->InputFileProperties.uiVideoBitrate = videoBitrate;
   9466         }
   9467 
   9468         /**
   9469         * Retrieve the Profile & Level */
   9470         if( ( M4VIDEOEDITING_kH263 != pC->InputFileProperties.VideoStreamType)
   9471             && (M4VIDEOEDITING_kH264
   9472             != pC->InputFileProperties.VideoStreamType) )
   9473         {
   9474             /* Use the DSI parsing function from the external video shell decoder.
   9475             See the comments in M4VSS3GPP_ClipAnalysis.c, it's pretty much the
   9476             same issue. */
   9477 
   9478             err = M4DECODER_EXTERNAL_ParseVideoDSI(pC->pReaderVideoStream->
   9479                 m_basicProperties.m_pDecoderSpecificInfo,
   9480                 pC->pReaderVideoStream->
   9481                 m_basicProperties.m_decoderSpecificInfoSize,
   9482                 &DecConfInfo, &videoSize);
   9483 
   9484             if( M4NO_ERROR != err )
   9485             {
   9486                 M4OSA_TRACE1_1(
   9487                     "M4MCS_intGetInputClipProperties():\
   9488                      M4DECODER_EXTERNAL_ParseVideoDSI returns 0x%08X",
   9489                     err);
   9490                 return err;
   9491             }
   9492 
   9493             pC->pReaderVideoStream->m_videoWidth = videoSize.m_uiWidth;
   9494             pC->pReaderVideoStream->m_videoHeight = videoSize.m_uiHeight;
   9495             pC->InputFileProperties.uiVideoTimeScale = DecConfInfo.uiTimeScale;
   9496             pC->InputFileProperties.bMPEG4dataPartition =
   9497                 DecConfInfo.bDataPartition;
   9498             pC->InputFileProperties.bMPEG4rvlc = DecConfInfo.bUseOfRVLC;
   9499             pC->InputFileProperties.bMPEG4resynchMarker =
   9500                 DecConfInfo.uiUseOfResynchMarker;
   9501 
   9502             err = getMPEG4ProfileAndLevel(DecConfInfo.uiProfile,
   9503                         &(pC->InputFileProperties.uiVideoProfile),
   9504                         &(pC->InputFileProperties.uiVideoLevel));
   9505             if ( M4NO_ERROR != err ) {
   9506                 M4OSA_TRACE1_1("M4MCS_intGetInputClipProperties():\
   9507                     getMPEG4ProfileAndLevel returns 0x%08X", err);
   9508                 return err;
   9509             }
   9510         }
   9511         else if( M4VIDEOEDITING_kH263 ==
   9512             pC->InputFileProperties.VideoStreamType ) {
   9513 
   9514             err = getH263ProfileAndLevel(pC->pReaderVideoStream->
   9515                         m_basicProperties.m_pDecoderSpecificInfo,
   9516                         pC->pReaderVideoStream->m_basicProperties.m_decoderSpecificInfoSize,
   9517                         &(pC->InputFileProperties.uiVideoProfile),
   9518                         &(pC->InputFileProperties.uiVideoLevel));
   9519             if ( M4NO_ERROR != err ) {
   9520                 M4OSA_TRACE1_1("M4MCS_intGetInputClipProperties():\
   9521                     getH263ProfileAndLevel returns 0x%08X", err);
   9522                 return err;
   9523             }
   9524             /* For h263 set default timescale : 30000:1001 */
   9525             pC->InputFileProperties.uiVideoTimeScale = 30000;
   9526         }
   9527         else if ( M4VIDEOEDITING_kH264 ==
   9528             pC->InputFileProperties.VideoStreamType ) {
   9529 
   9530             pC->InputFileProperties.uiVideoTimeScale = 30000;
   9531             err = getAVCProfileAndLevel(pC->pReaderVideoStream->
   9532                         m_basicProperties.m_pDecoderSpecificInfo,
   9533                         pC->pReaderVideoStream->m_basicProperties.m_decoderSpecificInfoSize,
   9534                         &(pC->InputFileProperties.uiVideoProfile),
   9535                         &(pC->InputFileProperties.uiVideoLevel));
   9536             if ( M4NO_ERROR != err ) {
   9537                 M4OSA_TRACE1_1("M4MCS_intGetInputClipProperties():\
   9538                     getAVCProfileAndLevel returns 0x%08X", err);
   9539                 return err;
   9540             }
   9541         }
   9542 
   9543         /* Here because width x height is correct only after dsi parsing
   9544         (done in create decoder) */
   9545         pC->InputFileProperties.uiVideoHeight =
   9546             pC->pReaderVideoStream->m_videoHeight;
   9547         pC->InputFileProperties.uiVideoWidth =
   9548             pC->pReaderVideoStream->m_videoWidth;
   9549         pC->InputFileProperties.uiClipVideoDuration =
   9550             (M4OSA_UInt32)pC->pReaderVideoStream->m_basicProperties.m_duration;
   9551         pC->InputFileProperties.fAverageFrameRate =
   9552             pC->pReaderVideoStream->m_averageFrameRate;
   9553         pC->InputFileProperties.uiVideoMaxAuSize =
   9554             pC->pReaderVideoStream->m_basicProperties.m_maxAUSize;
   9555         pC->InputFileProperties.videoRotationDegrees =
   9556             pC->pReaderVideoStream->videoRotationDegrees;
   9557     }
   9558     else
   9559     {
   9560         if( M4OSA_TRUE == pC->bUnsupportedVideoFound )
   9561         {
   9562             pC->InputFileProperties.VideoStreamType =
   9563                 M4VIDEOEDITING_kUnsupportedVideo;
   9564         }
   9565         else
   9566         {
   9567             pC->InputFileProperties.VideoStreamType = M4VIDEOEDITING_kNoneVideo;
   9568         }
   9569     }
   9570 
   9571     /**
   9572     * Audio stream properties */
   9573     if( M4OSA_NULL != pC->pReaderAudioStream )
   9574     {
   9575         switch( pC->pReaderAudioStream->m_basicProperties.m_streamType )
   9576         {
   9577             case M4DA_StreamTypeAudioAmrNarrowBand:
   9578                 pC->InputFileProperties.AudioStreamType =
   9579                     M4VIDEOEDITING_kAMR_NB;
   9580                 break;
   9581 
   9582             case M4DA_StreamTypeAudioAac:
   9583                 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kAAC;
   9584                 break;
   9585 
   9586             case M4DA_StreamTypeAudioMp3:
   9587                 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kMP3;
   9588                 break;
   9589 
   9590             case M4DA_StreamTypeAudioEvrc:
   9591                 pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kEVRC;
   9592                 break;
   9593 
   9594             case M4DA_StreamTypeUnknown:
   9595             default:
   9596                 pC->InputFileProperties.AudioStreamType =
   9597                     M4VIDEOEDITING_kUnsupportedAudio;
   9598                 break;
   9599         }
   9600 
   9601         if( ( M4OSA_NULL != pC->m_pAudioDecoder)
   9602             && (M4OSA_NULL == pC->pAudioDecCtxt) )
   9603         {
   9604             M4OSA_TRACE3_1(
   9605                 "M4MCS_intGetInputClipProperties: calling CreateAudioDecoder, userData= 0x%x",
   9606                 pC->m_pCurrentAudioDecoderUserData);
   9607 
   9608             if( M4OSA_FALSE == pC->bExtOMXAudDecoder ) {
   9609                 err = M4MCS_intCheckAndGetCodecProperties(pC);
   9610             }
   9611             else
   9612             {
   9613                 err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(
   9614                     &pC->pAudioDecCtxt, pC->pReaderAudioStream,
   9615                     pC->m_pCurrentAudioDecoderUserData);
   9616 
   9617                 if( M4NO_ERROR == err )
   9618                 {
   9619                     /* AAC properties*/
   9620                     //get from Reader; temporary, till Audio decoder shell API available to
   9621                     //get the AAC properties
   9622                     pC->AacProperties.aNumChan =
   9623                         pC->pReaderAudioStream->m_nbChannels;
   9624                     pC->AacProperties.aSampFreq =
   9625                         pC->pReaderAudioStream->m_samplingFrequency;
   9626 
   9627                     err = pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(
   9628                         pC->pAudioDecCtxt, M4AD_kOptionID_StreamType,
   9629                         (M4OSA_DataOption) &iAacType);
   9630 
   9631                     if( M4NO_ERROR != err )
   9632                     {
   9633                         M4OSA_TRACE1_1(
   9634                             "M4MCS_intGetInputClipProperties:\
   9635                              m_pAudioDecoder->m_pFctGetOptionAudioDec returns err 0x%x",
   9636                             err);
   9637                         iAacType = M4_kAAC; //set to default
   9638                         err = M4NO_ERROR;
   9639                     }
   9640                     else
   9641                     {
   9642                         M4OSA_TRACE3_1(
   9643                             "M4MCS_intGetInputClipProperties:\
   9644                              m_pAudioDecoder->m_pFctGetOptionAudioDec returns streamType %d",
   9645                             iAacType);
   9646                     }
   9647 
   9648                     switch( iAacType )
   9649                     {
   9650                         case M4_kAAC:
   9651                             pC->AacProperties.aSBRPresent = 0;
   9652                             pC->AacProperties.aPSPresent = 0;
   9653                             break;
   9654 
   9655                         case M4_kAACplus:
   9656                             pC->AacProperties.aSBRPresent = 1;
   9657                             pC->AacProperties.aPSPresent = 0;
   9658                             pC->AacProperties.aExtensionSampFreq =
   9659                                 pC->pReaderAudioStream->
   9660                                 m_samplingFrequency; //TODO
   9661                             break;
   9662 
   9663                         case M4_keAACplus:
   9664                             pC->AacProperties.aSBRPresent = 1;
   9665                             pC->AacProperties.aPSPresent = 1;
   9666                             pC->AacProperties.aExtensionSampFreq =
   9667                                 pC->pReaderAudioStream->
   9668                                 m_samplingFrequency; //TODO
   9669                             break;
   9670                           case M4_kUnknown:
   9671                           break;
   9672                           default:
   9673                           break;
   9674                         }
   9675                         M4OSA_TRACE3_2(
   9676                             "M4MCS_intGetInputClipProperties: AAC NBChans=%d, SamplFreq=%d",
   9677                             pC->AacProperties.aNumChan,
   9678                             pC->AacProperties.aSampFreq);
   9679                 }
   9680             }
   9681 
   9682             if( M4NO_ERROR != err )
   9683             {
   9684                 M4OSA_TRACE1_1(
   9685                     "M4MCS_intGetInputClipProperties:\
   9686                      m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x",
   9687                     err);
   9688                 return err;
   9689             }
   9690         }
   9691 
   9692         //EVRC
   9693         if( pC->pReaderAudioStream->m_basicProperties.m_streamType
   9694             == M4DA_StreamTypeAudioEvrc )
   9695         {
   9696             /* decoder not implemented yet, provide some default values for the null encoding */
   9697             pC->pReaderAudioStream->m_nbChannels = 1;
   9698             pC->pReaderAudioStream->m_samplingFrequency = 8000;
   9699         }
   9700 
   9701         /**
   9702         * Bugfix P4ME00001128: With some IMTC files, the AMR bit rate is 0 kbps according
   9703          the GetProperties function */
   9704         if( 0 == pC->pReaderAudioStream->m_basicProperties.m_averageBitRate )
   9705         {
   9706             if( M4VIDEOEDITING_kAMR_NB
   9707                 == pC->InputFileProperties.AudioStreamType )
   9708             {
   9709                 /**
   9710                 * Better returning a guessed 12.2 kbps value than a sure-to-be-false
   9711                 0 kbps value! */
   9712                 pC->InputFileProperties.uiAudioBitrate =
   9713                     M4VIDEOEDITING_k12_2_KBPS;
   9714             }
   9715             else if( M4VIDEOEDITING_kEVRC
   9716                 == pC->InputFileProperties.AudioStreamType )
   9717             {
   9718                 /**
   9719                 * Better returning a guessed 8.5 kbps value than a sure-to-be-false
   9720                 0 kbps value! */
   9721                 pC->InputFileProperties.uiAudioBitrate =
   9722                     M4VIDEOEDITING_k9_2_KBPS;
   9723             }
   9724             else
   9725             {
   9726                 M4OSA_UInt32 FileBitrate;
   9727 
   9728                 /* Can happen also for aac, in this case we calculate an approximative */
   9729                 /* value from global bitrate and video bitrate */
   9730                 err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext,
   9731                     M4READER_kOptionID_Bitrate,
   9732                     (M4OSA_DataOption) &FileBitrate);
   9733 
   9734                 if( M4NO_ERROR != err )
   9735                 {
   9736                     M4OSA_TRACE1_1(
   9737                         "M4MCS_intGetInputClipProperties: M4READER_kOptionID_Bitrate returns 0x%x",
   9738                         err);
   9739                     return err;
   9740                 }
   9741                 pC->InputFileProperties.uiAudioBitrate =
   9742                     FileBitrate
   9743                     - pC->
   9744                     InputFileProperties.
   9745                     uiVideoBitrate /* normally setted to 0, if no video */;
   9746             }
   9747         }
   9748         else
   9749         {
   9750             pC->InputFileProperties.uiAudioBitrate =
   9751                 pC->pReaderAudioStream->m_basicProperties.m_averageBitRate;
   9752         }
   9753 
   9754         pC->InputFileProperties.uiNbChannels =
   9755             pC->pReaderAudioStream->m_nbChannels;
   9756         pC->InputFileProperties.uiSamplingFrequency =
   9757             pC->pReaderAudioStream->m_samplingFrequency;
   9758         pC->InputFileProperties.uiClipAudioDuration =
   9759             (M4OSA_UInt32)pC->pReaderAudioStream->m_basicProperties.m_duration;
   9760         pC->InputFileProperties.uiAudioMaxAuSize =
   9761             pC->pReaderAudioStream->m_basicProperties.m_maxAUSize;
   9762 
   9763         /* Bug: with aac, value is 0 until decoder start() is called */
   9764         pC->InputFileProperties.uiDecodedPcmSize =
   9765             pC->pReaderAudioStream->m_byteFrameLength
   9766             * pC->pReaderAudioStream->m_byteSampleSize
   9767             * pC->pReaderAudioStream->m_nbChannels;
   9768 
   9769         /* New aac properties */
   9770         if( M4DA_StreamTypeAudioAac
   9771             == pC->pReaderAudioStream->m_basicProperties.m_streamType )
   9772         {
   9773             pC->InputFileProperties.uiNbChannels = pC->AacProperties.aNumChan;
   9774             pC->InputFileProperties.uiSamplingFrequency =
   9775                 pC->AacProperties.aSampFreq;
   9776 
   9777             if( pC->AacProperties.aSBRPresent )
   9778             {
   9779                 pC->InputFileProperties.AudioStreamType =
   9780                     M4VIDEOEDITING_kAACplus;
   9781                 pC->InputFileProperties.uiExtendedSamplingFrequency =
   9782                     pC->AacProperties.aExtensionSampFreq;
   9783             }
   9784 
   9785             if( pC->AacProperties.aPSPresent )
   9786             {
   9787                 pC->InputFileProperties.AudioStreamType =
   9788                     M4VIDEOEDITING_keAACplus;
   9789             }
   9790         }
   9791     }
   9792     else
   9793     {
   9794         if( M4OSA_TRUE == pC->bUnsupportedAudioFound )
   9795         {
   9796             pC->InputFileProperties.AudioStreamType =
   9797                 M4VIDEOEDITING_kUnsupportedAudio;
   9798         }
   9799         else
   9800         {
   9801             pC->InputFileProperties.AudioStreamType = M4VIDEOEDITING_kNoneAudio;
   9802         }
   9803     }
   9804 
   9805     /* Get 'ftyp' atom */
   9806     err = pC->m_pReader->m_pFctGetOption(pC->pReaderContext,
   9807         M4READER_kOptionID_3gpFtypBox, &pC->InputFileProperties.ftyp);
   9808 
   9809     /* Analysis is successful */
   9810     if( pC->InputFileProperties.uiClipVideoDuration
   9811         > pC->InputFileProperties.uiClipAudioDuration )
   9812         pC->InputFileProperties.uiClipDuration =
   9813         pC->InputFileProperties.uiClipVideoDuration;
   9814     else
   9815         pC->InputFileProperties.uiClipDuration =
   9816         pC->InputFileProperties.uiClipAudioDuration;
   9817 
   9818     pC->InputFileProperties.FileType = pC->InputFileType;
   9819     pC->InputFileProperties.bAnalysed = M4OSA_TRUE;
   9820 
   9821     return M4NO_ERROR;
   9822 }
   9823 
   9824 /**
   9825  ******************************************************************************
   9826  * M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB(M4OSA_MemAddr8 pAudioFrame)
   9827  * @brief   Return the length, in bytes, of the AMR Narrow-Band frame contained in the given buffer
   9828  * @note
   9829  * @param   pCpAudioFrame   (IN) AMRNB frame
   9830  * @return  M4NO_ERROR: No error
   9831  ******************************************************************************
   9832  */
   9833 static M4OSA_UInt32 M4MCS_intGetFrameSize_AMRNB( M4OSA_MemAddr8 pAudioFrame )
   9834 {
   9835     M4OSA_UInt32 frameSize = 0;
   9836     M4OSA_UInt32 frameType = ( ( *pAudioFrame) &(0xF << 3)) >> 3;
   9837 
   9838     switch( frameType )
   9839     {
   9840         case 0:
   9841             frameSize = 95;
   9842             break; /*  4750 bps */
   9843 
   9844         case 1:
   9845             frameSize = 103;
   9846             break; /*  5150 bps */
   9847 
   9848         case 2:
   9849             frameSize = 118;
   9850             break; /*  5900 bps */
   9851 
   9852         case 3:
   9853             frameSize = 134;
   9854             break; /*  6700 bps */
   9855 
   9856         case 4:
   9857             frameSize = 148;
   9858             break; /*  7400 bps */
   9859 
   9860         case 5:
   9861             frameSize = 159;
   9862             break; /*  7950 bps */
   9863 
   9864         case 6:
   9865             frameSize = 204;
   9866             break; /* 10200 bps */
   9867 
   9868         case 7:
   9869             frameSize = 244;
   9870             break; /* 12000 bps */
   9871 
   9872         case 8:
   9873             frameSize = 39;
   9874             break; /* SID (Silence) */
   9875 
   9876         case 15:
   9877             frameSize = 0;
   9878             break; /* No data */
   9879 
   9880         default:
   9881             M4OSA_TRACE3_0(
   9882                 "M4MCS_intGetFrameSize_AMRNB(): Corrupted AMR frame! returning 0.");
   9883             return 0;
   9884     }
   9885 
   9886     return (1 + (( frameSize + 7) / 8));
   9887 }
   9888 
   9889 /**
   9890  ******************************************************************************
   9891  * M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC(M4OSA_MemAddr8 pAudioFrame)
   9892  * @brief   Return the length, in bytes, of the EVRC frame contained in the given buffer
   9893  * @note
   9894  *     0 1 2 3
   9895  *    +-+-+-+-+
   9896  *    |fr type|              RFC 3558
   9897  *    +-+-+-+-+
   9898  *
   9899  * Frame Type: 4 bits
   9900  *    The frame type indicates the type of the corresponding codec data
   9901  *    frame in the RTP packet.
   9902  *
   9903  * For EVRC and SMV codecs, the frame type values and size of the
   9904  * associated codec data frame are described in the table below:
   9905  *
   9906  * Value   Rate      Total codec data frame size (in octets)
   9907  * ---------------------------------------------------------
   9908  *   0     Blank      0    (0 bit)
   9909  *   1     1/8        2    (16 bits)
   9910  *   2     1/4        5    (40 bits; not valid for EVRC)
   9911  *   3     1/2       10    (80 bits)
   9912  *   4     1         22    (171 bits; 5 padded at end with zeros)
   9913  *   5     Erasure    0    (SHOULD NOT be transmitted by sender)
   9914  *
   9915  * @param   pCpAudioFrame   (IN) EVRC frame
   9916  * @return  M4NO_ERROR: No error
   9917  ******************************************************************************
   9918  */
   9919 static M4OSA_UInt32 M4MCS_intGetFrameSize_EVRC( M4OSA_MemAddr8 pAudioFrame )
   9920 {
   9921     M4OSA_UInt32 frameSize = 0;
   9922     M4OSA_UInt32 frameType = ( *pAudioFrame) &0x0F;
   9923 
   9924     switch( frameType )
   9925     {
   9926         case 0:
   9927             frameSize = 0;
   9928             break; /*  blank */
   9929 
   9930         case 1:
   9931             frameSize = 16;
   9932             break; /*  1/8 */
   9933 
   9934         case 2:
   9935             frameSize = 40;
   9936             break; /*  1/4 */
   9937 
   9938         case 3:
   9939             frameSize = 80;
   9940             break; /*  1/2 */
   9941 
   9942         case 4:
   9943             frameSize = 171;
   9944             break; /*  1 */
   9945 
   9946         case 5:
   9947             frameSize = 0;
   9948             break; /*  erasure */
   9949 
   9950         default:
   9951             M4OSA_TRACE3_0(
   9952                 "M4MCS_intGetFrameSize_EVRC(): Corrupted EVRC frame! returning 0.");
   9953             return 0;
   9954     }
   9955 
   9956     return (1 + (( frameSize + 7) / 8));
   9957 }
   9958 
   9959 /**
   9960  ******************************************************************************
   9961  * M4OSA_ERR M4MCS_intCheckMaxFileSize(M4MCS_Context pContext)
   9962  * @brief    Check if max file size is greater enough to encode a file with the
   9963  *           current selected bitrates and duration.
   9964  * @param    pContext            (IN) MCS context
   9965  * @return   M4NO_ERROR
   9966  * @return   M4MCS_ERR_MAXFILESIZE_TOO_SMALL
   9967  ******************************************************************************
   9968  */
   9969 static M4OSA_ERR M4MCS_intCheckMaxFileSize( M4MCS_Context pContext )
   9970 {
   9971     M4MCS_InternalContext *pC = (M4MCS_InternalContext *)(pContext);
   9972 
   9973     M4OSA_UInt32 duration;
   9974     M4OSA_UInt32 audiobitrate;
   9975     M4OSA_UInt32 videobitrate;
   9976 
   9977     /* free file size : OK */
   9978     if( pC->uiMaxFileSize == 0 )
   9979         return M4NO_ERROR;
   9980 
   9981     /* duration */
   9982     if( pC->uiEndCutTime == 0 )
   9983     {
   9984         duration = pC->InputFileProperties.uiClipDuration - pC->uiBeginCutTime;
   9985     }
   9986     else
   9987     {
   9988         duration = pC->uiEndCutTime - pC->uiBeginCutTime;
   9989     }
   9990 
   9991     /* audio bitrate */
   9992     if( pC->noaudio )
   9993     {
   9994         audiobitrate = 0;
   9995     }
   9996     else if( pC->AudioEncParams.Format == M4ENCODER_kAudioNULL )
   9997     {
   9998         audiobitrate = pC->InputFileProperties.uiAudioBitrate;
   9999     }
   10000     else if( pC->uiAudioBitrate == M4VIDEOEDITING_kUndefinedBitrate )
   10001     {
   10002         switch( pC->AudioEncParams.Format )
   10003         {
   10004             case M4ENCODER_kAMRNB:
   10005                 audiobitrate = M4VIDEOEDITING_k12_2_KBPS;
   10006                 break;
   10007                 //EVRC
   10008                 //            case M4ENCODER_kEVRC:
   10009                 //                audiobitrate = M4VIDEOEDITING_k9_2_KBPS;
   10010                 //                break;
   10011 
   10012             default: /* AAC and MP3*/
   10013                 audiobitrate =
   10014                     (pC->AudioEncParams.ChannelNum == M4ENCODER_kMono)
   10015                     ? M4VIDEOEDITING_k16_KBPS : M4VIDEOEDITING_k32_KBPS;
   10016                 break;
   10017         }
   10018     }
   10019     else
   10020     {
   10021         audiobitrate = pC->uiAudioBitrate;
   10022     }
   10023 
   10024     /* video bitrate */
   10025     if( pC->novideo )
   10026     {
   10027         videobitrate = 0;
   10028     }
   10029     else if( pC->EncodingVideoFormat == M4ENCODER_kNULL )
   10030     {
   10031         videobitrate = pC->InputFileProperties.uiVideoBitrate;
   10032     }
   10033     else if( pC->uiVideoBitrate == M4VIDEOEDITING_kUndefinedBitrate )
   10034     {
   10035         videobitrate = M4VIDEOEDITING_k16_KBPS;
   10036     }
   10037     else
   10038     {
   10039         videobitrate = pC->uiVideoBitrate;
   10040     }
   10041 
   10042     /* max file size */
   10043     if( (M4OSA_UInt32)pC->uiMaxFileSize
   10044         < (M4OSA_UInt32)(M4MCS_MOOV_OVER_FILESIZE_RATIO
   10045         * (audiobitrate + videobitrate) * (duration / 8000.0)) )
   10046         return M4MCS_ERR_MAXFILESIZE_TOO_SMALL;
   10047     else
   10048         return M4NO_ERROR;
   10049 }
   10050 
   10051 /**
   10052  ******************************************************************************
   10053  * M4VIDEOEDITING_Bitrate M4MCS_intGetNearestBitrate(M4OSA_UInt32 freebitrate, M4OSA_Int8 mode)
   10054  * @brief    Returns the closest bitrate value from the enum list of type M4VIDEOEDITING_Bitrate
   10055  * @param    freebitrate: unsigned int value
   10056  * @param    mode: -1:previous,0:current,1:next
   10057  * @return   bitrate value in enum list M4VIDEOEDITING_Bitrate
   10058  ******************************************************************************
   10059  */
   10060 static M4VIDEOEDITING_Bitrate
   10061 M4MCS_intGetNearestBitrate( M4OSA_Int32 freebitrate, M4OSA_Int8 mode )
   10062 {
   10063     M4OSA_Int32 bitarray [] =
   10064     {
   10065         0, M4VIDEOEDITING_k16_KBPS, M4VIDEOEDITING_k24_KBPS,
   10066         M4VIDEOEDITING_k32_KBPS, M4VIDEOEDITING_k48_KBPS,
   10067         M4VIDEOEDITING_k64_KBPS, M4VIDEOEDITING_k96_KBPS,
   10068         M4VIDEOEDITING_k128_KBPS, M4VIDEOEDITING_k192_KBPS,
   10069         M4VIDEOEDITING_k256_KBPS, M4VIDEOEDITING_k288_KBPS,
   10070         M4VIDEOEDITING_k384_KBPS, M4VIDEOEDITING_k512_KBPS,
   10071         M4VIDEOEDITING_k800_KBPS, M4VIDEOEDITING_k2_MBPS,
   10072         M4VIDEOEDITING_k5_MBPS,
   10073         M4VIDEOEDITING_k8_MBPS, /*+ New Encoder bitrates */
   10074         M4OSA_INT32_MAX
   10075     };
   10076 
   10077     const M4OSA_UInt32 nbbitrates = 14;
   10078     M4OSA_UInt32 i;
   10079 
   10080     for ( i = 0; freebitrate >= bitarray[i]; i++ );
   10081 
   10082     switch( mode )
   10083     {
   10084         case -1: /* previous */
   10085             if( i <= 2 )
   10086                 return 0;
   10087             else
   10088                 return bitarray[i - 2];
   10089             break;
   10090 
   10091         case 0: /* current */
   10092             if( i <= 1 )
   10093                 return 0;
   10094             else
   10095                 return bitarray[i - 1];
   10096             break;
   10097 
   10098         case 1: /* next */
   10099             if( i >= nbbitrates )
   10100                 return M4OSA_INT32_MAX;
   10101             else
   10102                 return bitarray[i];
   10103             break;
   10104     }
   10105 
   10106     return 0;
   10107 }
   10108 
   10109 /**
   10110  ******************************************************************************
   10111  * M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders(M4MCS_InternalContext* pC);
   10112  * @brief    Free all resources allocated by M4MCS_open()
   10113  * @param    pContext            (IN) MCS context
   10114  * @return   M4NO_ERROR:         No error
   10115  ******************************************************************************
   10116  */
   10117 static M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders( M4MCS_InternalContext *pC )
   10118 {
   10119     M4OSA_ERR err = M4NO_ERROR;
   10120 
   10121     M4OSA_TRACE2_1("M4MCS_intCleanUp_ReadersDecoders called with pC=0x%x", pC);
   10122 
   10123     /**/
   10124     /* ----- Free video decoder stuff, if needed ----- */
   10125 
   10126     if( M4OSA_NULL != pC->pViDecCtxt )
   10127     {
   10128         err = pC->m_pVideoDecoder->m_pFctDestroy(pC->pViDecCtxt);
   10129         pC->pViDecCtxt = M4OSA_NULL;
   10130 
   10131         if( M4NO_ERROR != err )
   10132         {
   10133             M4OSA_TRACE1_1(
   10134                 "M4MCS_cleanUp: m_pVideoDecoder->pFctDestroy returns 0x%x",
   10135                 err);
   10136             /**< don't return, we still have stuff to free */
   10137         }
   10138     }
   10139 
   10140     /* ----- Free the audio decoder stuff ----- */
   10141 
   10142     if( M4OSA_NULL != pC->pAudioDecCtxt )
   10143     {
   10144         err = pC->m_pAudioDecoder->m_pFctDestroyAudioDec(pC->pAudioDecCtxt);
   10145         pC->pAudioDecCtxt = M4OSA_NULL;
   10146 
   10147         if( M4NO_ERROR != err )
   10148         {
   10149             M4OSA_TRACE1_1(
   10150                 "M4MCS_cleanUp: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x",
   10151                 err);
   10152             /**< don't return, we still have stuff to free */
   10153         }
   10154     }
   10155 
   10156     if( M4OSA_NULL != pC->AudioDecBufferOut.m_dataAddress )
   10157     {
   10158         free(pC->AudioDecBufferOut.m_dataAddress);
   10159         pC->AudioDecBufferOut.m_dataAddress = M4OSA_NULL;
   10160     }
   10161 
   10162     /* ----- Free reader stuff, if needed ----- */
   10163     // We cannot free the reader before decoders because the decoders may read
   10164     // from the reader (in another thread) before being stopped.
   10165 
   10166     if( M4OSA_NULL != pC->
   10167         pReaderContext ) /**< may be M4OSA_NULL if M4MCS_open was not called */
   10168     {
   10169         err = pC->m_pReader->m_pFctClose(pC->pReaderContext);
   10170 
   10171         if( M4NO_ERROR != err )
   10172         {
   10173             M4OSA_TRACE1_1("M4MCS_cleanUp: m_pReader->m_pFctClose returns 0x%x",
   10174                 err);
   10175             /**< don't return, we still have stuff to free */
   10176         }
   10177 
   10178         err = pC->m_pReader->m_pFctDestroy(pC->pReaderContext);
   10179         pC->pReaderContext = M4OSA_NULL;
   10180 
   10181         if( M4NO_ERROR != err )
   10182         {
   10183             M4OSA_TRACE1_1(
   10184                 "M4MCS_cleanUp: m_pReader->m_pFctDestroy returns 0x%x", err);
   10185             /**< don't return, we still have stuff to free */
   10186         }
   10187     }
   10188 
   10189     if( pC->m_pDataAddress1 != M4OSA_NULL )
   10190     {
   10191         free(pC->m_pDataAddress1);
   10192         pC->m_pDataAddress1 = M4OSA_NULL;
   10193     }
   10194 
   10195     if( pC->m_pDataAddress2 != M4OSA_NULL )
   10196     {
   10197         free(pC->m_pDataAddress2);
   10198         pC->m_pDataAddress2 = M4OSA_NULL;
   10199     }
   10200     /*Bug fix 11/12/2008 (to obtain more precise video end cut)*/
   10201     if( pC->m_pDataVideoAddress1 != M4OSA_NULL )
   10202     {
   10203         free(pC->m_pDataVideoAddress1);
   10204         pC->m_pDataVideoAddress1 = M4OSA_NULL;
   10205     }
   10206 
   10207     if( pC->m_pDataVideoAddress2 != M4OSA_NULL )
   10208     {
   10209         free(pC->m_pDataVideoAddress2);
   10210         pC->m_pDataVideoAddress2 = M4OSA_NULL;
   10211     }
   10212 
   10213     return M4NO_ERROR;
   10214 }
   10215 
   10216 
   10217 /**
   10218 
   10219  ******************************************************************************
   10220  * M4OSA_ERR M4MCS_open_normalMode(M4MCS_Context pContext, M4OSA_Void* pFileIn,
   10221  *                             M4OSA_Void* pFileOut, M4OSA_Void* pTempFile);
   10222  * @brief   Set the MCS input and output files. It is the same as M4MCS_open without
   10223  *                                M4MCS_WITH_FAST_OPEN flag
   10224 It is used in VideoArtist
   10225  * @note    It opens the input file, but the output file is not created yet.
   10226  * @param   pContext            (IN) MCS context
   10227  * @param   pFileIn             (IN) Input file to transcode (The type of this parameter
   10228  *                                    (URL, pipe...) depends on the OSAL implementation).
   10229  * @param   mediaType           (IN) Container type (.3gp,.amr, ...) of input file.
   10230  * @param   pFileOut            (IN) Output file to create  (The type of this parameter
   10231  *                                (URL, pipe...) depends on the OSAL implementation).
   10232  * @param   pTempFile           (IN) Temporary file for the constant memory writer to store
   10233  *                                 metadata ("moov.bin").
   10234  * @return  M4NO_ERROR:         No error
   10235  * @return  M4ERR_PARAMETER:    At least one parameter is M4OSA_NULL (debug only)
   10236  * @return  M4ERR_STATE:        MCS is not in an appropriate state for this function to be called
   10237  * @return  M4ERR_ALLOC:        There is no more available memory
   10238  * @return  M4ERR_FILE_NOT_FOUND:   The input file has not been found
   10239  * @return  M4MCS_ERR_INVALID_INPUT_FILE:   The input file is not a valid file, or is corrupted
   10240  * @return  M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM:  The input file contains no
   10241  *                                                         supported audio or video stream
   10242  ******************************************************************************
   10243  */
   10244 M4OSA_ERR M4MCS_open_normalMode(M4MCS_Context pContext, M4OSA_Void* pFileIn,
   10245                                  M4VIDEOEDITING_FileType InputFileType,
   10246                                   M4OSA_Void* pFileOut, M4OSA_Void* pTempFile)
   10247 {
   10248     M4MCS_InternalContext *pC = (M4MCS_InternalContext*)(pContext);
   10249     M4OSA_ERR err;
   10250 
   10251     M4READER_MediaFamily mediaFamily;
   10252     M4_StreamHandler* pStreamHandler;
   10253 
   10254     M4OSA_TRACE2_3("M4MCS_open_normalMode called with pContext=0x%x, pFileIn=0x%x,\
   10255      pFileOut=0x%x", pContext, pFileIn, pFileOut);
   10256 
   10257     /**
   10258     * Check input parameters */
   10259     M4OSA_DEBUG_IF2((M4OSA_NULL == pContext), M4ERR_PARAMETER,
   10260      "M4MCS_open_normalMode: pContext is M4OSA_NULL");
   10261     M4OSA_DEBUG_IF2((M4OSA_NULL == pFileIn) , M4ERR_PARAMETER,
   10262      "M4MCS_open_normalMode: pFileIn is M4OSA_NULL");
   10263 
   10264     if ((InputFileType == M4VIDEOEDITING_kFileType_JPG)
   10265         ||(InputFileType == M4VIDEOEDITING_kFileType_PNG)
   10266         ||(InputFileType == M4VIDEOEDITING_kFileType_GIF)
   10267         ||(InputFileType == M4VIDEOEDITING_kFileType_BMP))
   10268     {
   10269         M4OSA_TRACE1_0("M4MCS_open_normalMode: Still picture is not\
   10270              supported with this function");
   10271         return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM;
   10272     }
   10273 
   10274     /**
   10275     * Check state automaton */
   10276     if (M4MCS_kState_CREATED != pC->State)
   10277     {
   10278         M4OSA_TRACE1_1("M4MCS_open_normalMode(): Wrong State (%d), returning M4ERR_STATE",
   10279              pC->State);
   10280         return M4ERR_STATE;
   10281     }
   10282 
   10283     /* Copy function input parameters into our context */
   10284     pC->pInputFile     = pFileIn;
   10285     pC->InputFileType  = InputFileType;
   10286     pC->pOutputFile    = pFileOut;
   10287     pC->pTemporaryFile = pTempFile;
   10288 
   10289     /***********************************/
   10290     /* Open input file with the reader */
   10291     /***********************************/
   10292 
   10293     err = M4MCS_setCurrentReader(pContext, pC->InputFileType);
   10294     M4ERR_CHECK_RETURN(err);
   10295 
   10296     /**
   10297     * Reset reader related variables */
   10298     pC->VideoState          = M4MCS_kStreamState_NOSTREAM;
   10299     pC->AudioState          = M4MCS_kStreamState_NOSTREAM;
   10300     pC->pReaderVideoStream  = M4OSA_NULL;
   10301     pC->pReaderAudioStream  = M4OSA_NULL;
   10302 
   10303     /*******************************************************/
   10304     /* Initializes the reader shell and open the data file */
   10305     /*******************************************************/
   10306     err = pC->m_pReader->m_pFctCreate(&pC->pReaderContext);
   10307     if (M4NO_ERROR != err)
   10308     {
   10309         M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctCreate returns 0x%x", err);
   10310         return err;
   10311     }
   10312 
   10313     /**
   10314     * Link the reader interface to the reader context */
   10315     pC->m_pReaderDataIt->m_readerContext = pC->pReaderContext;
   10316 
   10317     /**
   10318     * Set the reader shell file access functions */
   10319     err = pC->m_pReader->m_pFctSetOption(pC->pReaderContext,
   10320          M4READER_kOptionID_SetOsaFileReaderFctsPtr,
   10321         (M4OSA_DataOption)pC->pOsaFileReadPtr);
   10322     if (M4NO_ERROR != err)
   10323     {
   10324         M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctSetOption returns 0x%x", err);
   10325         return err;
   10326     }
   10327 
   10328     /**
   10329     * Open the input file */
   10330     err = pC->m_pReader->m_pFctOpen(pC->pReaderContext, pC->pInputFile);
   10331     if (M4NO_ERROR != err)
   10332     {
   10333         M4OSA_UInt32 uiDummy, uiCoreId;
   10334         M4OSA_TRACE1_1("M4MCS_open_normalMode(): m_pReader->m_pFctOpen returns 0x%x", err);
   10335 
   10336         if (err == ((M4OSA_UInt32)M4ERR_UNSUPPORTED_MEDIA_TYPE)) {
   10337             M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning M4MCS_ERR_FILE_DRM_PROTECTED");
   10338             return M4MCS_ERR_FILE_DRM_PROTECTED;
   10339         } else {
   10340             /**
   10341             * If the error is from the core reader, we change it to a public VXS error */
   10342             M4OSA_ERR_SPLIT(err, uiDummy, uiCoreId, uiDummy);
   10343             if (M4MP4_READER == uiCoreId)
   10344             {
   10345                 M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning M4MCS_ERR_INVALID_INPUT_FILE");
   10346                 return M4MCS_ERR_INVALID_INPUT_FILE;
   10347             }
   10348         }
   10349         return err;
   10350     }
   10351 
   10352     /**
   10353     * Get the streams from the input file */
   10354     while (M4NO_ERROR == err)
   10355     {
   10356         err = pC->m_pReader->m_pFctGetNextStream(pC->pReaderContext, &mediaFamily,
   10357             &pStreamHandler);
   10358 
   10359         /**
   10360         * In case we found a BIFS stream or something else...*/
   10361         if((err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE))
   10362             || (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS)))
   10363         {
   10364             err = M4NO_ERROR;
   10365             continue;
   10366         }
   10367 
   10368         if (M4NO_ERROR == err) /**< One stream found */
   10369         {
   10370             /**
   10371             * Found the first video stream */
   10372             if ((M4READER_kMediaFamilyVideo == mediaFamily) \
   10373                 && (M4OSA_NULL == pC->pReaderVideoStream))
   10374             {
   10375                 if ((M4DA_StreamTypeVideoH263==pStreamHandler->m_streamType) ||
   10376                     (M4DA_StreamTypeVideoMpeg4==pStreamHandler->m_streamType)
   10377 #ifdef M4VSS_SUPPORT_VIDEO_AVC
   10378                     ||(M4DA_StreamTypeVideoMpeg4Avc==pStreamHandler->m_streamType))
   10379 #else
   10380                     ||((M4DA_StreamTypeVideoMpeg4Avc==pStreamHandler->m_streamType)
   10381                     &&(pC->m_pVideoDecoderItTable[M4DECODER_kVideoTypeAVC] != M4OSA_NULL)))
   10382 #endif
   10383                 {
   10384                     M4OSA_TRACE3_0("M4MCS_open_normalMode():\
   10385                      Found a H263 or MPEG-4 video stream in input 3gpp clip");
   10386 
   10387                     /**
   10388                     * Keep pointer to the video stream */
   10389                     pC->pReaderVideoStream = (M4_VideoStreamHandler*)pStreamHandler;
   10390                     pC->bUnsupportedVideoFound = M4OSA_FALSE;
   10391                     pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
   10392 
   10393                     /**
   10394                     * Init our video stream state variable */
   10395                     pC->VideoState = M4MCS_kStreamState_STARTED;
   10396 
   10397                     /**
   10398                     * Reset the stream reader */
   10399                     err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
   10400                          (M4_StreamHandler*)pC->pReaderVideoStream);
   10401                     if (M4NO_ERROR != err)
   10402                     {
   10403                         M4OSA_TRACE1_1("M4MCS_open_normalMode():\
   10404                              m_pReader->m_pFctReset(video) returns 0x%x", err);
   10405                         return err;
   10406                     }
   10407 
   10408                     /**
   10409                     * Initializes an access Unit */
   10410                     err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, pStreamHandler,
   10411                          &pC->ReaderVideoAU);
   10412                     if (M4NO_ERROR != err)
   10413                     {
   10414                         M4OSA_TRACE1_1("M4MCS_open_normalMode():\
   10415                              m_pReader->m_pFctFillAuStruct(video) returns 0x%x", err);
   10416                         return err;
   10417                     }
   10418                 }
   10419                 else /**< Not H263 or MPEG-4 (H264, etc.) */
   10420                 {
   10421                     M4OSA_TRACE1_1("M4MCS_open_normalMode():\
   10422                          Found an unsupported video stream (0x%x) in input 3gpp clip",
   10423                              pStreamHandler->m_streamType);
   10424 
   10425                     pC->bUnsupportedVideoFound = M4OSA_TRUE;
   10426                     pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
   10427                 }
   10428             }
   10429             /**
   10430             * Found the first audio stream */
   10431             else if ((M4READER_kMediaFamilyAudio == mediaFamily)
   10432                 && (M4OSA_NULL == pC->pReaderAudioStream))
   10433             {
   10434                 if ((M4DA_StreamTypeAudioAmrNarrowBand==pStreamHandler->m_streamType) ||
   10435                     (M4DA_StreamTypeAudioAac==pStreamHandler->m_streamType) ||
   10436                     (M4DA_StreamTypeAudioMp3==pStreamHandler->m_streamType) ||
   10437                     (M4DA_StreamTypeAudioEvrc==pStreamHandler->m_streamType) )
   10438                 {
   10439                     M4OSA_TRACE3_0("M4MCS_open_normalMode(): Found an AMR-NB, AAC \
   10440                         or MP3 audio stream in input clip");
   10441 
   10442                     /**
   10443                     * Keep pointer to the audio stream */
   10444                     pC->pReaderAudioStream = (M4_AudioStreamHandler*)pStreamHandler;
   10445                     pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
   10446                     pC->bUnsupportedAudioFound = M4OSA_FALSE;
   10447 
   10448                     /**
   10449                     * Init our audio stream state variable */
   10450                     pC->AudioState = M4MCS_kStreamState_STARTED;
   10451 
   10452                     /**
   10453                     * Reset the stream reader */
   10454                     err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
   10455                          (M4_StreamHandler*)pC->pReaderAudioStream);
   10456                     if (M4NO_ERROR != err)
   10457                     {
   10458                         M4OSA_TRACE1_1("M4MCS_open_normalMode():\
   10459                              m_pReader->m_pFctReset(audio) returns 0x%x", err);
   10460                         return err;
   10461                     }
   10462 
   10463                     /**
   10464                     * Initializes an access Unit */
   10465                     err = pC->m_pReader->m_pFctFillAuStruct(pC->pReaderContext, pStreamHandler,
   10466                          &pC->ReaderAudioAU);
   10467                     if (M4NO_ERROR != err)
   10468                     {
   10469                         M4OSA_TRACE1_1("M4MCS_open_normalMode(): \
   10470                             m_pReader->m_pFctFillAuStruct(audio) returns 0x%x", err);
   10471                         return err;
   10472                     }
   10473 
   10474                     /**
   10475                     * Output max AU size is equal to input max AU size (this value
   10476                     * will be changed if there is audio transcoding) */
   10477                     pC->uiAudioMaxAuSize = pStreamHandler->m_maxAUSize;
   10478 
   10479                 }
   10480                 else
   10481                 {
   10482                     /**< Not AMR-NB, AAC, MP3 nor EVRC (AMR-WB, WAV...) */
   10483                     M4OSA_TRACE1_1("M4MCS_open_normalMode(): Found an unsupported audio stream\
   10484                          (0x%x) in input 3gpp clip", pStreamHandler->m_streamType);
   10485 
   10486                     pC->bUnsupportedAudioFound = M4OSA_TRUE;
   10487                     pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
   10488                 }
   10489             }
   10490         }
   10491     } /**< end of while (M4NO_ERROR == err) */
   10492 
   10493     /**
   10494     * Check we found at least one supported stream */
   10495     if((M4OSA_NULL == pC->pReaderVideoStream) && (M4OSA_NULL == pC->pReaderAudioStream))
   10496     {
   10497         M4OSA_TRACE1_0("M4MCS_open_normalMode(): returning \
   10498             M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM");
   10499         return M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM;
   10500     }
   10501 
   10502 #ifndef M4VSS_ENABLE_EXTERNAL_DECODERS
   10503     if(pC->VideoState == M4MCS_kStreamState_STARTED)
   10504     {
   10505         err = M4MCS_setCurrentVideoDecoder(pContext,
   10506             pC->pReaderVideoStream->m_basicProperties.m_streamType);
   10507         M4ERR_CHECK_RETURN(err);
   10508     }
   10509 #endif
   10510 
   10511     if(pC->AudioState == M4MCS_kStreamState_STARTED)
   10512     {
   10513         //EVRC
   10514         if(M4DA_StreamTypeAudioEvrc != pStreamHandler->m_streamType)
   10515          /* decoder not supported yet, but allow to do null encoding */
   10516         {
   10517             err = M4MCS_setCurrentAudioDecoder(pContext,
   10518                  pC->pReaderAudioStream->m_basicProperties.m_streamType);
   10519             M4ERR_CHECK_RETURN(err);
   10520         }
   10521     }
   10522 
   10523     /**
   10524     * Get the audio and video stream properties */
   10525     err = M4MCS_intGetInputClipProperties(pC);
   10526     if (M4NO_ERROR != err)
   10527     {
   10528         M4OSA_TRACE1_1("M4MCS_open_normalMode():\
   10529              M4MCS_intGetInputClipProperties returns 0x%x", err);
   10530         return err;
   10531     }
   10532 
   10533     /**
   10534     * Set the begin cut decoding increment according to the input frame rate */
   10535     if (0. != pC->InputFileProperties.fAverageFrameRate) /**< sanity check */
   10536     {
   10537         pC->iVideoBeginDecIncr = (M4OSA_Int32)(3000. \
   10538             / pC->InputFileProperties.fAverageFrameRate); /**< about 3 frames */
   10539     }
   10540     else
   10541     {
   10542         pC->iVideoBeginDecIncr = 200; /**< default value: 200 milliseconds (3 frames @ 15fps)*/
   10543     }
   10544 
   10545     /**
   10546     * Update state automaton */
   10547     pC->State = M4MCS_kState_OPENED;
   10548 
   10549     /**
   10550     * Return with no error */
   10551     M4OSA_TRACE3_0("M4MCS_open_normalMode(): returning M4NO_ERROR");
   10552     return M4NO_ERROR;
   10553 }
   10554 
   10555 M4OSA_ERR M4MCS_intCheckAndGetCodecProperties(
   10556                                  M4MCS_InternalContext *pC) {
   10557 
   10558     M4OSA_ERR err = M4NO_ERROR;
   10559     M4AD_Buffer outputBuffer;
   10560     uint32_t optionValue =0;
   10561 
   10562     M4OSA_TRACE3_0("M4MCS_intCheckAndGetCodecProperties :start");
   10563 
   10564     // Decode first audio frame from clip to get properties from codec
   10565 
   10566     if (M4DA_StreamTypeAudioAac ==
   10567             pC->pReaderAudioStream->m_basicProperties.m_streamType) {
   10568 
   10569         err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(
   10570                     &pC->pAudioDecCtxt,
   10571                     pC->pReaderAudioStream, &(pC->AacProperties));
   10572     } else {
   10573         err = pC->m_pAudioDecoder->m_pFctCreateAudioDec(
   10574                     &pC->pAudioDecCtxt,
   10575                     pC->pReaderAudioStream,
   10576                     pC->m_pCurrentAudioDecoderUserData);
   10577     }
   10578     if (M4NO_ERROR != err) {
   10579 
   10580         M4OSA_TRACE1_1(
   10581             "M4MCS_intCheckAndGetCodecProperties: m_pFctCreateAudioDec \
   10582              returns 0x%x", err);
   10583         return err;
   10584     }
   10585 
   10586     pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
   10587            M4AD_kOptionID_3gpReaderInterface, (M4OSA_DataOption) pC->m_pReaderDataIt);
   10588 
   10589     pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt,
   10590            M4AD_kOptionID_AudioAU, (M4OSA_DataOption) &pC->ReaderAudioAU);
   10591 
   10592     if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) {
   10593 
   10594         err = pC->m_pAudioDecoder->m_pFctStartAudioDec(pC->pAudioDecCtxt);
   10595         if( M4NO_ERROR != err ) {
   10596 
   10597             M4OSA_TRACE1_1(
   10598                 "M4MCS_intCheckAndGetCodecProperties: m_pFctStartAudioDec \
   10599                  returns 0x%x", err);
   10600             return err;
   10601         }
   10602     }
   10603 
   10604     /**
   10605     * Allocate output buffer for the audio decoder */
   10606     outputBuffer.m_bufferSize =
   10607         pC->pReaderAudioStream->m_byteFrameLength
   10608         * pC->pReaderAudioStream->m_byteSampleSize
   10609         * pC->pReaderAudioStream->m_nbChannels;
   10610 
   10611     if( outputBuffer.m_bufferSize > 0 ) {
   10612 
   10613         outputBuffer.m_dataAddress =
   10614             (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(outputBuffer.m_bufferSize \
   10615             *sizeof(short), M4MCS, (M4OSA_Char *)"outputBuffer.m_bufferSize");
   10616 
   10617         if( M4OSA_NULL == outputBuffer.m_dataAddress ) {
   10618 
   10619             M4OSA_TRACE1_0(
   10620                 "M4MCS_intCheckAndGetCodecProperties():\
   10621                  unable to allocate outputBuffer.m_dataAddress, returning M4ERR_ALLOC");
   10622             return M4ERR_ALLOC;
   10623         }
   10624     }
   10625 
   10626     err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt,
   10627         M4OSA_NULL, &outputBuffer, M4OSA_FALSE);
   10628 
   10629     if ( err == M4WAR_INFO_FORMAT_CHANGE ) {
   10630 
   10631         // Get the properties from codec node
   10632         pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt,
   10633            M4AD_kOptionID_AudioNbChannels, (M4OSA_DataOption) &optionValue);
   10634 
   10635         // Reset Reader structure value also
   10636         pC->pReaderAudioStream->m_nbChannels = optionValue;
   10637 
   10638         pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt,
   10639          M4AD_kOptionID_AudioSampFrequency, (M4OSA_DataOption) &optionValue);
   10640 
   10641         // Reset Reader structure value also
   10642         pC->pReaderAudioStream->m_samplingFrequency = optionValue;
   10643 
   10644         if (M4DA_StreamTypeAudioAac ==
   10645             pC->pReaderAudioStream->m_basicProperties.m_streamType) {
   10646 
   10647             pC->AacProperties.aNumChan =
   10648                 pC->pReaderAudioStream->m_nbChannels;
   10649             pC->AacProperties.aSampFreq =
   10650                 pC->pReaderAudioStream->m_samplingFrequency;
   10651 
   10652         }
   10653 
   10654     } else if( err != M4NO_ERROR) {
   10655         M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecProperties:\
   10656             m_pFctStepAudioDec returns err = 0x%x", err);
   10657     }
   10658 
   10659     free(outputBuffer.m_dataAddress);
   10660 
   10661     // Reset the stream reader
   10662     err = pC->m_pReader->m_pFctReset(pC->pReaderContext,
   10663                  (M4_StreamHandler *)pC->pReaderAudioStream);
   10664 
   10665     if (M4NO_ERROR != err) {
   10666         M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecProperties\
   10667             Error in reseting reader: 0x%x", err);
   10668     }
   10669 
   10670     return err;
   10671 
   10672 }
   10673 
   10674 M4OSA_ERR M4MCS_intLimitBitratePerCodecProfileLevel(
   10675                                  M4ENCODER_AdvancedParams* EncParams) {
   10676 
   10677     M4OSA_ERR err = M4NO_ERROR;
   10678 
   10679     switch (EncParams->Format) {
   10680         case M4ENCODER_kH263:
   10681             EncParams->Bitrate = M4MCS_intLimitBitrateForH263Enc(
   10682                                      EncParams->videoProfile,
   10683                                      EncParams->videoLevel, EncParams->Bitrate);
   10684             break;
   10685 
   10686         case M4ENCODER_kMPEG4:
   10687             EncParams->Bitrate = M4MCS_intLimitBitrateForMpeg4Enc(
   10688                                      EncParams->videoProfile,
   10689                                      EncParams->videoLevel, EncParams->Bitrate);
   10690             break;
   10691 
   10692         case M4ENCODER_kH264:
   10693             EncParams->Bitrate = M4MCS_intLimitBitrateForH264Enc(
   10694                                      EncParams->videoProfile,
   10695                                      EncParams->videoLevel, EncParams->Bitrate);
   10696             break;
   10697 
   10698         default:
   10699             M4OSA_TRACE1_1("M4MCS_intLimitBitratePerCodecProfileLevel: \
   10700                 Wrong enc format %d", EncParams->Format);
   10701             err = M4ERR_PARAMETER;
   10702             break;
   10703     }
   10704 
   10705     return err;
   10706 
   10707 }
   10708 
   10709 M4OSA_Int32 M4MCS_intLimitBitrateForH264Enc(M4OSA_Int32 profile,
   10710                                     M4OSA_Int32 level, M4OSA_Int32 bitrate) {
   10711 
   10712     M4OSA_Int32 vidBitrate = 0;
   10713 
   10714     switch (profile) {
   10715         case OMX_VIDEO_AVCProfileBaseline:
   10716         case OMX_VIDEO_AVCProfileMain:
   10717 
   10718             switch (level) {
   10719 
   10720                 case OMX_VIDEO_AVCLevel1:
   10721                     vidBitrate = (bitrate > 64000) ? 64000 : bitrate;
   10722                     break;
   10723 
   10724                 case OMX_VIDEO_AVCLevel1b:
   10725                     vidBitrate = (bitrate > 128000) ? 128000 : bitrate;
   10726                     break;
   10727 
   10728                 case OMX_VIDEO_AVCLevel11:
   10729                     vidBitrate = (bitrate > 192000) ? 192000 : bitrate;
   10730                     break;
   10731 
   10732                 case OMX_VIDEO_AVCLevel12:
   10733                     vidBitrate = (bitrate > 384000) ? 384000 : bitrate;
   10734                     break;
   10735 
   10736                 case OMX_VIDEO_AVCLevel13:
   10737                     vidBitrate = (bitrate > 768000) ? 768000 : bitrate;
   10738                     break;
   10739 
   10740                 case OMX_VIDEO_AVCLevel2:
   10741                     vidBitrate = (bitrate > 2000000) ? 2000000 : bitrate;
   10742                     break;
   10743 
   10744                 case OMX_VIDEO_AVCLevel21:
   10745                     vidBitrate = (bitrate > 4000000) ? 4000000 : bitrate;
   10746                     break;
   10747 
   10748                 case OMX_VIDEO_AVCLevel22:
   10749                     vidBitrate = (bitrate > 4000000) ? 4000000 : bitrate;
   10750                     break;
   10751 
   10752                 case OMX_VIDEO_AVCLevel3:
   10753                     vidBitrate = (bitrate > 10000000) ? 10000000 : bitrate;
   10754                     break;
   10755 
   10756                 case OMX_VIDEO_AVCLevel31:
   10757                     vidBitrate = (bitrate > 14000000) ? 14000000 : bitrate;
   10758                     break;
   10759 
   10760                 case OMX_VIDEO_AVCLevel32:
   10761                     vidBitrate = (bitrate > 20000000) ? 20000000 : bitrate;
   10762                     break;
   10763 
   10764                 case OMX_VIDEO_AVCLevel4:
   10765                     vidBitrate = (bitrate > 20000000) ? 20000000 : bitrate;
   10766                     break;
   10767 
   10768                 case OMX_VIDEO_AVCLevel41:
   10769                     vidBitrate = (bitrate > 50000000) ? 50000000 : bitrate;
   10770                     break;
   10771 
   10772                 case OMX_VIDEO_AVCLevel42:
   10773                     vidBitrate = (bitrate > 50000000) ? 50000000 : bitrate;
   10774                     break;
   10775 
   10776                 case OMX_VIDEO_AVCLevel5:
   10777                     vidBitrate = (bitrate > 135000000) ? 135000000 : bitrate;
   10778                     break;
   10779 
   10780                 case OMX_VIDEO_AVCLevel51:
   10781                     vidBitrate = (bitrate > 240000000) ? 240000000 : bitrate;
   10782                     break;
   10783 
   10784                 default:
   10785                     vidBitrate = bitrate;
   10786                     break;
   10787             }
   10788             break;
   10789 
   10790         case OMX_VIDEO_AVCProfileHigh:
   10791             switch (level) {
   10792                 case OMX_VIDEO_AVCLevel1:
   10793                     vidBitrate = (bitrate > 80000) ? 80000 : bitrate;
   10794                     break;
   10795 
   10796                 case OMX_VIDEO_AVCLevel1b:
   10797                     vidBitrate = (bitrate > 160000) ? 160000 : bitrate;
   10798                     break;
   10799 
   10800                 case OMX_VIDEO_AVCLevel11:
   10801                     vidBitrate = (bitrate > 240000) ? 240000 : bitrate;
   10802                     break;
   10803 
   10804                 case OMX_VIDEO_AVCLevel12:
   10805                     vidBitrate = (bitrate > 480000) ? 480000 : bitrate;
   10806                     break;
   10807 
   10808                 case OMX_VIDEO_AVCLevel13:
   10809                     vidBitrate = (bitrate > 960000) ? 960000 : bitrate;
   10810                     break;
   10811 
   10812                 case OMX_VIDEO_AVCLevel2:
   10813                     vidBitrate = (bitrate > 2500000) ? 2500000 : bitrate;
   10814                     break;
   10815 
   10816                 case OMX_VIDEO_AVCLevel21:
   10817                     vidBitrate = (bitrate > 5000000) ? 5000000 : bitrate;
   10818                     break;
   10819 
   10820                 case OMX_VIDEO_AVCLevel22:
   10821                     vidBitrate = (bitrate > 5000000) ? 5000000 : bitrate;
   10822                     break;
   10823 
   10824                 case OMX_VIDEO_AVCLevel3:
   10825                     vidBitrate = (bitrate > 12500000) ? 12500000 : bitrate;
   10826                     break;
   10827 
   10828                 case OMX_VIDEO_AVCLevel31:
   10829                     vidBitrate = (bitrate > 17500000) ? 17500000 : bitrate;
   10830                     break;
   10831 
   10832                 case OMX_VIDEO_AVCLevel32:
   10833                     vidBitrate = (bitrate > 25000000) ? 25000000 : bitrate;
   10834                     break;
   10835 
   10836                 case OMX_VIDEO_AVCLevel4:
   10837                     vidBitrate = (bitrate > 25000000) ? 25000000 : bitrate;
   10838                     break;
   10839 
   10840                 case OMX_VIDEO_AVCLevel41:
   10841                     vidBitrate = (bitrate > 62500000) ? 62500000 : bitrate;
   10842                     break;
   10843 
   10844                 case OMX_VIDEO_AVCLevel42:
   10845                     vidBitrate = (bitrate > 62500000) ? 62500000 : bitrate;
   10846                     break;
   10847 
   10848                 case OMX_VIDEO_AVCLevel5:
   10849                     vidBitrate = (bitrate > 168750000) ? 168750000 : bitrate;
   10850                     break;
   10851 
   10852                 case OMX_VIDEO_AVCLevel51:
   10853                     vidBitrate = (bitrate > 300000000) ? 300000000 : bitrate;
   10854                     break;
   10855 
   10856                 default:
   10857                     vidBitrate = bitrate;
   10858                     break;
   10859             }
   10860             break;
   10861 
   10862         default:
   10863             // We do not handle any other AVC profile for now.
   10864             // Return input bitrate
   10865             vidBitrate = bitrate;
   10866             break;
   10867     }
   10868 
   10869     return vidBitrate;
   10870 }
   10871 
   10872 M4OSA_Int32 M4MCS_intLimitBitrateForMpeg4Enc(M4OSA_Int32 profile,
   10873                                     M4OSA_Int32 level, M4OSA_Int32 bitrate) {
   10874 
   10875     M4OSA_Int32 vidBitrate = 0;
   10876 
   10877     switch (profile) {
   10878         case OMX_VIDEO_MPEG4ProfileSimple:
   10879             switch (level) {
   10880 
   10881                 case OMX_VIDEO_MPEG4Level0:
   10882                     vidBitrate = (bitrate > 64000) ? 64000 : bitrate;
   10883                     break;
   10884 
   10885                 case OMX_VIDEO_MPEG4Level0b:
   10886                     vidBitrate = (bitrate > 128000) ? 128000 : bitrate;
   10887                     break;
   10888 
   10889                 case OMX_VIDEO_MPEG4Level1:
   10890                     vidBitrate = (bitrate > 64000) ? 64000 : bitrate;
   10891                     break;
   10892 
   10893                 case OMX_VIDEO_MPEG4Level2:
   10894                     vidBitrate = (bitrate > 128000) ? 128000 : bitrate;
   10895                     break;
   10896 
   10897                 case OMX_VIDEO_MPEG4Level3:
   10898                     vidBitrate = (bitrate > 384000) ? 384000 : bitrate;
   10899                     break;
   10900 
   10901                 default:
   10902                     vidBitrate = bitrate;
   10903                     break;
   10904             }
   10905             break;
   10906 
   10907         default:
   10908             // We do not handle any other MPEG4 profile for now.
   10909             // Return input bitrate
   10910             vidBitrate = bitrate;
   10911             break;
   10912     }
   10913 
   10914     return vidBitrate;
   10915 }
   10916 
   10917 M4OSA_Int32 M4MCS_intLimitBitrateForH263Enc(M4OSA_Int32 profile,
   10918                                     M4OSA_Int32 level, M4OSA_Int32 bitrate) {
   10919 
   10920     M4OSA_Int32 vidBitrate = 0;
   10921 
   10922     switch (profile) {
   10923         case OMX_VIDEO_H263ProfileBaseline:
   10924             switch (level) {
   10925 
   10926                 case OMX_VIDEO_H263Level10:
   10927                     vidBitrate = (bitrate > 64000) ? 64000 : bitrate;
   10928                     break;
   10929 
   10930                 case OMX_VIDEO_H263Level20:
   10931                     vidBitrate = (bitrate > 128000) ? 128000 : bitrate;
   10932                     break;
   10933 
   10934                 case OMX_VIDEO_H263Level30:
   10935                     vidBitrate = (bitrate > 384000) ? 384000 : bitrate;
   10936                     break;
   10937 
   10938                 default:
   10939                     vidBitrate = bitrate;
   10940                     break;
   10941             }
   10942             break;
   10943 
   10944         default:
   10945             // We do not handle any other H263 profile for now.
   10946             // Return input bitrate
   10947             vidBitrate = bitrate;
   10948             break;
   10949     }
   10950 
   10951     return vidBitrate;
   10952 }
   10953