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