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  * @file    M4VSS3GPP_Clip.c
     19  * @brief    Implementation of functions related to input clip management.
     20  * @note    All functions in this file are static, i.e. non public
     21  ******************************************************************************
     22  */
     23 
     24 /****************/
     25 /*** Includes ***/
     26 /****************/
     27 
     28 #include "NXPSW_CompilerSwitches.h"
     29 /**
     30  *    Our headers */
     31 #include "M4VSS3GPP_API.h"
     32 #include "M4VSS3GPP_ErrorCodes.h"
     33 #include "M4VSS3GPP_InternalTypes.h"
     34 #include "M4VSS3GPP_InternalFunctions.h"
     35 #include "M4VSS3GPP_InternalConfig.h"
     36 
     37 /**
     38  *    OSAL headers */
     39 #include "M4OSA_Memory.h" /* OSAL memory management */
     40 #include "M4OSA_Debug.h"  /* OSAL debug management */
     41 
     42 
     43 /**
     44  * Common headers (for aac) */
     45 #include "M4_Common.h"
     46 
     47 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
     48 #include "M4VD_EXTERNAL_Interface.h"
     49 
     50 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
     51 
     52 /* Osal header fileno */
     53 #include "M4OSA_CharStar.h"
     54 
     55 /**
     56  ******************************************************************************
     57  * define    Static function prototypes
     58  ******************************************************************************
     59  */
     60 
     61 static M4OSA_ERR M4VSS3GPP_intClipPrepareAudioDecoder(
     62     M4VSS3GPP_ClipContext *pClipCtxt );
     63 
     64 static M4OSA_ERR M4VSS3GPP_intCheckAndGetCodecAacProperties(
     65         M4VSS3GPP_ClipContext *pClipCtxt);
     66 
     67 /**
     68  ******************************************************************************
     69  * M4OSA_ERR M4VSS3GPP_intClipOpen()
     70  * @brief    Open a clip. Creates a clip context.
     71  * @note
     72  * @param   hClipCtxt            (OUT) Return the internal clip context
     73  * @param   pClipSettings        (IN) Edit settings of this clip. The module will keep a
     74  *                               reference to this pointer
     75  * @param    pFileReadPtrFct        (IN) Pointer to OSAL file reader functions
     76  * @param    bSkipAudioTrack        (IN) If true, do not open the audio
     77  * @param    bFastOpenMode        (IN) If true, use the fast mode of the 3gpp reader
     78  *                             (only the first AU is read)
     79  * @return    M4NO_ERROR:                No error
     80  * @return    M4ERR_ALLOC:            There is no more available memory
     81  ******************************************************************************
     82  */
     83 
     84 M4OSA_ERR M4VSS3GPP_intClipInit( M4VSS3GPP_ClipContext ** hClipCtxt,
     85                                 M4OSA_FileReadPointer *pFileReadPtrFct )
     86 {
     87     M4VSS3GPP_ClipContext *pClipCtxt;
     88     M4OSA_ERR err;
     89 
     90     M4OSA_DEBUG_IF2((M4OSA_NULL == hClipCtxt), M4ERR_PARAMETER,
     91         "M4VSS3GPP_intClipInit: hClipCtxt is M4OSA_NULL");
     92     M4OSA_DEBUG_IF2((M4OSA_NULL == pFileReadPtrFct), M4ERR_PARAMETER,
     93         "M4VSS3GPP_intClipInit: pFileReadPtrFct is M4OSA_NULL");
     94 
     95     /**
     96     * Allocate the clip context */
     97     *hClipCtxt =
     98         (M4VSS3GPP_ClipContext *)M4OSA_32bitAlignedMalloc(sizeof(M4VSS3GPP_ClipContext),
     99         M4VSS3GPP, (M4OSA_Char *)"M4VSS3GPP_ClipContext");
    100 
    101     if( M4OSA_NULL == *hClipCtxt )
    102     {
    103         M4OSA_TRACE1_0(
    104             "M4VSS3GPP_intClipInit(): unable to allocate M4VSS3GPP_ClipContext,\
    105             returning M4ERR_ALLOC");
    106         return M4ERR_ALLOC;
    107     }
    108     M4OSA_TRACE3_1("M4VSS3GPP_intClipInit(): clipCtxt=0x%x", *hClipCtxt);
    109 
    110 
    111     /**
    112     * Use this shortcut to simplify the code */
    113     pClipCtxt = *hClipCtxt;
    114 
    115     /* Inialization of context Variables */
    116     memset((void *)pClipCtxt, 0,sizeof(M4VSS3GPP_ClipContext));
    117 
    118     pClipCtxt->pSettings = M4OSA_NULL;
    119 
    120     /**
    121     * Init the clip context */
    122     pClipCtxt->iVoffset = 0;
    123     pClipCtxt->iAoffset = 0;
    124     pClipCtxt->Vstatus = M4VSS3GPP_kClipStatus_READ;
    125     pClipCtxt->Astatus = M4VSS3GPP_kClipStatus_READ;
    126 
    127     pClipCtxt->pReaderContext = M4OSA_NULL;
    128     pClipCtxt->pVideoStream = M4OSA_NULL;
    129     pClipCtxt->pAudioStream = M4OSA_NULL;
    130     pClipCtxt->VideoAU.m_dataAddress = M4OSA_NULL;
    131     pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL;
    132 
    133     pClipCtxt->pViDecCtxt = M4OSA_NULL;
    134     pClipCtxt->iVideoDecCts = 0;
    135     pClipCtxt->iVideoRenderCts = 0;
    136     pClipCtxt->lastDecodedPlane = M4OSA_NULL;
    137     pClipCtxt->iActualVideoBeginCut = 0;
    138     pClipCtxt->iActualAudioBeginCut = 0;
    139     pClipCtxt->bVideoAuAvailable = M4OSA_FALSE;
    140     pClipCtxt->bFirstAuWritten = M4OSA_FALSE;
    141 
    142     pClipCtxt->bMpeg4GovState = M4OSA_FALSE;
    143 
    144     pClipCtxt->bAudioFrameAvailable = M4OSA_FALSE;
    145     pClipCtxt->pAudioFramePtr = M4OSA_NULL;
    146     pClipCtxt->iAudioFrameCts = 0;
    147     pClipCtxt->pAudioDecCtxt = 0;
    148     pClipCtxt->AudioDecBufferOut.m_bufferSize = 0;
    149     pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL;
    150 
    151     pClipCtxt->pFileReadPtrFct = pFileReadPtrFct;
    152     pClipCtxt->pPlaneYuv   = M4OSA_NULL;
    153     pClipCtxt->pPlaneYuvWithEffect = M4OSA_NULL;
    154     pClipCtxt->m_pPreResizeFrame = M4OSA_NULL;
    155     pClipCtxt->bGetYuvDataFromDecoder = M4OSA_TRUE;
    156 
    157     /*
    158     * Reset pointers for media and codecs interfaces */
    159     err = M4VSS3GPP_clearInterfaceTables(&pClipCtxt->ShellAPI);
    160     M4ERR_CHECK_RETURN(err);
    161 
    162     /*
    163     *  Call the media and codecs subscription module */
    164     err = M4VSS3GPP_subscribeMediaAndCodec(&pClipCtxt->ShellAPI);
    165     M4ERR_CHECK_RETURN(err);
    166 
    167     return M4NO_ERROR;
    168 }
    169 
    170 /* Note: if the clip is opened in fast mode, it can only be used for analysis and nothing else. */
    171 M4OSA_ERR M4VSS3GPP_intClipOpen( M4VSS3GPP_ClipContext *pClipCtxt,
    172                                 M4VSS3GPP_ClipSettings *pClipSettings, M4OSA_Bool bSkipAudioTrack,
    173                                 M4OSA_Bool bFastOpenMode, M4OSA_Bool bAvoidOpeningVideoDec )
    174 {
    175     M4OSA_ERR err;
    176     M4READER_MediaFamily mediaFamily;
    177     M4_StreamHandler *pStreamHandler;
    178     M4_StreamHandler  dummyStreamHandler;
    179     M4OSA_Int32 iDuration;
    180     M4OSA_Void *decoderUserData;
    181 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
    182 
    183     M4DECODER_MPEG4_DecoderConfigInfo dummy;
    184     M4DECODER_VideoSize videoSizeFromDSI;
    185 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
    186 
    187     M4DECODER_OutputFilter FilterOption;
    188     M4OSA_Char pTempFile[100];
    189 
    190     /**
    191     *    Check input parameters */
    192     M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER,
    193         "M4VSS3GPP_intClipOpen: pClipCtxt is M4OSA_NULL");
    194     M4OSA_DEBUG_IF2((M4OSA_NULL == pClipSettings), M4ERR_PARAMETER,
    195         "M4VSS3GPP_intClipOpen: pClipSettings is M4OSA_NULL");
    196 
    197     M4OSA_TRACE3_2(
    198         "M4VSS3GPP_intClipOpen: called with pClipCtxt: 0x%x, bAvoidOpeningVideoDec=0x%x",
    199         pClipCtxt, bAvoidOpeningVideoDec);
    200     /**
    201     * Keep a pointer to the clip settings. Remember that we don't possess it! */
    202     pClipCtxt->pSettings = pClipSettings;
    203     if(M4VIDEOEDITING_kFileType_ARGB8888 == pClipCtxt->pSettings->FileType) {
    204         M4OSA_TRACE3_0("M4VSS3GPP_intClipOpen: Image stream; set current vid dec");
    205         err = M4VSS3GPP_setCurrentVideoDecoder(
    206                   &pClipCtxt->ShellAPI, M4DA_StreamTypeVideoARGB8888);
    207         M4ERR_CHECK_RETURN(err);
    208 
    209         decoderUserData = M4OSA_NULL;
    210 
    211         err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctCreate(
    212                   &pClipCtxt->pViDecCtxt,
    213                   &dummyStreamHandler,
    214                   pClipCtxt->ShellAPI.m_pReader,
    215                   pClipCtxt->ShellAPI.m_pReaderDataIt,
    216                   &pClipCtxt->VideoAU,
    217                   decoderUserData);
    218 
    219         if (M4NO_ERROR != err) {
    220             M4OSA_TRACE1_1("M4VSS3GPP_intClipOpen: \
    221                 m_pVideoDecoder->m_pFctCreate returns 0x%x", err);
    222             return err;
    223         }
    224         M4OSA_TRACE3_1("M4VSS3GPP_intClipOpen: \
    225             Vid dec started; pViDecCtxt=0x%x", pClipCtxt->pViDecCtxt);
    226 
    227         return M4NO_ERROR;
    228     }
    229 
    230     /**
    231     * Get the correct reader interface */
    232     err = M4VSS3GPP_setCurrentReader(&pClipCtxt->ShellAPI,
    233         pClipCtxt->pSettings->FileType);
    234     M4ERR_CHECK_RETURN(err);
    235 
    236     /**
    237     * Init the 3GPP or MP3 reader */
    238     err =
    239         pClipCtxt->ShellAPI.m_pReader->m_pFctCreate(&pClipCtxt->pReaderContext);
    240 
    241     if( M4NO_ERROR != err )
    242     {
    243         M4OSA_TRACE1_1(
    244             "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctCreate returns 0x%x",
    245             err);
    246         return err;
    247     }
    248 
    249     /**
    250     * Link the reader interface to the reader context (used by the decoder to know the reader) */
    251     pClipCtxt->ShellAPI.m_pReaderDataIt->m_readerContext =
    252         pClipCtxt->pReaderContext;
    253 
    254     /**
    255     * Set the OSAL read function set */
    256     err = pClipCtxt->ShellAPI.m_pReader->m_pFctSetOption(
    257         pClipCtxt->pReaderContext,
    258         M4READER_kOptionID_SetOsaFileReaderFctsPtr,
    259         (M4OSA_DataOption)(pClipCtxt->pFileReadPtrFct));
    260 
    261     if( M4NO_ERROR != err )
    262     {
    263         M4OSA_TRACE1_1(
    264             "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctSetOption returns 0x%x",
    265             err);
    266         return err;
    267     }
    268 
    269     /**
    270     * Set the fast open mode if asked (3GPP only) */
    271     if( M4VIDEOEDITING_kFileType_3GPP == pClipCtxt->pSettings->FileType )
    272     {
    273         if( M4OSA_TRUE == bFastOpenMode )
    274         {
    275             err = pClipCtxt->ShellAPI.m_pReader->m_pFctSetOption(
    276                 pClipCtxt->pReaderContext,
    277                 M4READER_3GP_kOptionID_FastOpenMode, M4OSA_NULL);
    278 
    279             if( M4NO_ERROR != err )
    280             {
    281                 M4OSA_TRACE1_1(
    282                     "M4VSS3GPP_intClipOpen():\
    283                     m_pReader->m_pFctSetOption(FastOpenMode) returns 0x%x",
    284                     err);
    285                 return err;
    286             }
    287         }
    288 
    289         /**
    290         * Set the skip audio option if asked */
    291         if( M4OSA_TRUE == bSkipAudioTrack )
    292         {
    293             err = pClipCtxt->ShellAPI.m_pReader->m_pFctSetOption(
    294                 pClipCtxt->pReaderContext,
    295                 M4READER_3GP_kOptionID_VideoOnly, M4OSA_NULL);
    296 
    297             if( M4NO_ERROR != err )
    298             {
    299                 M4OSA_TRACE1_1(
    300                     "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctSetOption(VideoOnly) returns 0x%x",
    301                     err);
    302                 return err;
    303             }
    304         }
    305     }
    306     if(pClipCtxt->pSettings->FileType == M4VIDEOEDITING_kFileType_PCM)
    307     {
    308 
    309 
    310 
    311 
    312         M4OSA_chrNCopy(pTempFile,pClipSettings->pFile,strlen(pClipSettings->pFile));
    313 
    314 
    315     switch (pClipCtxt->pSettings->ClipProperties.uiSamplingFrequency)
    316     {
    317         case 8000:
    318         strncat((char *)pTempFile,(const char *)"_8000",6);
    319         break;
    320         case 11025:
    321         strncat((char *)pTempFile,(const char *)"_11025",6);
    322         break;
    323         case 12000:
    324         strncat((char *)pTempFile,(const char *)"_12000",6);
    325         break;
    326         case 16000:
    327         strncat((char *)pTempFile,(const char *)"_16000",6);
    328         break;
    329         case 22050:
    330         strncat((char *)pTempFile,(const char *)"_22050",6);
    331         break;
    332         case 24000:
    333         strncat((char *)pTempFile,(const char *)"_24000",6);
    334         break;
    335         case 32000:
    336         strncat((char *)pTempFile,(const char *)"_32000",6);
    337         break;
    338         case 44100:
    339         strncat((char *)pTempFile,(const char *)"_44100",6);
    340         break;
    341         case 48000:
    342         strncat((char *)pTempFile,(const char *)"_48000",6);
    343         break;
    344         default:
    345             M4OSA_TRACE1_1("M4VSS3GPP_intClipOpen: invalid input for BG tracksampling \
    346                 frequency (%d Hz), returning M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY"\
    347                     ,pClipCtxt->pSettings->ClipProperties.uiSamplingFrequency );
    348             return M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY;
    349     }
    350 
    351 
    352 
    353         //M4OSA_chrNCat(pTempFile,
    354         //    itoa(pClipCtxt->pSettings->ClipProperties.uiSamplingFrequency),5);
    355         switch(pClipCtxt->pSettings->ClipProperties.uiNbChannels)
    356         {
    357             case 1:
    358                 strncat((char *)pTempFile,(const char *)"_1.pcm",6);
    359             break;
    360             case 2:
    361                 strncat((char *)pTempFile,(const char *)"_2.pcm",6);
    362             break;
    363             default:
    364             M4OSA_TRACE1_1("M4VSS3GPP_intClipOpen: invalid input for BG track no.\
    365                  of channels (%d ), returning M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS",\
    366                     pClipCtxt->pSettings->ClipProperties.uiNbChannels);
    367             return    M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS;
    368         }
    369         //M4OSA_chrNCat(pTempFile,itoa(pClipCtxt->pSettings->ClipProperties.uiNbChannels),1);
    370 
    371         err = pClipCtxt->ShellAPI.m_pReader->m_pFctOpen( pClipCtxt->pReaderContext, pTempFile);
    372 
    373     }
    374     else
    375     {
    376     /**
    377         * Open the 3GPP/MP3 clip file */
    378         err = pClipCtxt->ShellAPI.m_pReader->m_pFctOpen( pClipCtxt->pReaderContext,
    379              pClipSettings->pFile);
    380     }
    381     if( M4NO_ERROR != err )
    382     {
    383         M4OSA_UInt32 uiDummy, uiCoreId;
    384         M4OSA_TRACE1_1(
    385             "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctOpen returns 0x%x", err);
    386 
    387         /**
    388         * If the error is from the core reader, we change it to a public VSS3GPP error */
    389         M4OSA_ERR_SPLIT(err, uiDummy, uiCoreId, uiDummy);
    390 
    391         if( M4MP4_READER == uiCoreId )
    392         {
    393             M4OSA_TRACE1_0(
    394                 "M4VSS3GPP_intClipOpen(): returning M4VSS3GPP_ERR_INVALID_3GPP_FILE");
    395             return M4VSS3GPP_ERR_INVALID_3GPP_FILE;
    396         }
    397         return err;
    398     }
    399 
    400     /**
    401     * Get the audio and video streams */
    402     while( err == M4NO_ERROR )
    403     {
    404         err = pClipCtxt->ShellAPI.m_pReader->m_pFctGetNextStream(
    405             pClipCtxt->pReaderContext, &mediaFamily, &pStreamHandler);
    406 
    407         /*in case we found a BIFS stream or something else...*/
    408         if( ( err == ((M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE))
    409             || (err == ((M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS)) )
    410         {
    411             err = M4NO_ERROR;
    412             continue;
    413         }
    414 
    415         if( M4NO_ERROR == err ) /**< One stream found */
    416         {
    417             /**
    418             * Found a video stream */
    419             if( ( mediaFamily == M4READER_kMediaFamilyVideo)
    420                 && (M4OSA_NULL == pClipCtxt->pVideoStream) )
    421             {
    422                 if( ( M4DA_StreamTypeVideoH263 == pStreamHandler->m_streamType)
    423                     || (M4DA_StreamTypeVideoMpeg4
    424                     == pStreamHandler->m_streamType)
    425                     || (M4DA_StreamTypeVideoMpeg4Avc
    426                     == pStreamHandler->m_streamType) )
    427                 {
    428                     M4OSA_TRACE3_1(
    429                         "M4VSS3GPP_intClipOpen():\
    430                         Found a H263 or MPEG-4 or H264 video stream in input 3gpp clip; %d",
    431                         pStreamHandler->m_streamType);
    432 
    433                     /**
    434                     * Keep pointer to the video stream */
    435                     pClipCtxt->pVideoStream =
    436                         (M4_VideoStreamHandler *)pStreamHandler;
    437                     pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
    438 
    439                     /**
    440                     * Reset the stream reader */
    441                     err = pClipCtxt->ShellAPI.m_pReader->m_pFctReset(
    442                         pClipCtxt->pReaderContext,
    443                         (M4_StreamHandler *)pClipCtxt->pVideoStream);
    444 
    445                     if( M4NO_ERROR != err )
    446                     {
    447                         M4OSA_TRACE1_1(
    448                             "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctReset(video) returns 0x%x",
    449                             err);
    450                         return err;
    451                     }
    452 
    453                     /**
    454                     * Initializes an access Unit */
    455                     err = pClipCtxt->ShellAPI.m_pReader->m_pFctFillAuStruct(
    456                         pClipCtxt->pReaderContext,
    457                         (M4_StreamHandler *)pClipCtxt->pVideoStream,
    458                         &pClipCtxt->VideoAU);
    459 
    460                     if( M4NO_ERROR != err )
    461                     {
    462                         M4OSA_TRACE1_1(
    463                             "M4VSS3GPP_intClipOpen():\
    464                             m_pReader->m_pFctFillAuStruct(video) returns 0x%x",
    465                             err);
    466                         return err;
    467                     }
    468                 }
    469                 else /**< Not H263 or MPEG-4 (H264, etc.) */
    470                 {
    471                     M4OSA_TRACE1_1(
    472                         "M4VSS_editClipOpen():\
    473                         Found an unsupported video stream (0x%x) in input 3gpp clip",
    474                         pStreamHandler->m_streamType);
    475 
    476                     pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
    477                 }
    478             }
    479             /**
    480             * Found an audio stream */
    481             else if( ( mediaFamily == M4READER_kMediaFamilyAudio)
    482                 && (M4OSA_NULL == pClipCtxt->pAudioStream) )
    483             {
    484                 if( ( M4DA_StreamTypeAudioAmrNarrowBand
    485                     == pStreamHandler->m_streamType)
    486                     || (M4DA_StreamTypeAudioAac == pStreamHandler->m_streamType)
    487                     || (M4DA_StreamTypeAudioMp3
    488                     == pStreamHandler->m_streamType)
    489                     || (M4DA_StreamTypeAudioEvrc
    490                     == pStreamHandler->m_streamType)
    491                     || (M4DA_StreamTypeAudioPcm
    492                     == pStreamHandler->m_streamType) )
    493                 {
    494                     M4OSA_TRACE3_1(
    495                         "M4VSS3GPP_intClipOpen(): \
    496                         Found an AMR-NB or AAC or MP3 audio stream in input clip; %d",
    497                         pStreamHandler->m_streamType);
    498 
    499                     /**
    500                     * Keep pointer to the audio stream */
    501                     pClipCtxt->pAudioStream =
    502                         (M4_AudioStreamHandler *)pStreamHandler;
    503                     pStreamHandler->m_bStreamIsOK = M4OSA_TRUE;
    504 
    505                     /**
    506                     * Reset the stream reader */
    507                     err = pClipCtxt->ShellAPI.m_pReader->m_pFctReset(
    508                         pClipCtxt->pReaderContext,
    509                         (M4_StreamHandler *)pClipCtxt->pAudioStream);
    510 
    511                     if( M4NO_ERROR != err )
    512                     {
    513                         M4OSA_TRACE1_1(
    514                             "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctReset(audio) returns 0x%x",
    515                             err);
    516                         return err;
    517                     }
    518 
    519                     /**
    520                     * Initializes an access Unit */
    521                     err = pClipCtxt->ShellAPI.m_pReader->m_pFctFillAuStruct(
    522                         pClipCtxt->pReaderContext,
    523                         (M4_StreamHandler *)pClipCtxt->pAudioStream,
    524                         &pClipCtxt->AudioAU);
    525 
    526                     if( M4NO_ERROR != err )
    527                     {
    528                         M4OSA_TRACE1_1(
    529                             "M4VSS3GPP_intClipOpen():\
    530                             m_pReader->m_pFctFillAuStruct(audio) returns 0x%x",
    531                             err);
    532                         return err;
    533                     }
    534                 }
    535                 else /**< Not AMR-NB or AAC (AMR-WB...) */
    536                 {
    537                     M4OSA_TRACE1_1(
    538                         "M4VSS3GPP_intClipOpen():\
    539                         Found an unsupported audio stream (0x%x) in input 3gpp/mp3 clip",
    540                         pStreamHandler->m_streamType);
    541 
    542                     pStreamHandler->m_bStreamIsOK = M4OSA_FALSE;
    543                 }
    544             }
    545         }
    546         else if( M4OSA_ERR_IS_ERROR(err) )
    547         {
    548             M4OSA_TRACE1_1(
    549                 "M4VSS3GPP_intClipOpen(): m_pReader->m_pFctGetNextStream() returns 0x%x!",
    550                 err);
    551             return err;
    552         }
    553     }
    554 
    555     /**
    556     * Init Video decoder */
    557     if( M4OSA_NULL != pClipCtxt->pVideoStream )
    558     {
    559 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
    560   /* If external decoders are possible, it's best to avoid opening the decoder if the clip is only
    561   going to be used for analysis, as we're not going to use it for the analysis in the case of a
    562   possible external decoder anyway, and either there could be no decoder at this point or the HW
    563   decoder could be present, which we want to avoid opening for that. See comments in
    564   intBuildAnalysis for more details. */
    565 
    566   /* CHANGEME Temporarily only do this for MPEG4, since for now only MPEG4 external decoders are
    567   supported, and the following wouldn't work for H263 so a release where external decoders are
    568   possible, but not used, wouldn't work with H263 stuff. */
    569 
    570         if( bAvoidOpeningVideoDec && M4DA_StreamTypeVideoMpeg4
    571             == pClipCtxt->pVideoStream->m_basicProperties.m_streamType )
    572         {
    573             /* Oops! The mere act of opening the decoder also results in the image size being
    574             filled in the video stream! Compensate for this by using ParseVideoDSI to fill
    575             this info. */
    576             M4OSA_TRACE3_0(
    577                 "M4VSS3GPP_intClipOpen: Mpeg4 stream; vid dec not started");
    578             err = M4DECODER_EXTERNAL_ParseVideoDSI(pClipCtxt->pVideoStream->
    579                 m_basicProperties.m_pDecoderSpecificInfo,
    580                 pClipCtxt->pVideoStream->
    581                 m_basicProperties.m_decoderSpecificInfoSize,
    582                 &dummy, &videoSizeFromDSI);
    583 
    584             pClipCtxt->pVideoStream->m_videoWidth = videoSizeFromDSI.m_uiWidth;
    585             pClipCtxt->pVideoStream->m_videoHeight =
    586                 videoSizeFromDSI.m_uiHeight;
    587         }
    588         else
    589         {
    590 
    591 #endif
    592 
    593             M4OSA_TRACE3_0(
    594                 "M4VSS3GPP_intClipOpen: Mp4/H263/H264 stream; set current vid dec");
    595             err = M4VSS3GPP_setCurrentVideoDecoder(&pClipCtxt->ShellAPI,
    596                 pClipCtxt->pVideoStream->m_basicProperties.m_streamType);
    597             M4ERR_CHECK_RETURN(err);
    598 
    599 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
    600 
    601             decoderUserData =
    602                 pClipCtxt->ShellAPI.m_pCurrentVideoDecoderUserData;
    603 
    604 #else
    605 
    606             decoderUserData = M4OSA_NULL;
    607 
    608 #endif
    609 
    610             err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctCreate(
    611                 &pClipCtxt->pViDecCtxt,
    612                 &pClipCtxt->pVideoStream->m_basicProperties,
    613                 pClipCtxt->ShellAPI.m_pReader,
    614                 pClipCtxt->ShellAPI.m_pReaderDataIt,
    615                 &pClipCtxt->VideoAU, decoderUserData);
    616 
    617             if( ( ((M4OSA_UInt32)M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED) == err)
    618                 || (((M4OSA_UInt32)M4ERR_DECODER_H263_NOT_BASELINE) == err) )
    619             {
    620                 /**
    621                 * Our decoder is not compatible with H263 profile other than 0.
    622                 * So it returns this internal error code.
    623                 * We translate it to our own error code */
    624                 return M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED;
    625             }
    626             else if( M4NO_ERROR != err )
    627             {
    628                 M4OSA_TRACE1_1(
    629                     "M4VSS3GPP_intClipOpen: m_pVideoDecoder->m_pFctCreate returns 0x%x",
    630                     err);
    631                 return err;
    632             }
    633             M4OSA_TRACE3_1(
    634                 "M4VSS3GPP_intClipOpen: Vid dec started; pViDecCtxt=0x%x",
    635                 pClipCtxt->pViDecCtxt);
    636 
    637             if( M4DA_StreamTypeVideoMpeg4Avc
    638                 == pClipCtxt->pVideoStream->m_basicProperties.m_streamType )
    639             {
    640                 FilterOption.m_pFilterFunction =
    641                     (M4OSA_Void *) &M4VIFI_ResizeBilinearYUV420toYUV420;
    642                 FilterOption.m_pFilterUserData = M4OSA_NULL;
    643                 err = pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctSetOption(
    644                     pClipCtxt->pViDecCtxt, M4DECODER_kOptionID_OutputFilter,
    645                     (M4OSA_DataOption) &FilterOption);
    646 
    647                 if( M4NO_ERROR != err )
    648                 {
    649                     M4OSA_TRACE1_1(
    650                         "M4VSS3GPP_intClipOpen: m_pVideoDecoder->m_pFctSetOption returns 0x%x",
    651                         err);
    652                     return err;
    653                 }
    654                 else
    655                 {
    656                     M4OSA_TRACE3_0(
    657                         "M4VSS3GPP_intClipOpen: m_pVideoDecoder->m_pFctSetOption\
    658                         M4DECODER_kOptionID_OutputFilter OK");
    659                 }
    660             }
    661 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
    662 
    663         }
    664 
    665 #endif
    666 
    667     }
    668 
    669     /**
    670     * Init Audio decoder */
    671     if( M4OSA_NULL != pClipCtxt->pAudioStream )
    672     {
    673         err = M4VSS3GPP_intClipPrepareAudioDecoder(pClipCtxt);
    674         M4ERR_CHECK_RETURN(err);
    675         M4OSA_TRACE3_1("M4VSS3GPP_intClipOpen: Audio dec started; context=0x%x",
    676             pClipCtxt->pAudioDecCtxt);
    677     }
    678     else
    679     {
    680         pClipCtxt->AudioAU.m_streamID = 0;
    681         pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL;
    682         pClipCtxt->AudioAU.m_size = 0;
    683         pClipCtxt->AudioAU.m_CTS = 0;
    684         pClipCtxt->AudioAU.m_DTS = 0;
    685         pClipCtxt->AudioAU.m_attribute = 0;
    686         pClipCtxt->AudioAU.m_maxsize = 0;
    687         pClipCtxt->AudioAU.m_structSize = sizeof(pClipCtxt->AudioAU);
    688     }
    689 
    690     /**
    691     * Get the duration of the longest stream */
    692     if( M4OSA_TRUE == pClipCtxt->pSettings->ClipProperties.bAnalysed )
    693     {
    694         /* If already calculated set it to previous value */
    695         /* Because fast open and full open can return a different value,
    696            it can mismatch user settings */
    697         /* Video track is more important than audio track (if video track is shorter than
    698            audio track, it can led to cut larger than expected) */
    699         iDuration = pClipCtxt->pSettings->ClipProperties.uiClipVideoDuration;
    700 
    701         if( iDuration == 0 )
    702         {
    703             iDuration = pClipCtxt->pSettings->ClipProperties.uiClipDuration;
    704         }
    705     }
    706     else
    707     {
    708         /* Else compute it from streams */
    709         iDuration = 0;
    710 
    711         if( M4OSA_NULL != pClipCtxt->pVideoStream )
    712         {
    713             iDuration = (M4OSA_Int32)(
    714                 pClipCtxt->pVideoStream->m_basicProperties.m_duration);
    715         }
    716 
    717         if( ( M4OSA_NULL != pClipCtxt->pAudioStream) && ((M4OSA_Int32)(
    718             pClipCtxt->pAudioStream->m_basicProperties.m_duration)
    719             > iDuration) && iDuration == 0 )
    720         {
    721             iDuration = (M4OSA_Int32)(
    722                 pClipCtxt->pAudioStream->m_basicProperties.m_duration);
    723         }
    724     }
    725 
    726     /**
    727     * If end time is not used, we set it to the video track duration */
    728     if( 0 == pClipCtxt->pSettings->uiEndCutTime )
    729     {
    730         pClipCtxt->pSettings->uiEndCutTime = (M4OSA_UInt32)iDuration;
    731     }
    732 
    733     pClipCtxt->iEndTime = (M4OSA_Int32)pClipCtxt->pSettings->uiEndCutTime;
    734 
    735     /**
    736     * Return with no error */
    737     M4OSA_TRACE3_0("M4VSS3GPP_intClipOpen(): returning M4NO_ERROR");
    738     return M4NO_ERROR;
    739 }
    740 
    741 /**
    742  ******************************************************************************
    743  * M4OSA_Void M4VSS3GPP_intClipDeleteAudioTrack()
    744  * @brief    Delete the audio track. Clip will be like if it had no audio track
    745  * @note
    746  * @param   pClipCtxt            (IN) Internal clip context
    747  ******************************************************************************
    748  */
    749 M4OSA_Void M4VSS3GPP_intClipDeleteAudioTrack( M4VSS3GPP_ClipContext *pClipCtxt )
    750 {
    751     /**
    752     * But we don't have to free the audio stream. It will be freed by the reader when closing it*/
    753     pClipCtxt->pAudioStream = M4OSA_NULL;
    754 
    755     /**
    756     * We will return a constant silence AMR AU.
    757     * We set it here once, instead of at each read audio step. */
    758     pClipCtxt->pAudioFramePtr = (M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData;
    759     pClipCtxt->uiAudioFrameSize = pClipCtxt->uiSilenceFrameSize;
    760 
    761     /**
    762     * Free the decoded audio buffer (it needs to be re-allocated to store silence
    763       frame eventually)*/
    764     if( M4OSA_NULL != pClipCtxt->AudioDecBufferOut.m_dataAddress )
    765     {
    766         free(pClipCtxt->AudioDecBufferOut.m_dataAddress);
    767         pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL;
    768     }
    769 
    770     return;
    771 }
    772 
    773 /**
    774  ******************************************************************************
    775  * M4OSA_ERR M4VSS3GPP_intClipDecodeVideoUpToCurrentTime()
    776  * @brief    Jump to the previous RAP and decode up to the current video time
    777  * @param   pClipCtxt    (IN) Internal clip context
    778  * @param   iCts        (IN) Target CTS
    779  ******************************************************************************
    780  */
    781 M4OSA_ERR M4VSS3GPP_intClipDecodeVideoUpToCts( M4VSS3GPP_ClipContext *pClipCtxt,
    782                                               M4OSA_Int32 iCts )
    783 {
    784     M4OSA_Int32 iRapCts, iClipCts;
    785     M4_MediaTime dDecodeTime;
    786     M4OSA_Bool bClipJump = M4OSA_FALSE;
    787     M4OSA_ERR err;
    788 
    789     /**
    790     * Compute the time in the clip base */
    791     iClipCts = iCts - pClipCtxt->iVoffset;
    792 
    793     /**
    794     * If we were reading the clip, we must jump to the previous RAP
    795     * to decode from that point. */
    796     if( M4VSS3GPP_kClipStatus_READ == pClipCtxt->Vstatus )
    797     {
    798         /**
    799         * The decoder must be told to jump */
    800         bClipJump = M4OSA_TRUE;
    801         pClipCtxt->iVideoDecCts = iClipCts;
    802 
    803         /**
    804         * Remember the clip reading state */
    805         pClipCtxt->Vstatus = M4VSS3GPP_kClipStatus_DECODE_UP_TO;
    806     }
    807 
    808     /**
    809     * If we are in decodeUpTo() process, check if we need to do
    810     one more step or if decoding is finished */
    811     if( M4VSS3GPP_kClipStatus_DECODE_UP_TO == pClipCtxt->Vstatus )
    812     {
    813         /* Do a step of 500 ms decoding */
    814         pClipCtxt->iVideoDecCts += 500;
    815 
    816         if( pClipCtxt->iVideoDecCts > iClipCts )
    817         {
    818             /* Target time reached, we switch back to DECODE mode */
    819             pClipCtxt->iVideoDecCts = iClipCts;
    820             pClipCtxt->Vstatus = M4VSS3GPP_kClipStatus_DECODE;
    821         }
    822 
    823         M4OSA_TRACE2_1("c ,,,, decode up to : %ld", pClipCtxt->iVideoDecCts);
    824     }
    825     else
    826     {
    827         /* Just decode at current clip cts */
    828         pClipCtxt->iVideoDecCts = iClipCts;
    829 
    830         M4OSA_TRACE2_1("d ,,,, decode up to : %ld", pClipCtxt->iVideoDecCts);
    831     }
    832 
    833     /**
    834     * Decode up to the target */
    835     M4OSA_TRACE3_2(
    836         "M4VSS3GPP_intClipDecodeVideoUpToCts: Decoding upTo CTS %.3f, pClipCtxt=0x%x",
    837         dDecodeTime, pClipCtxt);
    838 
    839     dDecodeTime = (M4OSA_Double)pClipCtxt->iVideoDecCts;
    840     pClipCtxt->isRenderDup = M4OSA_FALSE;
    841     err =
    842         pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctDecode(pClipCtxt->pViDecCtxt,
    843         &dDecodeTime, bClipJump, 0);
    844 
    845     if( ( M4NO_ERROR != err) && (M4WAR_NO_MORE_AU != err)
    846         && (err != M4WAR_VIDEORENDERER_NO_NEW_FRAME) )
    847     {
    848         M4OSA_TRACE1_1(
    849             "M4VSS3GPP_intClipDecodeVideoUpToCts: m_pFctDecode returns 0x%x!",
    850             err);
    851         return err;
    852     }
    853 
    854     if( err == M4WAR_VIDEORENDERER_NO_NEW_FRAME )
    855     {
    856         pClipCtxt->isRenderDup = M4OSA_TRUE;
    857     }
    858 
    859     /**
    860     * Return */
    861     M4OSA_TRACE3_0("M4VSS3GPP_intClipDecodeVideoUpToCts: returning M4NO_ERROR");
    862     return M4NO_ERROR;
    863 }
    864 
    865 /**
    866  ******************************************************************************
    867  * M4OSA_ERR M4VSS3GPP_intClipReadNextAudioFrame()
    868  * @brief    Read one AU frame in the clip
    869  * @note
    870  * @param   pClipCtxt            (IN) Internal clip context
    871  * @return    M4NO_ERROR:            No error
    872  ******************************************************************************
    873  */
    874 M4OSA_ERR M4VSS3GPP_intClipReadNextAudioFrame(
    875     M4VSS3GPP_ClipContext *pClipCtxt )
    876 {
    877     M4OSA_ERR err;
    878 
    879     /* ------------------------------ */
    880     /* ---------- NO AUDIO ---------- */
    881     /* ------------------------------ */
    882 
    883     if( M4OSA_NULL == pClipCtxt->pAudioStream )
    884     {
    885         /* If there is no audio track, we return silence AUs */
    886         pClipCtxt->pAudioFramePtr =
    887             (M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData;
    888         pClipCtxt->uiAudioFrameSize = pClipCtxt->uiSilenceFrameSize;
    889         pClipCtxt->iAudioFrameCts += pClipCtxt->iSilenceFrameDuration;
    890 
    891         M4OSA_TRACE2_0("b #### blank track");
    892     }
    893 
    894     /* ---------------------------------- */
    895     /* ---------- AMR-NB, EVRC ---------- */
    896     /* ---------------------------------- */
    897 
    898     else if( ( M4VIDEOEDITING_kAMR_NB
    899         == pClipCtxt->pSettings->ClipProperties.AudioStreamType)
    900         || (M4VIDEOEDITING_kEVRC
    901         == pClipCtxt->pSettings->ClipProperties.AudioStreamType) )
    902     {
    903         if( M4OSA_FALSE == pClipCtxt->bAudioFrameAvailable )
    904         {
    905             /**
    906             * No AU available, so we must must read one from the original track reader */
    907             err = pClipCtxt->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu(
    908                 pClipCtxt->pReaderContext,
    909                 (M4_StreamHandler *)pClipCtxt->pAudioStream,
    910                 &pClipCtxt->AudioAU);
    911 
    912             if( M4NO_ERROR == err )
    913             {
    914                 /**
    915                 * Set the current AMR frame position at the beginning of the read AU */
    916                 pClipCtxt->pAudioFramePtr = pClipCtxt->AudioAU.m_dataAddress;
    917 
    918                 /**
    919                 * Set the AMR frame CTS */
    920                 pClipCtxt->iAudioFrameCts =
    921                     (M4OSA_Int32)(pClipCtxt->AudioAU.m_CTS
    922                     * pClipCtxt->scale_audio + 0.5);
    923             }
    924             else if( ( M4WAR_NO_MORE_AU == err) && (M4VIDEOEDITING_kAMR_NB
    925                 == pClipCtxt->pSettings->ClipProperties.AudioStreamType) )
    926             {
    927                 /**
    928                 * If there is less audio than the stream duration indicated,
    929                 * we return silence at the end of the stream. */
    930                 pClipCtxt->pAudioFramePtr =
    931                     (M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData;
    932                 pClipCtxt->uiAudioFrameSize = pClipCtxt->uiSilenceFrameSize;
    933                 pClipCtxt->iAudioFrameCts += pClipCtxt->iSilenceFrameDuration;
    934 
    935                 M4OSA_TRACE2_0("a #### silence AU");
    936 
    937                 /**
    938                 * Return with M4WAR_NO_MORE_AU */
    939                 M4OSA_TRACE3_0(
    940                     "M4VSS3GPP_intClipReadNextAudioFrame()-AMR: \
    941                     returning M4WAR_NO_MORE_AU (silence)");
    942                 return M4WAR_NO_MORE_AU;
    943             }
    944             else /**< fatal error (or no silence in EVRC) */
    945             {
    946                 M4OSA_TRACE3_1(
    947                     "M4VSS3GPP_intClipReadNextAudioFrame()-AMR: m_pFctGetNextAu() returns 0x%x",
    948                     err);
    949                 return err;
    950             }
    951         }
    952         else /* bAudioFrameAvailable */
    953         {
    954             /**
    955             * Go to the next AMR frame in the AU */
    956             pClipCtxt->pAudioFramePtr += pClipCtxt->uiAudioFrameSize;
    957 
    958             /**
    959             * Increment CTS: one AMR frame is 20 ms long */
    960             pClipCtxt->iAudioFrameCts += pClipCtxt->iSilenceFrameDuration;
    961         }
    962 
    963         /**
    964         * Get the size of the pointed AMR frame */
    965         switch( pClipCtxt->pSettings->ClipProperties.AudioStreamType )
    966         {
    967             case M4VIDEOEDITING_kAMR_NB:
    968                 pClipCtxt->uiAudioFrameSize =
    969                     (M4OSA_UInt16)M4VSS3GPP_intGetFrameSize_AMRNB(
    970                     pClipCtxt->pAudioFramePtr);
    971                 break;
    972 
    973             case M4VIDEOEDITING_kEVRC:
    974                 pClipCtxt->uiAudioFrameSize =
    975                     (M4OSA_UInt16)M4VSS3GPP_intGetFrameSize_EVRC(
    976                     pClipCtxt->pAudioFramePtr);
    977                 break;
    978             default:
    979                 break;
    980         }
    981 
    982         if( 0 == pClipCtxt->uiAudioFrameSize )
    983         {
    984             M4OSA_TRACE3_0(
    985                 "M4VSS3GPP_intClipReadNextAudioFrame()-AMR: AU frame size == 0,\
    986                 returning M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU");
    987             return M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU;
    988         }
    989         else if( pClipCtxt->uiAudioFrameSize > pClipCtxt->AudioAU.m_size )
    990         {
    991             M4OSA_TRACE3_0(
    992                 "M4VSS3GPP_intClipReadNextAudioFrame()-AMR: AU frame size greater than AU size!,\
    993                 returning M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU");
    994             return M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU;
    995         }
    996 
    997         /**
    998         * Check if the end of the current AU has been reached or not */
    999         if( ( pClipCtxt->pAudioFramePtr + pClipCtxt->uiAudioFrameSize)
   1000             < (pClipCtxt->AudioAU.m_dataAddress + pClipCtxt->AudioAU.m_size) )
   1001         {
   1002             pClipCtxt->bAudioFrameAvailable = M4OSA_TRUE;
   1003         }
   1004         else
   1005         {
   1006             pClipCtxt->bAudioFrameAvailable =
   1007                 M4OSA_FALSE; /**< will be used for next call */
   1008         }
   1009     }
   1010 
   1011     /* ------------------------- */
   1012     /* ---------- AAC ---------- */
   1013     /* ------------------------- */
   1014 
   1015     else if( ( M4VIDEOEDITING_kAAC
   1016         == pClipCtxt->pSettings->ClipProperties.AudioStreamType)
   1017         || (M4VIDEOEDITING_kAACplus
   1018         == pClipCtxt->pSettings->ClipProperties.AudioStreamType)
   1019         || (M4VIDEOEDITING_keAACplus
   1020         == pClipCtxt->pSettings->ClipProperties.AudioStreamType) )
   1021     {
   1022         err = pClipCtxt->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu(
   1023             pClipCtxt->pReaderContext,
   1024             (M4_StreamHandler *)pClipCtxt->pAudioStream,
   1025             &pClipCtxt->AudioAU);
   1026 
   1027         if( M4NO_ERROR == err )
   1028         {
   1029             pClipCtxt->pAudioFramePtr = pClipCtxt->AudioAU.m_dataAddress;
   1030             pClipCtxt->uiAudioFrameSize =
   1031                 (M4OSA_UInt16)pClipCtxt->AudioAU.m_size;
   1032             pClipCtxt->iAudioFrameCts =
   1033                 (M4OSA_Int32)(pClipCtxt->AudioAU.m_CTS * pClipCtxt->scale_audio
   1034                 + 0.5);
   1035 
   1036             /* Patch because m_CTS is unfortunately rounded in 3gp reader shell */
   1037             /* (cts is not an integer with frequency 24 kHz for example) */
   1038             pClipCtxt->iAudioFrameCts = ( ( pClipCtxt->iAudioFrameCts
   1039                 + pClipCtxt->iSilenceFrameDuration / 2)
   1040                 / pClipCtxt->iSilenceFrameDuration)
   1041                 * pClipCtxt->iSilenceFrameDuration;
   1042         }
   1043         else if( M4WAR_NO_MORE_AU == err )
   1044         {
   1045             /**
   1046             * If there is less audio than the stream duration indicated,
   1047             * we return silence at the end of the stream. */
   1048             pClipCtxt->pAudioFramePtr =
   1049                 (M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData;
   1050             pClipCtxt->uiAudioFrameSize = pClipCtxt->uiSilenceFrameSize;
   1051             pClipCtxt->iAudioFrameCts += pClipCtxt->iSilenceFrameDuration;
   1052 
   1053             M4OSA_TRACE2_0("a #### silence AU");
   1054 
   1055             /**
   1056             * Return with M4WAR_NO_MORE_AU */
   1057             M4OSA_TRACE3_0(
   1058                 "M4VSS3GPP_intClipReadNextAudioFrame()-AAC:\
   1059                 returning M4WAR_NO_MORE_AU (silence)");
   1060             return M4WAR_NO_MORE_AU;
   1061         }
   1062         else /**< fatal error */
   1063         {
   1064             M4OSA_TRACE3_1(
   1065                 "M4VSS3GPP_intClipReadNextAudioFrame()-AAC: m_pFctGetNextAu() returns 0x%x",
   1066                 err);
   1067             return err;
   1068         }
   1069     }
   1070 
   1071     /* --------------------------------- */
   1072     /* ---------- MP3, others ---------- */
   1073     /* --------------------------------- */
   1074 
   1075     else
   1076     {
   1077         err = pClipCtxt->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu(
   1078             pClipCtxt->pReaderContext,
   1079             (M4_StreamHandler *)pClipCtxt->pAudioStream,
   1080             &pClipCtxt->AudioAU);
   1081 
   1082         if( M4NO_ERROR != err )
   1083         {
   1084             M4OSA_TRACE3_1(
   1085                 "M4VSS3GPP_intClipReadNextAudioFrame()-MP3: m_pFctGetNextAu() returns 0x%x",
   1086                 err);
   1087             return err;
   1088         }
   1089 
   1090         pClipCtxt->pAudioFramePtr = pClipCtxt->AudioAU.m_dataAddress;
   1091         pClipCtxt->uiAudioFrameSize = (M4OSA_UInt16)pClipCtxt->AudioAU.m_size;
   1092         pClipCtxt->iAudioFrameCts =
   1093             (M4OSA_Int32)(pClipCtxt->AudioAU.m_CTS * pClipCtxt->scale_audio
   1094             + 0.5);
   1095     }
   1096 
   1097     /**
   1098     * Return with no error */
   1099     M4OSA_TRACE3_0(
   1100         "M4VSS3GPP_intClipReadNextAudioFrame(): returning M4NO_ERROR");
   1101 
   1102     return M4NO_ERROR;
   1103 }
   1104 
   1105 /**
   1106  ******************************************************************************
   1107  * M4OSA_ERR M4VSS3GPP_intClipPrepareAudioDecoder()
   1108  * @brief    Creates and initialize the audio decoder for the clip.
   1109  * @note
   1110  * @param   pClipCtxt        (IN) internal clip context
   1111  * @return    M4NO_ERROR:            No error
   1112  ******************************************************************************
   1113  */
   1114 static M4OSA_ERR M4VSS3GPP_intClipPrepareAudioDecoder(
   1115     M4VSS3GPP_ClipContext *pClipCtxt )
   1116 {
   1117     M4OSA_ERR err = M4NO_ERROR;
   1118     M4_StreamType audiotype;
   1119 #ifdef M4VSS_SUPPORT_OMX_CODECS
   1120 
   1121     M4_AACType iAacType = 0;
   1122 
   1123 #endif
   1124 
   1125     /**
   1126     * Set the proper audio decoder */
   1127 
   1128     audiotype = pClipCtxt->pAudioStream->m_basicProperties.m_streamType;
   1129 
   1130     //EVRC
   1131     if( M4DA_StreamTypeAudioEvrc
   1132         != audiotype ) /* decoder not supported yet, but allow to do null encoding */
   1133 
   1134         err = M4VSS3GPP_setCurrentAudioDecoder(&pClipCtxt->ShellAPI, audiotype);
   1135     M4ERR_CHECK_RETURN(err);
   1136 
   1137     /**
   1138     * Creates the audio decoder */
   1139     if( M4OSA_NULL == pClipCtxt->ShellAPI.m_pAudioDecoder )
   1140     {
   1141         M4OSA_TRACE1_0(
   1142             "M4VSS3GPP_intClipPrepareAudioDecoder(): Fails to initiate the audio decoder.");
   1143         return M4VSS3GPP_ERR_AUDIO_DECODER_INIT_FAILED;
   1144     }
   1145 
   1146     if( M4OSA_NULL == pClipCtxt->pAudioDecCtxt )
   1147     {
   1148 #ifdef M4VSS_SUPPORT_OMX_CODECS
   1149 
   1150         if( M4OSA_TRUE == pClipCtxt->ShellAPI.bAllowFreeingOMXCodecInterface )
   1151         {
   1152             if( M4DA_StreamTypeAudioAac == audiotype ) {
   1153                 err = M4VSS3GPP_intCheckAndGetCodecAacProperties(
   1154                        pClipCtxt);
   1155             } else if (M4DA_StreamTypeAudioPcm != audiotype) {
   1156                 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec(
   1157                 &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream,
   1158                 M4OSA_NULL);
   1159             } else {
   1160                 err = M4NO_ERROR;
   1161             }
   1162             if( M4NO_ERROR != err )
   1163             {
   1164                 M4OSA_TRACE1_1(
   1165                     "M4VSS3GPP_intClipPrepareAudioDecoder: m_pAudioDecoder->m_pFctCreateAudioDec\
   1166                     returns 0x%x", err);
   1167                 return err;
   1168             }
   1169         }
   1170         else
   1171         {
   1172             M4OSA_TRACE3_1(
   1173                 "M4VSS3GPP_intClipPrepareAudioDecoder:\
   1174                 Creating external audio decoder of type 0x%x", audiotype);
   1175             /* External OMX codecs are used*/
   1176             if( M4DA_StreamTypeAudioAac == audiotype )
   1177             {
   1178                 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec(
   1179                     &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream,
   1180                     pClipCtxt->ShellAPI.pCurrentAudioDecoderUserData);
   1181 
   1182                 if( M4NO_ERROR == err )
   1183                 {
   1184                     /* AAC properties*/
   1185                     /*get from Reader; temporary, till Audio decoder shell API
   1186                       available to get the AAC properties*/
   1187                     pClipCtxt->AacProperties.aNumChan =
   1188                         pClipCtxt->pAudioStream->m_nbChannels;
   1189                     pClipCtxt->AacProperties.aSampFreq =
   1190                         pClipCtxt->pAudioStream->m_samplingFrequency;
   1191 
   1192                     err = pClipCtxt->ShellAPI.m_pAudioDecoder->
   1193                         m_pFctGetOptionAudioDec(pClipCtxt->pAudioDecCtxt,
   1194                         M4AD_kOptionID_StreamType,
   1195                         (M4OSA_DataOption) &iAacType);
   1196 
   1197                     if( M4NO_ERROR != err )
   1198                     {
   1199                         M4OSA_TRACE1_1(
   1200                             "M4VSS3GPP_intClipPrepareAudioDecoder:\
   1201                             m_pAudioDecoder->m_pFctGetOptionAudioDec returns err 0x%x", err);
   1202                         iAacType = M4_kAAC; //set to default
   1203                         err = M4NO_ERROR;
   1204                     }
   1205                     else {
   1206                         M4OSA_TRACE3_1(
   1207                         "M4VSS3GPP_intClipPrepareAudioDecoder: \
   1208                         m_pAudioDecoder->m_pFctGetOptionAudioDec returns streamType %d",
   1209                         iAacType);
   1210                        }
   1211                     switch( iAacType )
   1212                     {
   1213                         case M4_kAAC:
   1214                             pClipCtxt->AacProperties.aSBRPresent = 0;
   1215                             pClipCtxt->AacProperties.aPSPresent = 0;
   1216                             break;
   1217 
   1218                         case M4_kAACplus:
   1219                             pClipCtxt->AacProperties.aSBRPresent = 1;
   1220                             pClipCtxt->AacProperties.aPSPresent = 0;
   1221                             pClipCtxt->AacProperties.aExtensionSampFreq =
   1222                                 pClipCtxt->pAudioStream->m_samplingFrequency;
   1223                             break;
   1224 
   1225                         case M4_keAACplus:
   1226                             pClipCtxt->AacProperties.aSBRPresent = 1;
   1227                             pClipCtxt->AacProperties.aPSPresent = 1;
   1228                             pClipCtxt->AacProperties.aExtensionSampFreq =
   1229                                 pClipCtxt->pAudioStream->m_samplingFrequency;
   1230                             break;
   1231                         default:
   1232                             break;
   1233                     }
   1234                     M4OSA_TRACE3_2(
   1235                         "M4VSS3GPP_intClipPrepareAudioDecoder: AAC NBChans=%d, SamplFreq=%d",
   1236                         pClipCtxt->AacProperties.aNumChan,
   1237                         pClipCtxt->AacProperties.aSampFreq);
   1238                 }
   1239             }
   1240             else
   1241                 err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec(
   1242                 &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream,
   1243                 pClipCtxt->ShellAPI.pCurrentAudioDecoderUserData);
   1244 
   1245             if( M4NO_ERROR != err )
   1246             {
   1247                 M4OSA_TRACE1_1(
   1248                     "M4VSS3GPP_intClipPrepareAudioDecoder:\
   1249                     m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x",
   1250                     err);
   1251                 return err;
   1252             }
   1253         }
   1254 
   1255 #else
   1256         /* Trick, I use pUserData to retrieve aac properties,
   1257            waiting for some better implementation... */
   1258 
   1259         if( M4DA_StreamTypeAudioAac == audiotype )
   1260             err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec(
   1261             &pClipCtxt->pAudioDecCtxt,
   1262             pClipCtxt->pAudioStream, &(pClipCtxt->AacProperties));
   1263         else
   1264             err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec(
   1265             &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream,
   1266             M4OSA_NULL /* to be changed with HW interfaces */);
   1267 
   1268         if( M4NO_ERROR != err )
   1269         {
   1270             M4OSA_TRACE1_1(
   1271                 "M4VSS3GPP_intClipPrepareAudioDecoder:\
   1272                 m_pAudioDecoder->m_pFctCreateAudioDec returns 0x%x",
   1273                 err);
   1274             return err;
   1275         }
   1276 
   1277 #endif
   1278 
   1279     }
   1280 
   1281     if( M4DA_StreamTypeAudioAmrNarrowBand == audiotype ) {
   1282         /* AMR DECODER CONFIGURATION */
   1283 
   1284         /* nothing specific to do */
   1285     }
   1286     else if( M4DA_StreamTypeAudioEvrc == audiotype ) {
   1287         /* EVRC DECODER CONFIGURATION */
   1288 
   1289         /* nothing specific to do */
   1290     }
   1291     else if( M4DA_StreamTypeAudioMp3 == audiotype ) {
   1292         /* MP3 DECODER CONFIGURATION */
   1293 
   1294         /* nothing specific to do */
   1295     }
   1296     else if( M4DA_StreamTypeAudioAac == audiotype )
   1297     {
   1298         /* AAC DECODER CONFIGURATION */
   1299 
   1300         /* Decode high quality aac but disable PS and SBR */
   1301         /* Because we have to mix different kind of AAC so we must take the lowest capability */
   1302         /* In MCS it was not needed because there is only one stream */
   1303         M4_AacDecoderConfig AacDecParam;
   1304 
   1305         AacDecParam.m_AACDecoderProfile = AAC_kAAC;
   1306         AacDecParam.m_DownSamplingMode = AAC_kDS_OFF;
   1307 
   1308         if( M4ENCODER_kMono == pClipCtxt->pAudioStream->m_nbChannels )
   1309         {
   1310             AacDecParam.m_OutputMode = AAC_kMono;
   1311         }
   1312         else
   1313         {
   1314             AacDecParam.m_OutputMode = AAC_kStereo;
   1315         }
   1316 
   1317         err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec(
   1318             pClipCtxt->pAudioDecCtxt,
   1319             M4AD_kOptionID_UserParam, (M4OSA_DataOption) &AacDecParam);
   1320     }
   1321 
   1322     if( M4OSA_NULL != pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec ) {
   1323         pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec(
   1324          pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_3gpReaderInterface,
   1325          (M4OSA_DataOption) pClipCtxt->ShellAPI.m_pReaderDataIt);
   1326 
   1327         pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec(
   1328          pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_AudioAU,
   1329          (M4OSA_DataOption) &pClipCtxt->AudioAU);
   1330     }
   1331 
   1332     if( M4OSA_NULL != pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec )
   1333     {
   1334         /* Not implemented in all decoders */
   1335         err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec(
   1336             pClipCtxt->pAudioDecCtxt);
   1337 
   1338         if( M4NO_ERROR != err )
   1339         {
   1340             M4OSA_TRACE1_1(
   1341                 "M4VSS3GPP_intClipPrepareAudioDecoder:\
   1342                 m_pAudioDecoder->m_pFctStartAudioDec returns 0x%x",
   1343                 err);
   1344             return err;
   1345         }
   1346     }
   1347 
   1348     /**
   1349     * Allocate output buffer for the audio decoder */
   1350     pClipCtxt->AudioDecBufferOut.m_bufferSize =
   1351         pClipCtxt->pAudioStream->m_byteFrameLength
   1352         * pClipCtxt->pAudioStream->m_byteSampleSize
   1353         * pClipCtxt->pAudioStream->m_nbChannels;
   1354     pClipCtxt->AudioDecBufferOut.m_dataAddress =
   1355         (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(pClipCtxt->AudioDecBufferOut.m_bufferSize
   1356         * sizeof(M4OSA_Int16),
   1357         M4VSS3GPP, (M4OSA_Char *)"AudioDecBufferOut.m_bufferSize");
   1358 
   1359     if( M4OSA_NULL == pClipCtxt->AudioDecBufferOut.m_dataAddress )
   1360     {
   1361         M4OSA_TRACE1_0(
   1362             "M4VSS3GPP_intClipPrepareAudioDecoder():\
   1363             unable to allocate AudioDecBufferOut.m_dataAddress, returning M4ERR_ALLOC");
   1364         return M4ERR_ALLOC;
   1365     }
   1366 
   1367     return M4NO_ERROR;
   1368 }
   1369 
   1370 /**
   1371  ******************************************************************************
   1372  * M4OSA_ERR M4VSS3GPP_intClipDecodeCurrentAudioFrame()
   1373  * @brief    Decode the current AUDIO frame.
   1374  * @note
   1375  * @param   pClipCtxt        (IN) internal clip context
   1376  * @return    M4NO_ERROR:            No error
   1377  ******************************************************************************
   1378  */
   1379 M4OSA_ERR M4VSS3GPP_intClipDecodeCurrentAudioFrame(
   1380     M4VSS3GPP_ClipContext *pClipCtxt )
   1381 {
   1382     M4OSA_ERR err;
   1383 
   1384     /**
   1385     * Silence mode */
   1386     if( pClipCtxt->pSilenceFrameData
   1387         == (M4OSA_UInt8 *)pClipCtxt->pAudioFramePtr )
   1388     {
   1389         if( pClipCtxt->AudioDecBufferOut.m_dataAddress == M4OSA_NULL )
   1390         {
   1391             /**
   1392             * Allocate output buffer for the audio decoder */
   1393             pClipCtxt->AudioDecBufferOut.m_bufferSize =
   1394                 pClipCtxt->uiSilencePcmSize;
   1395             pClipCtxt->AudioDecBufferOut.m_dataAddress =
   1396                 (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(
   1397                 pClipCtxt->AudioDecBufferOut.m_bufferSize
   1398                 * sizeof(M4OSA_Int16),
   1399                 M4VSS3GPP,(M4OSA_Char *) "AudioDecBufferOut.m_bufferSize");
   1400 
   1401             if( M4OSA_NULL == pClipCtxt->AudioDecBufferOut.m_dataAddress )
   1402             {
   1403                 M4OSA_TRACE1_0(
   1404                     "M4VSS3GPP_intClipDecodeCurrentAudioFrame():\
   1405                     unable to allocate AudioDecBufferOut.m_dataAddress, returning M4ERR_ALLOC");
   1406                 return M4ERR_ALLOC;
   1407             }
   1408         }
   1409 
   1410         /* Fill it with 0 (= pcm silence) */
   1411         memset(pClipCtxt->AudioDecBufferOut.m_dataAddress,0,
   1412              pClipCtxt->AudioDecBufferOut.m_bufferSize * sizeof(M4OSA_Int16));
   1413     }
   1414     else if (pClipCtxt->pSettings->FileType == M4VIDEOEDITING_kFileType_PCM)
   1415     {
   1416         pClipCtxt->AudioDecBufferIn.m_dataAddress = (M4OSA_MemAddr8) pClipCtxt->pAudioFramePtr;
   1417         pClipCtxt->AudioDecBufferIn.m_bufferSize  = pClipCtxt->uiAudioFrameSize;
   1418 
   1419         memcpy((void *)pClipCtxt->AudioDecBufferOut.m_dataAddress,
   1420             (void *)pClipCtxt->AudioDecBufferIn.m_dataAddress, pClipCtxt->AudioDecBufferIn.m_bufferSize);
   1421         pClipCtxt->AudioDecBufferOut.m_bufferSize = pClipCtxt->AudioDecBufferIn.m_bufferSize;
   1422         /**
   1423         * Return with no error */
   1424 
   1425         M4OSA_TRACE3_0("M4VSS3GPP_intClipDecodeCurrentAudioFrame(): returning M4NO_ERROR");
   1426         return M4NO_ERROR;
   1427     }
   1428     /**
   1429     * Standard decoding mode */
   1430     else
   1431     {
   1432         /**
   1433         * Decode current AMR frame */
   1434         if ( pClipCtxt->pAudioFramePtr != M4OSA_NULL ) {
   1435             pClipCtxt->AudioDecBufferIn.m_dataAddress =
   1436              (M4OSA_MemAddr8)pClipCtxt->pAudioFramePtr;
   1437             pClipCtxt->AudioDecBufferIn.m_bufferSize =
   1438              pClipCtxt->uiAudioFrameSize;
   1439             pClipCtxt->AudioDecBufferIn.m_timeStampUs =
   1440              (int64_t) (pClipCtxt->iAudioFrameCts * 1000LL);
   1441 
   1442             err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec(
   1443              pClipCtxt->pAudioDecCtxt,
   1444              &pClipCtxt->AudioDecBufferIn, &pClipCtxt->AudioDecBufferOut,
   1445              M4OSA_FALSE);
   1446         } else {
   1447             // Pass Null input buffer
   1448             // Reader invoked from Audio decoder source
   1449             err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec(
   1450              pClipCtxt->pAudioDecCtxt,
   1451              M4OSA_NULL, &pClipCtxt->AudioDecBufferOut,
   1452              M4OSA_FALSE);
   1453         }
   1454 
   1455         if( M4NO_ERROR != err )
   1456         {
   1457             M4OSA_TRACE1_1(
   1458                 "M4VSS3GPP_intClipDecodeCurrentAudioFrame():\
   1459                 m_pAudioDecoder->m_pFctStepAudio returns 0x%x",
   1460                 err);
   1461             return err;
   1462         }
   1463     }
   1464 
   1465     /**
   1466     * Return with no error */
   1467     M4OSA_TRACE3_0(
   1468         "M4VSS3GPP_intClipDecodeCurrentAudioFrame(): returning M4NO_ERROR");
   1469     return M4NO_ERROR;
   1470 }
   1471 
   1472 /**
   1473  ******************************************************************************
   1474  * M4OSA_ERR M4VSS3GPP_intClipJumpAudioAt()
   1475  * @brief    Jump in the audio track of the clip.
   1476  * @note
   1477  * @param   pClipCtxt            (IN) internal clip context
   1478  * @param   pJumpCts            (IN/OUT) in:target CTS, out: reached CTS
   1479  * @return    M4NO_ERROR:            No error
   1480  ******************************************************************************
   1481  */
   1482 M4OSA_ERR M4VSS3GPP_intClipJumpAudioAt( M4VSS3GPP_ClipContext *pClipCtxt,
   1483                                        M4OSA_Int32 *pJumpCts )
   1484 {
   1485     M4OSA_ERR err;
   1486     M4OSA_Int32 iTargetCts;
   1487     M4OSA_Int32 iJumpCtsMs;
   1488 
   1489     /**
   1490     *    Check input parameters */
   1491     M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER,
   1492         "M4VSS3GPP_intClipJumpAudioAt: pClipCtxt is M4OSA_NULL");
   1493     M4OSA_DEBUG_IF2((M4OSA_NULL == pJumpCts), M4ERR_PARAMETER,
   1494         "M4VSS3GPP_intClipJumpAudioAt: pJumpCts is M4OSA_NULL");
   1495 
   1496     iTargetCts = *pJumpCts;
   1497 
   1498     /**
   1499     * If there is no audio stream, we simulate a jump at the target jump CTS */
   1500     if( M4OSA_NULL == pClipCtxt->pAudioStream )
   1501     {
   1502         /**
   1503         * the target CTS will be reached at next ReadFrame call (thus the -20) */
   1504         *pJumpCts = iTargetCts - pClipCtxt->iSilenceFrameDuration;
   1505 
   1506         /* Patch because m_CTS is unfortunately rounded in 3gp reader shell */
   1507         /* (cts is not an integer with frequency 24 kHz for example) */
   1508         *pJumpCts = ( ( *pJumpCts + pClipCtxt->iSilenceFrameDuration / 2)
   1509             / pClipCtxt->iSilenceFrameDuration)
   1510             * pClipCtxt->iSilenceFrameDuration;
   1511         pClipCtxt->iAudioFrameCts =
   1512             *
   1513             pJumpCts; /* simulate a read at jump position for later silence AUs */
   1514     }
   1515     else
   1516     {
   1517         M4OSA_Int32 current_time = 0;
   1518         M4OSA_Int32 loop_counter = 0;
   1519 
   1520         if( (M4DA_StreamTypeAudioMp3
   1521             == pClipCtxt->pAudioStream->m_basicProperties.m_streamType) )
   1522         {
   1523             while( ( loop_counter < M4VSS3GPP_MP3_JUMPED_AU_NUMBER_MAX)
   1524                 && (current_time < iTargetCts) )
   1525             {
   1526                 err = pClipCtxt->ShellAPI.m_pReaderDataIt->m_pFctGetNextAu(
   1527                     pClipCtxt->pReaderContext,
   1528                     (M4_StreamHandler *)pClipCtxt->pAudioStream,
   1529                     &pClipCtxt->AudioAU);
   1530 
   1531                 if( M4NO_ERROR != err )
   1532                 {
   1533                     M4OSA_TRACE3_1(
   1534                         "M4VSS3GPP_intClipJumpAudioAt: m_pFctGetNextAu() returns 0x%x",
   1535                         err);
   1536                     return err;
   1537                 }
   1538 
   1539                 current_time = (M4OSA_Int32)pClipCtxt->AudioAU.m_CTS;
   1540                 loop_counter++;
   1541             }
   1542 
   1543             /**
   1544             * The current AU is stored */
   1545             pClipCtxt->pAudioFramePtr = pClipCtxt->AudioAU.m_dataAddress;
   1546             pClipCtxt->uiAudioFrameSize =
   1547                 (M4OSA_UInt16)pClipCtxt->AudioAU.m_size;
   1548             pClipCtxt->iAudioFrameCts =
   1549                 (M4OSA_Int32)(pClipCtxt->AudioAU.m_CTS * pClipCtxt->scale_audio
   1550                 + 0.5);
   1551 
   1552             *pJumpCts = pClipCtxt->iAudioFrameCts;
   1553         }
   1554         else
   1555         {
   1556             /**
   1557             * Jump in the audio stream */
   1558             iJumpCtsMs =
   1559                 (M4OSA_Int32)(*pJumpCts / pClipCtxt->scale_audio + 0.5);
   1560 
   1561             err = pClipCtxt->ShellAPI.m_pReader->m_pFctJump(
   1562                 pClipCtxt->pReaderContext,
   1563                 (M4_StreamHandler *)pClipCtxt->pAudioStream,
   1564                 &iJumpCtsMs);
   1565 
   1566             if( M4NO_ERROR != err )
   1567             {
   1568                 M4OSA_TRACE1_1(
   1569                     "M4VSS3GPP_intClipJumpAudioAt(): m_pFctJump() returns 0x%x",
   1570                     err);
   1571                 return err;
   1572             }
   1573 
   1574             *pJumpCts =
   1575                 (M4OSA_Int32)(iJumpCtsMs * pClipCtxt->scale_audio + 0.5);
   1576 
   1577             /* Patch because m_CTS is unfortunately rounded in 3gp reader shell */
   1578             /* (cts is not an integer with frequency 24 kHz for example) */
   1579             *pJumpCts = ( ( *pJumpCts + pClipCtxt->iSilenceFrameDuration / 2)
   1580                 / pClipCtxt->iSilenceFrameDuration)
   1581                 * pClipCtxt->iSilenceFrameDuration;
   1582             pClipCtxt->iAudioFrameCts = 0; /* No frame read yet */
   1583 
   1584             /**
   1585             * To detect some may-be bugs, I prefer to reset all these after a jump */
   1586             pClipCtxt->bAudioFrameAvailable = M4OSA_FALSE;
   1587             pClipCtxt->pAudioFramePtr = M4OSA_NULL;
   1588 
   1589             /**
   1590             * In AMR, we have to manage multi-framed AUs,
   1591             but also in AAC the jump can be 1 AU too much backward */
   1592             if( *pJumpCts < iTargetCts )
   1593             {
   1594                 /**
   1595                 * Jump doesn't read any AU, we must read at least one */
   1596                 err = M4VSS3GPP_intClipReadNextAudioFrame(pClipCtxt);
   1597 
   1598                 if( M4OSA_ERR_IS_ERROR(err) )
   1599                 {
   1600                     M4OSA_TRACE1_1(
   1601                         "M4VSS3GPP_intClipJumpAudioAt():\
   1602                         M4VSS3GPP_intClipReadNextAudioFrame(a) returns 0x%x",
   1603                         err);
   1604                     return err;
   1605                 }
   1606 
   1607                 /**
   1608                 * Read AU frames as long as we reach the AU before the target CTS
   1609                 * (so the target will be reached when the user call ReadNextAudioFrame). */
   1610                 while( pClipCtxt->iAudioFrameCts
   1611                     < (iTargetCts - pClipCtxt->iSilenceFrameDuration) )
   1612                 {
   1613                     err = M4VSS3GPP_intClipReadNextAudioFrame(pClipCtxt);
   1614 
   1615                     if( M4OSA_ERR_IS_ERROR(err) )
   1616                     {
   1617                         M4OSA_TRACE1_1(
   1618                             "M4VSS3GPP_intClipJumpAudioAt():\
   1619                             M4VSS3GPP_intClipReadNextAudioFrame(b) returns 0x%x",
   1620                             err);
   1621                         return err;
   1622                     }
   1623                 }
   1624 
   1625                 /**
   1626                 * Return the CTS that will be reached at next ReadFrame */
   1627                 *pJumpCts = pClipCtxt->iAudioFrameCts
   1628                     + pClipCtxt->iSilenceFrameDuration;
   1629             }
   1630         }
   1631     }
   1632 
   1633     /**
   1634     * Return with no error */
   1635     M4OSA_TRACE3_0("M4VSS3GPP_intClipJumpAudioAt(): returning M4NO_ERROR");
   1636     return M4NO_ERROR;
   1637 }
   1638 
   1639 /**
   1640  ******************************************************************************
   1641  * M4OSA_ERR M4VSS3GPP_intClipClose()
   1642  * @brief    Close a clip. Destroy the context.
   1643  * @note
   1644  * @param   pClipCtxt            (IN) Internal clip context
   1645  * @return    M4NO_ERROR:            No error
   1646  ******************************************************************************
   1647  */
   1648 M4OSA_ERR M4VSS3GPP_intClipClose( M4VSS3GPP_ClipContext *pClipCtxt )
   1649 {
   1650     M4OSA_ERR err;
   1651 
   1652     /**
   1653     *    Check input parameters */
   1654     M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER,
   1655         "M4VSS3GPP_intClipClose: pClipCtxt is M4OSA_NULL");
   1656 
   1657     /**
   1658     * Free the video decoder context */
   1659     if( M4OSA_NULL != pClipCtxt->pViDecCtxt )
   1660     {
   1661         pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctDestroy(
   1662             pClipCtxt->pViDecCtxt);
   1663         pClipCtxt->pViDecCtxt = M4OSA_NULL;
   1664     }
   1665 
   1666     /**
   1667     * Free the audio decoder context  */
   1668     if( M4OSA_NULL != pClipCtxt->pAudioDecCtxt )
   1669     {
   1670         err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctDestroyAudioDec(
   1671             pClipCtxt->pAudioDecCtxt);
   1672 
   1673         if( M4NO_ERROR != err )
   1674         {
   1675             M4OSA_TRACE1_1(
   1676                 "M4VSS3GPP_intClipClose: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x",
   1677                 err);
   1678             /**< don't return, we still have stuff to free */
   1679         }
   1680 
   1681         pClipCtxt->pAudioDecCtxt = M4OSA_NULL;
   1682     }
   1683 
   1684     /**
   1685     * Free the decoded audio buffer */
   1686     if( M4OSA_NULL != pClipCtxt->AudioDecBufferOut.m_dataAddress )
   1687     {
   1688         free(pClipCtxt->AudioDecBufferOut.m_dataAddress);
   1689         pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL;
   1690     }
   1691 
   1692     /**
   1693     * Audio AU is allocated by reader.
   1694     * If no audio track, audio AU is set at 'silent' (SID) by VSS.
   1695     * As a consequence, if audio AU is set to 'silent' (static)
   1696     it can't be free unless it is set to NULL */
   1697     if( ( (M4OSA_MemAddr8)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048
   1698         == pClipCtxt->AudioAU.m_dataAddress)
   1699         || ((M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData
   1700         == pClipCtxt->AudioAU.m_dataAddress) )
   1701     {
   1702         pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL;
   1703     }
   1704 
   1705     if( M4OSA_NULL != pClipCtxt->pReaderContext )
   1706     {
   1707         /**
   1708         * Close the 3GPP or MP3 reader */
   1709         err = pClipCtxt->ShellAPI.m_pReader->m_pFctClose(
   1710             pClipCtxt->pReaderContext);
   1711 
   1712         if( M4NO_ERROR != err )
   1713         {
   1714             M4OSA_TRACE1_1(
   1715                 "M4VSS3GPP_intClipClose(): m_pReader->m_pFctClose returns 0x%x",
   1716                 err);
   1717         }
   1718 
   1719         /**
   1720         * Destroy the 3GPP or MP3 reader context */
   1721         err = pClipCtxt->ShellAPI.m_pReader->m_pFctDestroy(
   1722             pClipCtxt->pReaderContext);
   1723 
   1724         if( M4NO_ERROR != err )
   1725         {
   1726             M4OSA_TRACE1_1(
   1727                 "M4VSS3GPP_intClipClose(): m_pReader->m_pFctDestroy returns 0x%x",
   1728                 err);
   1729         }
   1730 
   1731         pClipCtxt->pReaderContext = M4OSA_NULL;
   1732     }
   1733 
   1734     /**
   1735     * Return with no error */
   1736     M4OSA_TRACE3_1("M4VSS3GPP_intClipClose(Ctxt=0x%x): returning M4NO_ERROR",
   1737         pClipCtxt);
   1738     return M4NO_ERROR;
   1739 }
   1740 
   1741 M4OSA_ERR M4VSS3GPP_intClipCleanUp( M4VSS3GPP_ClipContext *pClipCtxt )
   1742 {
   1743     M4OSA_ERR err = M4NO_ERROR, err2;
   1744 
   1745     /**
   1746     *    Check input parameters */
   1747     M4OSA_DEBUG_IF2((M4OSA_NULL == pClipCtxt), M4ERR_PARAMETER,
   1748         "M4VSS3GPP_intClipCleanUp: pClipCtxt is M4OSA_NULL");
   1749 
   1750     /**
   1751     * Free the video decoder context */
   1752     if( M4OSA_NULL != pClipCtxt->pViDecCtxt )
   1753     {
   1754         pClipCtxt->ShellAPI.m_pVideoDecoder->m_pFctDestroy(
   1755             pClipCtxt->pViDecCtxt);
   1756         pClipCtxt->pViDecCtxt = M4OSA_NULL;
   1757     }
   1758 
   1759     /**
   1760     * Free the audio decoder context  */
   1761     if( M4OSA_NULL != pClipCtxt->pAudioDecCtxt )
   1762     {
   1763         err2 = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctDestroyAudioDec(
   1764             pClipCtxt->pAudioDecCtxt);
   1765 
   1766         if( M4NO_ERROR != err2 )
   1767         {
   1768             M4OSA_TRACE1_1(
   1769                 "M4VSS3GPP_intClipCleanUp: m_pAudioDecoder->m_pFctDestroyAudioDec returns 0x%x",
   1770                 err);
   1771             /**< don't return, we still have stuff to free */
   1772             if( M4NO_ERROR != err )
   1773                 err = err2;
   1774         }
   1775 
   1776         pClipCtxt->pAudioDecCtxt = M4OSA_NULL;
   1777     }
   1778 
   1779     /**
   1780     * Free the decoded audio buffer */
   1781     if( M4OSA_NULL != pClipCtxt->AudioDecBufferOut.m_dataAddress )
   1782     {
   1783         free(pClipCtxt->AudioDecBufferOut.m_dataAddress);
   1784         pClipCtxt->AudioDecBufferOut.m_dataAddress = M4OSA_NULL;
   1785     }
   1786 
   1787     /**
   1788     * Audio AU is allocated by reader.
   1789     * If no audio track, audio AU is set at 'silent' (SID) by VSS.
   1790     * As a consequence, if audio AU is set to 'silent' (static)
   1791     it can't be free unless it is set to NULL */
   1792     if( ( (M4OSA_MemAddr8)M4VSS3GPP_AMR_AU_SILENCE_FRAME_048
   1793         == pClipCtxt->AudioAU.m_dataAddress)
   1794         || ((M4OSA_MemAddr8)pClipCtxt->pSilenceFrameData
   1795         == pClipCtxt->AudioAU.m_dataAddress) )
   1796     {
   1797         pClipCtxt->AudioAU.m_dataAddress = M4OSA_NULL;
   1798     }
   1799 
   1800     if( M4OSA_NULL != pClipCtxt->pReaderContext )
   1801     {
   1802         /**
   1803         * Close the 3GPP or MP3 reader */
   1804         err2 = pClipCtxt->ShellAPI.m_pReader->m_pFctClose(
   1805             pClipCtxt->pReaderContext);
   1806 
   1807         if( M4NO_ERROR != err2 )
   1808         {
   1809             M4OSA_TRACE1_1(
   1810                 "M4VSS3GPP_intClipCleanUp(): m_pReader->m_pFctClose returns 0x%x",
   1811                 err);
   1812 
   1813             if( M4NO_ERROR != err )
   1814                 err = err2;
   1815         }
   1816 
   1817         /**
   1818         * Destroy the 3GPP or MP3 reader context */
   1819         err2 = pClipCtxt->ShellAPI.m_pReader->m_pFctDestroy(
   1820             pClipCtxt->pReaderContext);
   1821 
   1822         if( M4NO_ERROR != err2 )
   1823         {
   1824             M4OSA_TRACE1_1(
   1825                 "M4VSS3GPP_intClipCleanUp(): m_pReader->m_pFctDestroy returns 0x%x",
   1826                 err);
   1827 
   1828             if( M4NO_ERROR != err )
   1829                 err = err2;
   1830         }
   1831 
   1832         pClipCtxt->pReaderContext = M4OSA_NULL;
   1833     }
   1834 
   1835     if(pClipCtxt->pPlaneYuv != M4OSA_NULL) {
   1836         if(pClipCtxt->pPlaneYuv[0].pac_data != M4OSA_NULL) {
   1837             free(pClipCtxt->pPlaneYuv[0].pac_data);
   1838             pClipCtxt->pPlaneYuv[0].pac_data = M4OSA_NULL;
   1839         }
   1840         free(pClipCtxt->pPlaneYuv);
   1841         pClipCtxt->pPlaneYuv = M4OSA_NULL;
   1842     }
   1843 
   1844     if(pClipCtxt->pPlaneYuvWithEffect != M4OSA_NULL) {
   1845         if(pClipCtxt->pPlaneYuvWithEffect[0].pac_data != M4OSA_NULL) {
   1846             free(pClipCtxt->pPlaneYuvWithEffect[0].pac_data);
   1847             pClipCtxt->pPlaneYuvWithEffect[0].pac_data = M4OSA_NULL;
   1848         }
   1849         free(pClipCtxt->pPlaneYuvWithEffect);
   1850         pClipCtxt->pPlaneYuvWithEffect = M4OSA_NULL;
   1851     }
   1852     /**
   1853     * Free the shells interfaces */
   1854     M4VSS3GPP_unRegisterAllWriters(&pClipCtxt->ShellAPI);
   1855     M4VSS3GPP_unRegisterAllEncoders(&pClipCtxt->ShellAPI);
   1856     M4VSS3GPP_unRegisterAllReaders(&pClipCtxt->ShellAPI);
   1857     M4VSS3GPP_unRegisterAllDecoders(&pClipCtxt->ShellAPI);
   1858 
   1859     M4OSA_TRACE3_1("M4VSS3GPP_intClipCleanUp: pClipCtxt=0x%x", pClipCtxt);
   1860     /**
   1861     * Free the clip context */
   1862     free(pClipCtxt);
   1863 
   1864     return err;
   1865 }
   1866 
   1867 /**
   1868  ******************************************************************************
   1869  * M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_AMRNB()
   1870  * @brief   Return the length, in bytes, of the AMR Narrow-Band frame contained in the given buffer
   1871  * @note
   1872  * @param   pAudioFrame   (IN) AMRNB frame
   1873  * @return  M4NO_ERROR: No error
   1874  ******************************************************************************
   1875  */
   1876 
   1877 M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_AMRNB( M4OSA_MemAddr8 pAudioFrame )
   1878 {
   1879     M4OSA_UInt32 frameSize = 0;
   1880     M4OSA_UInt32 frameType = ( ( *pAudioFrame) &(0xF << 3)) >> 3;
   1881 
   1882     switch( frameType )
   1883     {
   1884         case 0:
   1885             frameSize = 95;
   1886             break; /*  4750 bps */
   1887 
   1888         case 1:
   1889             frameSize = 103;
   1890             break; /*  5150 bps */
   1891 
   1892         case 2:
   1893             frameSize = 118;
   1894             break; /*  5900 bps */
   1895 
   1896         case 3:
   1897             frameSize = 134;
   1898             break; /*  6700 bps */
   1899 
   1900         case 4:
   1901             frameSize = 148;
   1902             break; /*  7400 bps */
   1903 
   1904         case 5:
   1905             frameSize = 159;
   1906             break; /*  7950 bps */
   1907 
   1908         case 6:
   1909             frameSize = 204;
   1910             break; /* 10200 bps */
   1911 
   1912         case 7:
   1913             frameSize = 244;
   1914             break; /* 12000 bps */
   1915 
   1916         case 8:
   1917             frameSize = 39;
   1918             break; /* SID (Silence) */
   1919 
   1920         case 15:
   1921             frameSize = 0;
   1922             break; /* No data */
   1923 
   1924         default:
   1925             M4OSA_TRACE3_0(
   1926                 "M4VSS3GPP_intGetFrameSize_AMRNB(): Corrupted AMR frame! returning 0.");
   1927             return 0;
   1928     }
   1929 
   1930     return (1 + (( frameSize + 7) / 8));
   1931 }
   1932 
   1933 /**
   1934  ******************************************************************************
   1935  * M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_EVRC()
   1936  * @brief   Return the length, in bytes, of the EVRC frame contained in the given buffer
   1937  * @note
   1938  *     0 1 2 3
   1939  *    +-+-+-+-+
   1940  *    |fr type|              RFC 3558
   1941  *    +-+-+-+-+
   1942  *
   1943  * Frame Type: 4 bits
   1944  *    The frame type indicates the type of the corresponding codec data
   1945  *    frame in the RTP packet.
   1946  *
   1947  * For EVRC and SMV codecs, the frame type values and size of the
   1948  * associated codec data frame are described in the table below:
   1949  *
   1950  * Value   Rate      Total codec data frame size (in octets)
   1951  * ---------------------------------------------------------
   1952  *   0     Blank      0    (0 bit)
   1953  *   1     1/8        2    (16 bits)
   1954  *   2     1/4        5    (40 bits; not valid for EVRC)
   1955  *   3     1/2       10    (80 bits)
   1956  *   4     1         22    (171 bits; 5 padded at end with zeros)
   1957  *   5     Erasure    0    (SHOULD NOT be transmitted by sender)
   1958  *
   1959  * @param   pCpAudioFrame   (IN) EVRC frame
   1960  * @return  M4NO_ERROR: No error
   1961  ******************************************************************************
   1962  */
   1963 M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_EVRC( M4OSA_MemAddr8 pAudioFrame )
   1964 {
   1965     M4OSA_UInt32 frameSize = 0;
   1966     M4OSA_UInt32 frameType = ( *pAudioFrame) &0x0F;
   1967 
   1968     switch( frameType )
   1969     {
   1970         case 0:
   1971             frameSize = 0;
   1972             break; /*  blank */
   1973 
   1974         case 1:
   1975             frameSize = 16;
   1976             break; /*  1/8 */
   1977 
   1978         case 2:
   1979             frameSize = 40;
   1980             break; /*  1/4 */
   1981 
   1982         case 3:
   1983             frameSize = 80;
   1984             break; /*  1/2 */
   1985 
   1986         case 4:
   1987             frameSize = 171;
   1988             break; /*  1 */
   1989 
   1990         case 5:
   1991             frameSize = 0;
   1992             break; /*  erasure */
   1993 
   1994         default:
   1995             M4OSA_TRACE3_0(
   1996                 "M4VSS3GPP_intGetFrameSize_EVRC(): Corrupted EVRC frame! returning 0.");
   1997             return 0;
   1998     }
   1999 
   2000     return (1 + (( frameSize + 7) / 8));
   2001 }
   2002 
   2003 M4OSA_ERR M4VSS3GPP_intCheckAndGetCodecAacProperties(
   2004                                  M4VSS3GPP_ClipContext *pClipCtxt) {
   2005 
   2006     M4OSA_ERR err = M4NO_ERROR;
   2007     M4AD_Buffer outputBuffer;
   2008     uint32_t optionValue =0;
   2009 
   2010     // Decode first audio frame from clip to get properties from codec
   2011 
   2012     err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec(
   2013                     &pClipCtxt->pAudioDecCtxt,
   2014                     pClipCtxt->pAudioStream, &(pClipCtxt->AacProperties));
   2015 
   2016     pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec(
   2017      pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_3gpReaderInterface,
   2018      (M4OSA_DataOption) pClipCtxt->ShellAPI.m_pReaderDataIt);
   2019 
   2020     pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec(
   2021      pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_AudioAU,
   2022      (M4OSA_DataOption) &pClipCtxt->AudioAU);
   2023 
   2024     if( pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) {
   2025 
   2026         err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec(
   2027          pClipCtxt->pAudioDecCtxt);
   2028         if( M4NO_ERROR != err ) {
   2029 
   2030             M4OSA_TRACE1_1(
   2031                 "M4VSS3GPP_intCheckAndGetCodecAacProperties: \
   2032                  m_pFctStartAudioDec returns 0x%x", err);
   2033             return err;
   2034         }
   2035     }
   2036 
   2037     /**
   2038     * Allocate output buffer for the audio decoder */
   2039     outputBuffer.m_bufferSize =
   2040         pClipCtxt->pAudioStream->m_byteFrameLength
   2041         * pClipCtxt->pAudioStream->m_byteSampleSize
   2042         * pClipCtxt->pAudioStream->m_nbChannels;
   2043 
   2044     if( outputBuffer.m_bufferSize > 0 ) {
   2045 
   2046         outputBuffer.m_dataAddress =
   2047             (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(outputBuffer.m_bufferSize \
   2048             *sizeof(short), M4VSS3GPP, (M4OSA_Char *)"outputBuffer.m_bufferSize");
   2049 
   2050         if( M4OSA_NULL == outputBuffer.m_dataAddress ) {
   2051 
   2052             M4OSA_TRACE1_0(
   2053                 "M4VSS3GPP_intCheckAndGetCodecAacProperties():\
   2054                  unable to allocate outputBuffer.m_dataAddress");
   2055             return M4ERR_ALLOC;
   2056         }
   2057     }
   2058 
   2059     err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec(
   2060             pClipCtxt->pAudioDecCtxt, M4OSA_NULL, &outputBuffer, M4OSA_FALSE);
   2061 
   2062     if ( err == M4WAR_INFO_FORMAT_CHANGE ) {
   2063 
   2064         // Get the properties from codec node
   2065         pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctGetOptionAudioDec(
   2066          pClipCtxt->pAudioDecCtxt,
   2067            M4AD_kOptionID_AudioNbChannels, (M4OSA_DataOption) &optionValue);
   2068 
   2069         pClipCtxt->AacProperties.aNumChan = optionValue;
   2070         // Reset Reader structure value also
   2071         pClipCtxt->pAudioStream->m_nbChannels = optionValue;
   2072 
   2073         pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctGetOptionAudioDec(
   2074          pClipCtxt->pAudioDecCtxt,
   2075           M4AD_kOptionID_AudioSampFrequency, (M4OSA_DataOption) &optionValue);
   2076 
   2077         pClipCtxt->AacProperties.aSampFreq = optionValue;
   2078         // Reset Reader structure value also
   2079         pClipCtxt->pAudioStream->m_samplingFrequency = optionValue;
   2080 
   2081     } else if( err != M4NO_ERROR) {
   2082         M4OSA_TRACE1_1("M4VSS3GPP_intCheckAndGetCodecAacProperties:\
   2083             m_pFctStepAudioDec returns err = 0x%x", err);
   2084     }
   2085 
   2086     free(outputBuffer.m_dataAddress);
   2087 
   2088     // Reset the stream reader
   2089     err = pClipCtxt->ShellAPI.m_pReader->m_pFctReset(
   2090      pClipCtxt->pReaderContext,
   2091      (M4_StreamHandler *)pClipCtxt->pAudioStream);
   2092 
   2093     if (M4NO_ERROR != err) {
   2094         M4OSA_TRACE1_1("M4VSS3GPP_intCheckAndGetCodecAacProperties\
   2095             Error in reseting reader: 0x%x", err);
   2096     }
   2097 
   2098     return err;
   2099 
   2100 }
   2101