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   M4MCS_Codecs.c
     19  * @brief  MCS implementation
     20  * @note   This file contains all functions related to audio/video
     21  *         codec manipulations.
     22  ************************************************************************
     23  */
     24 
     25 /**
     26  ********************************************************************
     27  * Includes
     28  ********************************************************************
     29  */
     30 #include "NXPSW_CompilerSwitches.h"
     31 #include "M4OSA_Debug.h"            /* Include for OSAL debug services */
     32 #include "M4MCS_InternalTypes.h"    /* Internal types of the MCS */
     33 
     34 
     35 #ifdef M4MCS_SUPPORT_VIDEC_3GP
     36 #include "M4_MPEG4VI_VideoHandler.h"  /*needed for renderer error codes*/
     37 #endif
     38 
     39 
     40 /**
     41  ************************************************************************
     42  * M4OSA_ERR   M4MCS_clearInterfaceTables()
     43  * @brief    Clear encoders, decoders, reader and writers interfaces tables
     44  * @param    pContext            (IN/OUT) MCS context.
     45  * @return    M4NO_ERROR:            No error
     46  * @return    M4ERR_PARAMETER:    The context is null
     47  ************************************************************************
     48  */
     49 M4OSA_ERR   M4MCS_clearInterfaceTables(M4MCS_Context pContext)
     50 {
     51     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
     52     M4OSA_UInt8 i;
     53 
     54     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
     55 
     56     /* Initialisation that will allow to check if registering twice */
     57     pC->pWriterGlobalFcts = M4OSA_NULL;
     58     pC->pWriterDataFcts = M4OSA_NULL;
     59     pC->pVideoEncoderGlobalFcts = M4OSA_NULL;
     60     pC->pAudioEncoderGlobalFcts = M4OSA_NULL;
     61 
     62     pC->pCurrentVideoEncoderExternalAPI = M4OSA_NULL;
     63     pC->pCurrentVideoEncoderUserData = M4OSA_NULL;
     64 
     65     for (i = 0; i < M4WRITER_kType_NB; i++ )
     66     {
     67         pC->WriterInterface[i].pGlobalFcts = M4OSA_NULL;
     68         pC->WriterInterface[i].pDataFcts = M4OSA_NULL;
     69     }
     70 
     71     for (i = 0; i < M4ENCODER_kVideo_NB; i++ )
     72     {
     73         pC->pVideoEncoderInterface[i] = M4OSA_NULL;
     74         pC->pVideoEncoderExternalAPITable[i] = M4OSA_NULL;
     75         pC->pVideoEncoderUserDataTable[i] = M4OSA_NULL;
     76     }
     77 
     78     for (i = 0; i < M4ENCODER_kAudio_NB; i++ )
     79     {
     80         pC->pAudioEncoderInterface[i] = M4OSA_NULL;
     81         pC->pAudioEncoderFlag[i] = M4OSA_FALSE;
     82         pC->pAudioEncoderUserDataTable[i] = M4OSA_NULL;
     83     }
     84 
     85     /* Initialisation that will allow to check if registering twice */
     86     pC->m_pReader = M4OSA_NULL;
     87     pC->m_pReaderDataIt   = M4OSA_NULL;
     88     pC->m_uiNbRegisteredReaders  = 0;
     89 
     90     for (i = 0; i < M4READER_kMediaType_NB; i++ )
     91     {
     92         pC->m_pReaderGlobalItTable[i] = M4OSA_NULL;
     93         pC->m_pReaderDataItTable[i]   = M4OSA_NULL;
     94     }
     95 
     96     pC->m_pVideoDecoder = M4OSA_NULL;
     97 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
     98     pC->m_pCurrentVideoDecoderUserData = M4OSA_NULL;
     99 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
    100     pC->m_uiNbRegisteredVideoDec = 0;
    101     for (i = 0; i < M4DECODER_kVideoType_NB; i++ )
    102     {
    103         pC->m_pVideoDecoderItTable[i] = M4OSA_NULL;
    104 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
    105         pC->m_pVideoDecoderUserDataTable[i] = M4OSA_NULL;
    106 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
    107     }
    108 
    109     pC->m_pAudioDecoder = M4OSA_NULL;
    110     for (i = 0; i < M4AD_kType_NB; i++ )
    111     {
    112         pC->m_pAudioDecoderItTable[i] = M4OSA_NULL;
    113         pC->m_pAudioDecoderFlagTable[i] = M4OSA_FALSE;
    114         pC->m_pAudioDecoderUserDataTable[i] = M4OSA_NULL;
    115     }
    116 
    117     return M4NO_ERROR;
    118 }
    119 
    120 /**
    121  ******************************************************************************
    122  * M4OSA_ERR   M4MCS_registerWriter()
    123  * @brief    This function will register a specific file format writer.
    124  * @note    According to the Mediatype, this function will store in the internal context
    125  *          the writer context.
    126  * @param    pContext:    (IN) Execution context.
    127  * @return    M4NO_ERROR: there is no error
    128  * @return      M4ERR_PARAMETER     pContext,pWtrGlobalInterface or
    129  *                                  pWtrDataInterface is M4OSA_NULL
    130  *                                  (debug only), or invalid MediaType
    131  ******************************************************************************
    132  */
    133 M4OSA_ERR   M4MCS_registerWriter(M4MCS_Context pContext, M4WRITER_OutputFileType MediaType,
    134                                  M4WRITER_GlobalInterface* pWtrGlobalInterface,
    135                                  M4WRITER_DataInterface* pWtrDataInterface)
    136 {
    137     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    138 
    139     /**
    140      *    Check input parameters */
    141     M4OSA_DEBUG_IF2((pC == M4OSA_NULL),M4ERR_PARAMETER,
    142          "MCS: context is M4OSA_NULL in M4MCS_registerWriter");
    143     M4OSA_DEBUG_IF2((pWtrGlobalInterface == M4OSA_NULL),M4ERR_PARAMETER,
    144          "pWtrGlobalInterface is M4OSA_NULL in M4MCS_registerWriter");
    145     M4OSA_DEBUG_IF2((pWtrDataInterface == M4OSA_NULL),M4ERR_PARAMETER,
    146          "pWtrDataInterface is M4OSA_NULL in M4MCS_registerWriter");
    147 
    148     M4OSA_TRACE3_3("MCS: M4MCS_registerWriter called with pContext=0x%x,\
    149      pWtrGlobalInterface=0x%x, pWtrDataInterface=0x%x", pC,pWtrGlobalInterface,
    150      pWtrDataInterface);
    151 
    152     if((MediaType == M4WRITER_kUnknown) || (MediaType >= M4WRITER_kType_NB))
    153     {
    154         M4OSA_DEBUG_IF1(M4OSA_TRUE, M4ERR_PARAMETER, "Invalid media type");
    155         return M4ERR_PARAMETER;
    156     }
    157 
    158     if (pC->WriterInterface[MediaType].pGlobalFcts != M4OSA_NULL)
    159     {
    160       /* a writer corresponding to this media type has already been registered !*/
    161       M4OSA_DEBUG_IF1(M4OSA_TRUE, M4ERR_PARAMETER, "This media type has already been registered");
    162       return M4ERR_PARAMETER;
    163     }
    164 
    165     /*
    166      * Save writer interface in context */
    167     pC->WriterInterface[MediaType].pGlobalFcts = pWtrGlobalInterface;
    168     pC->WriterInterface[MediaType].pDataFcts = pWtrDataInterface;
    169 
    170     return M4NO_ERROR;
    171 }
    172 
    173 /**
    174  ******************************************************************************
    175  * M4OSA_ERR   M4MCS_registerEncoder()
    176  * @brief    This function will register a specific video encoder.
    177  * @note    According to the Mediatype, this function will store in the internal context
    178  *           the encoder context.
    179  * @param    pContext:    (IN) Execution context.
    180  * @return    M4NO_ERROR: there is no error
    181  * @return    M4ERR_PARAMETER    pContext or pEncGlobalInterface is M4OSA_NULL (debug only),
    182  *                             or invalid MediaType
    183  ******************************************************************************
    184  */
    185 M4OSA_ERR   M4MCS_registerVideoEncoder (
    186                     M4MCS_Context pContext,
    187                     M4ENCODER_Format MediaType,
    188                     M4ENCODER_GlobalInterface *pEncGlobalInterface)
    189 {
    190     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    191 
    192     /**
    193      *    Check input parameters */
    194     M4OSA_DEBUG_IF2((pC == M4OSA_NULL),M4ERR_PARAMETER,
    195          "MCS: context is M4OSA_NULL in M4MCS_registerVideoEncoder");
    196     M4OSA_DEBUG_IF2((pEncGlobalInterface == M4OSA_NULL),M4ERR_PARAMETER,
    197          "pEncGlobalInterface is M4OSA_NULL in M4MCS_registerVideoEncoder");
    198 
    199     M4OSA_TRACE3_2("MCS: M4MCS_registerVideoEncoder called with pContext=0x%x,\
    200          pEncGlobalInterface=0x%x", pC, pEncGlobalInterface);
    201 
    202     if (MediaType >= M4ENCODER_kVideo_NB)
    203     {
    204       M4OSA_DEBUG_IF1(M4OSA_TRUE, M4ERR_PARAMETER, "Invalid video encoder type");
    205       return M4ERR_PARAMETER;
    206     }
    207 
    208     if (pC->pVideoEncoderInterface[MediaType] != M4OSA_NULL)
    209     {
    210         /* can be legitimate, in cases where we have one version that can use external encoders
    211         but which still has the built-in one to be able to work without an external encoder; in
    212         this case the new encoder simply replaces the old one (i.e. we unregister it first). */
    213         free(pC->pVideoEncoderInterface[MediaType]);
    214         pC->pVideoEncoderInterface[MediaType] = M4OSA_NULL;
    215     }
    216 
    217     /*
    218      * Save encoder interface in context */
    219     pC->pVideoEncoderInterface[MediaType] = pEncGlobalInterface;
    220     /* The actual userData and external API will be set by the registration function in the case
    221     of an external encoder (add it as a parameter to this function in the long run?) */
    222     pC->pVideoEncoderUserDataTable[MediaType] = M4OSA_NULL;
    223     pC->pVideoEncoderExternalAPITable[MediaType] = M4OSA_NULL;
    224 
    225     return M4NO_ERROR;
    226 }
    227 
    228 /**
    229  ******************************************************************************
    230  * M4OSA_ERR   M4MCS_registerAudioEncoder()
    231  * @brief    This function will register a specific audio encoder.
    232  * @note    According to the Mediatype, this function will store in the internal context
    233  *           the encoder context.
    234  * @param    pContext:                (IN) Execution context.
    235  * @param    mediaType:                (IN) The media type.
    236  * @param    pEncGlobalInterface:    (OUT) the encoder interface functions.
    237  * @return    M4NO_ERROR: there is no error
    238  * @return   M4ERR_PARAMETER:   pContext or pEncGlobalInterface is
    239  *                              M4OSA_NULL (debug only)
    240  ******************************************************************************
    241  */
    242 M4OSA_ERR   M4MCS_registerAudioEncoder(
    243                     M4MCS_Context pContext,
    244                     M4ENCODER_AudioFormat MediaType,
    245                     M4ENCODER_AudioGlobalInterface *pEncGlobalInterface)
    246 {
    247     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    248 
    249     /**
    250      *    Check input parameters */
    251     M4OSA_DEBUG_IF2((pC == M4OSA_NULL),M4ERR_PARAMETER,
    252          "MCS: context is M4OSA_NULL in M4MCS_registerAudioEncoder");
    253     M4OSA_DEBUG_IF2((pEncGlobalInterface == M4OSA_NULL),M4ERR_PARAMETER,
    254          "pEncGlobalInterface is M4OSA_NULL in M4MCS_registerAudioEncoder");
    255 
    256     M4OSA_TRACE3_2("MCS: M4MCS_registerAudioEncoder called with pContext=0x%x,\
    257          pEncGlobalInterface=0x%x", pC, pEncGlobalInterface);
    258 
    259     if (MediaType >= M4ENCODER_kAudio_NB)
    260     {
    261         M4OSA_DEBUG_IF1(M4OSA_TRUE, M4ERR_PARAMETER, "Invalid audio encoder type");
    262         return M4ERR_PARAMETER;
    263     }
    264 
    265     if(M4OSA_NULL != pC->pAudioEncoderInterface[MediaType])
    266     {
    267         free(pC->pAudioEncoderInterface[MediaType]);
    268         pC->pAudioEncoderInterface[MediaType] = M4OSA_NULL;
    269 
    270         if(M4OSA_NULL != pC->pAudioEncoderUserDataTable[MediaType])
    271         {
    272             free(pC->pAudioEncoderUserDataTable[MediaType]);
    273             pC->pAudioEncoderUserDataTable[MediaType] = M4OSA_NULL;
    274         }
    275     }
    276 
    277     /*
    278      * Save encoder interface in context */
    279     pC->pAudioEncoderInterface[MediaType] = pEncGlobalInterface;
    280     pC->pAudioEncoderFlag[MediaType] = M4OSA_FALSE; /* internal encoder */
    281 
    282     return M4NO_ERROR;
    283 }
    284 
    285 /**
    286  ************************************************************************
    287  * M4OSA_ERR   M4MCS_registerReader()
    288  * @brief    Register reader.
    289  * @param    pContext            (IN/OUT) MCS context.
    290  * @return    M4NO_ERROR:            No error
    291  * @return    M4ERR_PARAMETER:    A parameter is null (in DEBUG only)
    292  ************************************************************************
    293  */
    294 M4OSA_ERR   M4MCS_registerReader(
    295                         M4MCS_Context pContext,
    296                         M4READER_MediaType mediaType,
    297                         M4READER_GlobalInterface *pRdrGlobalInterface,
    298                         M4READER_DataInterface *pRdrDataInterface)
    299 {
    300     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    301 
    302     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
    303     M4OSA_DEBUG_IF1((M4OSA_NULL == pRdrGlobalInterface),
    304          M4ERR_PARAMETER, "M4MCS_registerReader: invalid pointer on global interface");
    305     M4OSA_DEBUG_IF1((M4OSA_NULL == pRdrDataInterface),
    306          M4ERR_PARAMETER, "M4MCS_registerReader: invalid pointer on data interface");
    307 
    308     if (mediaType == M4READER_kMediaTypeUnknown || mediaType >= M4READER_kMediaType_NB)
    309     {
    310         M4OSA_DEBUG_IF1(M4OSA_TRUE, M4ERR_PARAMETER, "Invalid media type");
    311         return M4ERR_PARAMETER;
    312     }
    313 
    314     if (pC->m_pReaderGlobalItTable[mediaType] != M4OSA_NULL)
    315     {
    316         /* a reader corresponding to this media type has already been registered !*/
    317       M4OSA_DEBUG_IF1(M4OSA_TRUE, M4ERR_PARAMETER, "This media type has already been registered");
    318       return M4ERR_PARAMETER;
    319     }
    320 
    321     pC->m_pReaderGlobalItTable[mediaType] = pRdrGlobalInterface;
    322     pC->m_pReaderDataItTable[mediaType]   = pRdrDataInterface;
    323 
    324     pC->m_uiNbRegisteredReaders++;
    325 
    326     return M4NO_ERROR;
    327 }
    328 
    329 /**
    330  ************************************************************************
    331  * M4OSA_ERR   M4MCS_registerVideoDecoder()
    332  * @brief    Register video decoder
    333  * @param    pContext                (IN/OUT) MCS context.
    334  * @param    decoderType            (IN) Decoder type
    335  * @param    pDecoderInterface    (IN) Decoder interface.
    336  * @return    M4NO_ERROR:            No error
    337  * @return    M4ERR_PARAMETER:    A parameter is null (in DEBUG only), or the decoder
    338  *                              type is invalid
    339  ************************************************************************
    340  */
    341 M4OSA_ERR   M4MCS_registerVideoDecoder(
    342                             M4MCS_Context pContext,
    343                             M4DECODER_VideoType decoderType,
    344                             M4DECODER_VideoInterface *pDecoderInterface)
    345 {
    346     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    347 
    348     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
    349     M4OSA_DEBUG_IF1((M4OSA_NULL == pDecoderInterface), M4ERR_PARAMETER,
    350          "M4MCS_registerVideoDecoder: invalid pointer on decoder interface");
    351 
    352     if (decoderType >= M4DECODER_kVideoType_NB)
    353     {
    354       M4OSA_DEBUG_IF1(M4OSA_TRUE, M4ERR_PARAMETER, "Invalid video decoder type");
    355       return M4ERR_PARAMETER;
    356     }
    357 
    358     if (pC->m_pVideoDecoderItTable[decoderType] != M4OSA_NULL)
    359     {
    360 #ifndef M4VSS_ENABLE_EXTERNAL_DECODERS
    361         /* a decoder corresponding to this media type has already been registered !*/
    362         M4OSA_DEBUG_IF1(M4OSA_TRUE, M4ERR_PARAMETER, "Decoder has already been registered");
    363         return M4ERR_PARAMETER;
    364 #else /* external decoders are possible */
    365         /* can be legitimate, in cases where we have one version that can use external decoders
    366         but which still has the built-in one to be able to work without an external decoder; in
    367         this case the new decoder simply replaces the old one (i.e. we unregister it first). */
    368         free(pC->m_pVideoDecoderItTable[decoderType]);
    369         pC->m_pVideoDecoderItTable[decoderType] = M4OSA_NULL;
    370         /* oh, and don't forget the user data, too. */
    371         if (pC->m_pVideoDecoderUserDataTable[decoderType] != M4OSA_NULL)
    372         {
    373             free(pC->m_pVideoDecoderUserDataTable[decoderType]);
    374             pC->m_pVideoDecoderUserDataTable[decoderType] = M4OSA_NULL;
    375         }
    376 #endif /* are external decoders possible? */
    377     }
    378 
    379     pC->m_pVideoDecoderItTable[decoderType] = pDecoderInterface;
    380 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
    381     pC->m_pVideoDecoderUserDataTable[decoderType] = M4OSA_NULL;
    382     /* The actual userData will be set by the registration function in the case
    383     of an external decoder (add it as a parameter to this function in the long run?) */
    384 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
    385     pC->m_uiNbRegisteredVideoDec++;
    386 
    387     return M4NO_ERROR;
    388 }
    389 
    390 /**
    391  ************************************************************************
    392  * M4OSA_ERR   M4MCS_registerAudioDecoder()
    393  * @brief    Register audio decoder
    394  * @note        This function is used internaly by the MCS to
    395  *              register audio decoders,
    396  * @param    context                (IN/OUT) MCS context.
    397  * @param    decoderType            (IN) Audio decoder type
    398  * @param    pDecoderInterface    (IN) Audio decoder interface.
    399  * @return    M4NO_ERROR:            No error
    400  * @return   M4ERR_PARAMETER:    A parameter is null, or the decoder type is invalid(in DEBUG only)
    401  ************************************************************************
    402  */
    403 M4OSA_ERR   M4MCS_registerAudioDecoder(
    404                                     M4MCS_Context pContext,
    405                                     M4AD_Type decoderType,
    406                                     M4AD_Interface *pDecoderInterface)
    407 {
    408     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    409 
    410     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
    411     M4OSA_DEBUG_IF1((M4OSA_NULL == pDecoderInterface), M4ERR_PARAMETER,
    412          "M4MCS_registerAudioDecoder: invalid pointer on decoder interface");
    413 
    414     if (decoderType >= M4AD_kType_NB)
    415     {
    416         M4OSA_DEBUG_IF1(M4OSA_TRUE, M4ERR_PARAMETER, "Invalid audio decoder type");
    417         return M4ERR_PARAMETER;
    418     }
    419 
    420     if(M4OSA_NULL != pC->m_pAudioDecoderItTable[decoderType])
    421     {
    422         free(pC->m_pAudioDecoderItTable[decoderType]);
    423         pC->m_pAudioDecoderItTable[decoderType] = M4OSA_NULL;
    424 
    425         if(M4OSA_NULL != pC->m_pAudioDecoderUserDataTable[decoderType])
    426         {
    427             free(pC->m_pAudioDecoderUserDataTable[decoderType]);
    428             pC->m_pAudioDecoderUserDataTable[decoderType] = M4OSA_NULL;
    429         }
    430     }
    431     pC->m_pAudioDecoderItTable[decoderType] = pDecoderInterface;
    432     pC->m_pAudioDecoderFlagTable[decoderType] = M4OSA_FALSE; /* internal decoder */
    433 
    434     return M4NO_ERROR;
    435 }
    436 
    437 /**
    438  ************************************************************************
    439  * M4OSA_ERR   M4MCS_unRegisterAllWriters()
    440  * @brief    Unregister writer
    441  * @param    pContext            (IN/OUT) MCS context.
    442  * @return    M4NO_ERROR:            No error
    443  * @return    M4ERR_PARAMETER:    A parameter is null (in DEBUG only)
    444  ************************************************************************
    445  */
    446 M4OSA_ERR   M4MCS_unRegisterAllWriters(M4MCS_Context pContext)
    447 {
    448     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    449     M4OSA_Int32 i;
    450 
    451     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
    452 
    453     for (i = 0; i < M4WRITER_kType_NB; i++)
    454     {
    455         if (pC->WriterInterface[i].pGlobalFcts != M4OSA_NULL)
    456         {
    457             free(pC->WriterInterface[i].pGlobalFcts );
    458             pC->WriterInterface[i].pGlobalFcts = M4OSA_NULL;
    459         }
    460         if (pC->WriterInterface[i].pDataFcts != M4OSA_NULL)
    461         {
    462             free(pC->WriterInterface[i].pDataFcts );
    463             pC->WriterInterface[i].pDataFcts = M4OSA_NULL;
    464         }
    465     }
    466 
    467     pC->pWriterGlobalFcts = M4OSA_NULL;
    468     pC->pWriterDataFcts = M4OSA_NULL;
    469 
    470     return M4NO_ERROR;
    471 }
    472 
    473 /**
    474  ************************************************************************
    475  * M4OSA_ERR   M4MCS_unRegisterAllEncoders()
    476  * @brief    Unregister the encoders
    477  * @param    pContext            (IN/OUT) MCS context.
    478  * @return    M4NO_ERROR:            No error
    479  * @return    M4ERR_PARAMETER:    A parameter is null (in DEBUG only)
    480  ************************************************************************
    481  */
    482 M4OSA_ERR   M4MCS_unRegisterAllEncoders(M4MCS_Context pContext)
    483 {
    484     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    485     M4OSA_Int32 i;
    486 
    487     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
    488 
    489     for (i = 0; i < M4ENCODER_kVideo_NB; i++)
    490     {
    491         if (pC->pVideoEncoderInterface[i] != M4OSA_NULL)
    492         {
    493             free(pC->pVideoEncoderInterface[i] );
    494             pC->pVideoEncoderInterface[i] = M4OSA_NULL;
    495         }
    496     }
    497 
    498     for (i = 0; i < M4ENCODER_kAudio_NB; i++)
    499     {
    500         if (pC->pAudioEncoderInterface[i] != M4OSA_NULL)
    501         {
    502             /*Don't free external audio encoders interfaces*/
    503             if (M4OSA_FALSE == pC->pAudioEncoderFlag[i])
    504             {
    505                 free(pC->pAudioEncoderInterface[i] );
    506             }
    507             pC->pAudioEncoderInterface[i] = M4OSA_NULL;
    508         }
    509     }
    510 
    511     pC->pVideoEncoderGlobalFcts = M4OSA_NULL;
    512     pC->pAudioEncoderGlobalFcts = M4OSA_NULL;
    513 
    514     return M4NO_ERROR;
    515 }
    516 
    517 /**
    518  ************************************************************************
    519  * M4OSA_ERR   M4MCS_unRegisterAllReaders()
    520  * @brief    Unregister reader
    521  * @param    pContext            (IN/OUT) MCS context.
    522  * @return    M4NO_ERROR:            No error
    523  * @return    M4ERR_PARAMETER:    A parameter is null (in DEBUG only)
    524  ************************************************************************
    525  */
    526 M4OSA_ERR   M4MCS_unRegisterAllReaders(M4MCS_Context pContext)
    527 {
    528     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    529     M4OSA_Int32 i;
    530 
    531     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
    532 
    533     for (i = 0; i < M4READER_kMediaType_NB; i++)
    534     {
    535         if (pC->m_pReaderGlobalItTable[i] != M4OSA_NULL)
    536         {
    537             free(pC->m_pReaderGlobalItTable[i] );
    538             pC->m_pReaderGlobalItTable[i] = M4OSA_NULL;
    539         }
    540         if (pC->m_pReaderDataItTable[i] != M4OSA_NULL)
    541         {
    542             free(pC->m_pReaderDataItTable[i] );
    543             pC->m_pReaderDataItTable[i] = M4OSA_NULL;
    544         }
    545     }
    546 
    547     pC->m_uiNbRegisteredReaders = 0;
    548     pC->m_pReader = M4OSA_NULL;
    549     pC->m_pReaderDataIt = M4OSA_NULL;
    550 
    551     return M4NO_ERROR;
    552 }
    553 
    554 /**
    555  ************************************************************************
    556  * M4OSA_ERR   M4MCS_unRegisterAllDecoders()
    557  * @brief    Unregister the decoders
    558  * @param    pContext            (IN/OUT) MCS context.
    559  * @return    M4NO_ERROR:            No error
    560  * @return    M4ERR_PARAMETER:    A parameter is null (in DEBUG only)
    561  ************************************************************************
    562  */
    563 M4OSA_ERR   M4MCS_unRegisterAllDecoders(M4MCS_Context pContext)
    564 {
    565     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    566     M4OSA_Int32 i;
    567 
    568     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
    569 
    570     for (i = 0; i < M4DECODER_kVideoType_NB; i++)
    571     {
    572         if (pC->m_pVideoDecoderItTable[i] != M4OSA_NULL)
    573         {
    574             free(pC->m_pVideoDecoderItTable[i] );
    575             pC->m_pVideoDecoderItTable[i] = M4OSA_NULL;
    576         }
    577     }
    578 
    579     for (i = 0; i < M4AD_kType_NB; i++)
    580     {
    581         if (pC->m_pAudioDecoderItTable[i] != M4OSA_NULL)
    582         {
    583             /*Don't free external audio decoders interfaces*/
    584             if (M4OSA_FALSE == pC->m_pAudioDecoderFlagTable[i])
    585             {
    586                 free(pC->m_pAudioDecoderItTable[i] );
    587             }
    588             pC->m_pAudioDecoderItTable[i] = M4OSA_NULL;
    589         }
    590     }
    591 
    592     pC->m_uiNbRegisteredVideoDec = 0;
    593     pC->m_pVideoDecoder = M4OSA_NULL;
    594 
    595     pC->m_pAudioDecoder = M4OSA_NULL;
    596 
    597     return M4NO_ERROR;
    598 }
    599 
    600 /**
    601  ************************************************************************
    602  * M4OSA_ERR   M4MCS_setCurrentWriter()
    603  * @brief    Set current writer
    604  * @param    pContext            (IN/OUT) MCS context.
    605  * @param    mediaType            (IN) Media type.
    606  * @return    M4NO_ERROR:            No error
    607  * @return    M4ERR_PARAMETER:                    A parameter is null (in DEBUG only)
    608  * @return    M4WAR_MCS_MEDIATYPE_NOT_SUPPORTED:    Media type not supported
    609  ************************************************************************
    610  */
    611 M4OSA_ERR   M4MCS_setCurrentWriter( M4MCS_Context pContext,
    612                                     M4VIDEOEDITING_FileType mediaType)
    613 {
    614     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    615     M4WRITER_OutputFileType writerType;
    616 
    617     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
    618 
    619     switch (mediaType)
    620     {
    621         case M4VIDEOEDITING_kFileType_3GPP:
    622         case M4VIDEOEDITING_kFileType_MP4:
    623         case M4VIDEOEDITING_kFileType_M4V:
    624             writerType = M4WRITER_k3GPP;
    625             break;
    626         case M4VIDEOEDITING_kFileType_AMR:
    627             writerType = M4WRITER_kAMR;
    628             break;
    629         case M4VIDEOEDITING_kFileType_MP3:
    630             writerType = M4WRITER_kMP3;
    631             break;
    632         case M4VIDEOEDITING_kFileType_PCM:
    633             pC->b_isRawWriter = M4OSA_TRUE;
    634             writerType = M4WRITER_kPCM;
    635             break;
    636         default:
    637             M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
    638                  "Writer type not supported");
    639             return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
    640     }
    641 
    642     pC->pWriterGlobalFcts = pC->WriterInterface[writerType].pGlobalFcts;
    643     pC->pWriterDataFcts = pC->WriterInterface[writerType].pDataFcts;
    644 
    645     if (pC->pWriterGlobalFcts == M4OSA_NULL || pC->pWriterDataFcts == M4OSA_NULL)
    646     {
    647         M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
    648              "Writer type not supported");
    649         return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
    650     }
    651 
    652     pC->pWriterDataFcts->pWriterContext = M4OSA_NULL;
    653 
    654     return M4NO_ERROR;
    655 }
    656 
    657 /**
    658  ************************************************************************
    659  * M4OSA_ERR   M4MCS_setCurrentVideoEncoder()
    660  * @brief    Set a video encoder
    661  * @param    pContext            (IN/OUT) MCS context.
    662  * @param    MediaType           (IN) Encoder type
    663  * @return    M4NO_ERROR:            No error
    664  * @return    M4ERR_PARAMETER:                    A parameter is null (in DEBUG only)
    665  * @return    M4WAR_MCS_MEDIATYPE_NOT_SUPPORTED:    Media type not supported
    666  ************************************************************************
    667  */
    668 M4OSA_ERR   M4MCS_setCurrentVideoEncoder(
    669                                 M4MCS_Context pContext,
    670                                 M4VIDEOEDITING_VideoFormat mediaType)
    671 {
    672     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    673     M4ENCODER_Format encoderType;
    674 
    675     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
    676 
    677     switch (mediaType)
    678     {
    679         case M4VIDEOEDITING_kH263:
    680             encoderType = M4ENCODER_kH263;
    681             break;
    682         case M4VIDEOEDITING_kMPEG4:
    683             encoderType = M4ENCODER_kMPEG4;
    684             break;
    685         case M4VIDEOEDITING_kH264:
    686 #ifdef M4VSS_SUPPORT_ENCODER_AVC
    687             encoderType = M4ENCODER_kH264;
    688         break;
    689 #endif
    690         default:
    691             M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
    692                  "Video encoder type not supported");
    693             return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
    694     }
    695 
    696     pC->pVideoEncoderGlobalFcts = pC->pVideoEncoderInterface[encoderType];
    697     pC->pCurrentVideoEncoderExternalAPI = pC->pVideoEncoderExternalAPITable[encoderType];
    698     pC->pCurrentVideoEncoderUserData = pC->pVideoEncoderUserDataTable[encoderType];
    699 
    700     if (pC->pVideoEncoderGlobalFcts == M4OSA_NULL)
    701     {
    702         M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
    703              "Video encoder type not supported");
    704         return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
    705     }
    706 
    707     return M4NO_ERROR;
    708 }
    709 
    710 /**
    711  ************************************************************************
    712  * M4OSA_ERR   M4MCS_setCurrentAudioEncoder()
    713  * @brief    Set an audio encoder
    714  * @param    context            (IN/OUT) MCS context.
    715  * @param    MediaType        (IN) Encoder type
    716  * @return    M4NO_ERROR:            No error
    717  * @return    M4ERR_PARAMETER:    A parameter is null (in DEBUG only)
    718  ************************************************************************
    719  */
    720 M4OSA_ERR   M4MCS_setCurrentAudioEncoder(
    721                                 M4MCS_Context pContext,
    722                                 M4VIDEOEDITING_AudioFormat mediaType)
    723 {
    724     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    725     M4ENCODER_AudioFormat encoderType;
    726 
    727     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
    728 
    729     switch (mediaType)
    730     {
    731         case M4VIDEOEDITING_kAMR_NB:
    732             encoderType = M4ENCODER_kAMRNB;
    733             break;
    734         case M4VIDEOEDITING_kAAC:
    735             encoderType = M4ENCODER_kAAC;
    736             break;
    737         case M4VIDEOEDITING_kMP3:
    738             encoderType = M4ENCODER_kMP3;
    739             break;
    740 //EVRC
    741 //        case M4VIDEOEDITING_kEVRC:
    742 //            encoderType = M4ENCODER_kEVRC;
    743 //            break;
    744         default:
    745             M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
    746                  "Audio encoder type not supported");
    747             return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
    748     }
    749 
    750     pC->pAudioEncoderGlobalFcts = pC->pAudioEncoderInterface[encoderType];
    751     pC->pCurrentAudioEncoderUserData = pC->pAudioEncoderUserDataTable[encoderType];
    752 
    753     if (pC->pAudioEncoderGlobalFcts == M4OSA_NULL)
    754     {
    755         M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
    756              "Audio encoder type not supported");
    757         return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
    758     }
    759 
    760     return M4NO_ERROR;
    761 }
    762 
    763 /**
    764  ************************************************************************
    765  * M4OSA_ERR   M4MCS_setCurrentReader()
    766  * @brief    Set current reader
    767  * @param    pContext            (IN/OUT) MCS context.
    768  * @param    mediaType            (IN) Media type.
    769  * @return    M4NO_ERROR:            No error
    770  * @return    M4ERR_PARAMETER:                    A parameter is null (in DEBUG only)
    771  * @return    M4WAR_MCS_MEDIATYPE_NOT_SUPPORTED:    Media type not supported
    772  ************************************************************************
    773  */
    774 M4OSA_ERR   M4MCS_setCurrentReader( M4MCS_Context pContext,
    775                                     M4VIDEOEDITING_FileType mediaType)
    776 {
    777     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    778     M4READER_MediaType readerType;
    779 
    780     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
    781 
    782     switch (mediaType)
    783     {
    784         case M4VIDEOEDITING_kFileType_3GPP:
    785         case M4VIDEOEDITING_kFileType_MP4:
    786         case M4VIDEOEDITING_kFileType_M4V:
    787             readerType = M4READER_kMediaType3GPP;
    788             break;
    789         case M4VIDEOEDITING_kFileType_AMR:
    790             readerType = M4READER_kMediaTypeAMR;
    791             break;
    792         case M4VIDEOEDITING_kFileType_MP3:
    793             readerType = M4READER_kMediaTypeMP3;
    794             break;
    795         default:
    796             M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
    797                  "Reader type not supported");
    798             return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
    799     }
    800 
    801     pC->m_pReader       = pC->m_pReaderGlobalItTable[readerType];
    802     pC->m_pReaderDataIt = pC->m_pReaderDataItTable[readerType];
    803 
    804     if (pC->m_pReader == M4OSA_NULL || pC->m_pReaderDataIt == M4OSA_NULL)
    805     {
    806         M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
    807              "Reader type not supported");
    808         return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
    809     }
    810     return M4NO_ERROR;
    811 }
    812 
    813 /**
    814  ************************************************************************
    815  * M4OSA_ERR   M4MCS_setCurrentVideoDecoder()
    816  * @brief    Set a video decoder
    817  * @param    pContext            (IN/OUT) MCS context.
    818  * @param    decoderType        (IN) Decoder type
    819  * @return    M4NO_ERROR:            No error
    820  * @return    M4ERR_PARAMETER:                    A parameter is null (in DEBUG only)
    821  * @return    M4WAR_MCS_MEDIATYPE_NOT_SUPPORTED:    Media type not supported
    822  ************************************************************************
    823  */
    824 M4OSA_ERR   M4MCS_setCurrentVideoDecoder(   M4MCS_Context pContext,
    825                                             M4_StreamType mediaType)
    826 {
    827     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    828     M4DECODER_VideoType decoderType;
    829 
    830     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
    831 
    832     switch (mediaType)
    833     {
    834         case M4DA_StreamTypeVideoMpeg4:
    835         case M4DA_StreamTypeVideoH263:
    836             decoderType = M4DECODER_kVideoTypeMPEG4;
    837             break;
    838         case M4DA_StreamTypeVideoMpeg4Avc:
    839             decoderType = M4DECODER_kVideoTypeAVC;
    840             break;
    841         default:
    842             M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
    843                  "Video decoder type not supported");
    844             return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
    845     }
    846 
    847     pC->m_pVideoDecoder = pC->m_pVideoDecoderItTable[decoderType];
    848 #ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
    849     pC->m_pCurrentVideoDecoderUserData =
    850             pC->m_pVideoDecoderUserDataTable[decoderType];
    851 #endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
    852 
    853     if (pC->m_pVideoDecoder == M4OSA_NULL)
    854     {
    855         M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
    856              "Video decoder type not supported");
    857         return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
    858     }
    859 
    860     return M4NO_ERROR;
    861 }
    862 
    863 /**
    864  ************************************************************************
    865  * M4OSA_ERR   M4MCS_setCurrentAudioDecoder()
    866  * @brief    Set an audio decoder
    867  * @param    context            (IN/OUT) MCS context.
    868  * @param    decoderType        (IN) Decoder type
    869  * @return    M4NO_ERROR:            No error
    870  * @return    M4ERR_PARAMETER:    A parameter is null (in DEBUG only)
    871  ************************************************************************
    872  */
    873 M4OSA_ERR   M4MCS_setCurrentAudioDecoder(   M4MCS_Context pContext,
    874                                             M4_StreamType mediaType)
    875 {
    876     M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
    877     M4AD_Type decoderType;
    878 
    879     M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
    880 
    881     switch (mediaType)
    882     {
    883         case M4DA_StreamTypeAudioAmrNarrowBand:
    884             decoderType = M4AD_kTypeAMRNB;
    885             break;
    886         case M4DA_StreamTypeAudioAac:
    887         case M4DA_StreamTypeAudioAacADTS:
    888         case M4DA_StreamTypeAudioAacADIF:
    889             decoderType = M4AD_kTypeAAC;
    890             break;
    891         case M4DA_StreamTypeAudioMp3:
    892             decoderType = M4AD_kTypeMP3;
    893             break;
    894 //EVRC
    895 //        case M4DA_StreamTypeAudioEvrc:
    896 //            decoderType = M4AD_kTypeEVRC;
    897 //            break;
    898         default:
    899             M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
    900                  "Audio decoder type not supported");
    901             return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
    902     }
    903 
    904     pC->m_pAudioDecoder = pC->m_pAudioDecoderItTable[decoderType];
    905     pC->m_pCurrentAudioDecoderUserData =
    906                     pC->m_pAudioDecoderUserDataTable[decoderType];
    907 
    908     if (pC->m_pAudioDecoder == M4OSA_NULL)
    909     {
    910         M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
    911              "Audio decoder type not supported");
    912         return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
    913     }
    914 
    915     return M4NO_ERROR;
    916 }
    917 
    918