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