M4MCS_Codecs.c revision b5c7784c96a606890eb8a8b560153ef4a5d1a0d9
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 */
49M4OSA_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 */
133M4OSA_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 */
185M4OSA_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 */
242M4OSA_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 */
294M4OSA_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 */
341M4OSA_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 */
403M4OSA_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 */
446M4OSA_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 */
482M4OSA_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 */
526M4OSA_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 */
563M4OSA_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 */
611M4OSA_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 */
668M4OSA_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        case M4VIDEOEDITING_kMPEG4_EMP:
684            encoderType = M4ENCODER_kMPEG4;
685            break;
686        case M4VIDEOEDITING_kH264:
687#ifdef M4VSS_SUPPORT_ENCODER_AVC
688            encoderType = M4ENCODER_kH264;
689        break;
690#endif
691        default:
692            M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
693                 "Video encoder type not supported");
694            return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
695    }
696
697    pC->pVideoEncoderGlobalFcts = pC->pVideoEncoderInterface[encoderType];
698    pC->pCurrentVideoEncoderExternalAPI = pC->pVideoEncoderExternalAPITable[encoderType];
699    pC->pCurrentVideoEncoderUserData = pC->pVideoEncoderUserDataTable[encoderType];
700
701    if (pC->pVideoEncoderGlobalFcts == M4OSA_NULL)
702    {
703        M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
704             "Video encoder type not supported");
705        return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
706    }
707
708    return M4NO_ERROR;
709}
710
711/**
712 ************************************************************************
713 * M4OSA_ERR   M4MCS_setCurrentAudioEncoder()
714 * @brief    Set an audio encoder
715 * @param    context            (IN/OUT) MCS context.
716 * @param    MediaType        (IN) Encoder type
717 * @return    M4NO_ERROR:            No error
718 * @return    M4ERR_PARAMETER:    A parameter is null (in DEBUG only)
719 ************************************************************************
720 */
721M4OSA_ERR   M4MCS_setCurrentAudioEncoder(
722                                M4MCS_Context pContext,
723                                M4VIDEOEDITING_AudioFormat mediaType)
724{
725    M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
726    M4ENCODER_AudioFormat encoderType;
727
728    M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
729
730    switch (mediaType)
731    {
732        case M4VIDEOEDITING_kAMR_NB:
733            encoderType = M4ENCODER_kAMRNB;
734            break;
735        case M4VIDEOEDITING_kAAC:
736            encoderType = M4ENCODER_kAAC;
737            break;
738        case M4VIDEOEDITING_kMP3:
739            encoderType = M4ENCODER_kMP3;
740            break;
741//EVRC
742//        case M4VIDEOEDITING_kEVRC:
743//            encoderType = M4ENCODER_kEVRC;
744//            break;
745        default:
746            M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
747                 "Audio encoder type not supported");
748            return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
749    }
750
751    pC->pAudioEncoderGlobalFcts = pC->pAudioEncoderInterface[encoderType];
752    pC->pCurrentAudioEncoderUserData = pC->pAudioEncoderUserDataTable[encoderType];
753
754    if (pC->pAudioEncoderGlobalFcts == M4OSA_NULL)
755    {
756        M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
757             "Audio encoder type not supported");
758        return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
759    }
760
761    return M4NO_ERROR;
762}
763
764/**
765 ************************************************************************
766 * M4OSA_ERR   M4MCS_setCurrentReader()
767 * @brief    Set current reader
768 * @param    pContext            (IN/OUT) MCS context.
769 * @param    mediaType            (IN) Media type.
770 * @return    M4NO_ERROR:            No error
771 * @return    M4ERR_PARAMETER:                    A parameter is null (in DEBUG only)
772 * @return    M4WAR_MCS_MEDIATYPE_NOT_SUPPORTED:    Media type not supported
773 ************************************************************************
774 */
775M4OSA_ERR   M4MCS_setCurrentReader( M4MCS_Context pContext,
776                                    M4VIDEOEDITING_FileType mediaType)
777{
778    M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
779    M4READER_MediaType readerType;
780
781    M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
782
783    switch (mediaType)
784    {
785        case M4VIDEOEDITING_kFileType_3GPP:
786        case M4VIDEOEDITING_kFileType_MP4:
787        case M4VIDEOEDITING_kFileType_M4V:
788            readerType = M4READER_kMediaType3GPP;
789            break;
790        case M4VIDEOEDITING_kFileType_AMR:
791            readerType = M4READER_kMediaTypeAMR;
792            break;
793        case M4VIDEOEDITING_kFileType_MP3:
794            readerType = M4READER_kMediaTypeMP3;
795            break;
796        default:
797            M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
798                 "Reader type not supported");
799            return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
800    }
801
802    pC->m_pReader       = pC->m_pReaderGlobalItTable[readerType];
803    pC->m_pReaderDataIt = pC->m_pReaderDataItTable[readerType];
804
805    if (pC->m_pReader == M4OSA_NULL || pC->m_pReaderDataIt == M4OSA_NULL)
806    {
807        M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
808             "Reader type not supported");
809        return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
810    }
811    return M4NO_ERROR;
812}
813
814/**
815 ************************************************************************
816 * M4OSA_ERR   M4MCS_setCurrentVideoDecoder()
817 * @brief    Set a video decoder
818 * @param    pContext            (IN/OUT) MCS context.
819 * @param    decoderType        (IN) Decoder type
820 * @return    M4NO_ERROR:            No error
821 * @return    M4ERR_PARAMETER:                    A parameter is null (in DEBUG only)
822 * @return    M4WAR_MCS_MEDIATYPE_NOT_SUPPORTED:    Media type not supported
823 ************************************************************************
824 */
825M4OSA_ERR   M4MCS_setCurrentVideoDecoder(   M4MCS_Context pContext,
826                                            M4_StreamType mediaType)
827{
828    M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
829    M4DECODER_VideoType decoderType;
830
831    M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
832
833    switch (mediaType)
834    {
835        case M4DA_StreamTypeVideoMpeg4:
836        case M4DA_StreamTypeVideoH263:
837            decoderType = M4DECODER_kVideoTypeMPEG4;
838            break;
839        case M4DA_StreamTypeVideoMpeg4Avc:
840            decoderType = M4DECODER_kVideoTypeAVC;
841            break;
842        default:
843            M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
844                 "Video decoder type not supported");
845            return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
846    }
847
848    pC->m_pVideoDecoder = pC->m_pVideoDecoderItTable[decoderType];
849#ifdef M4VSS_ENABLE_EXTERNAL_DECODERS
850    pC->m_pCurrentVideoDecoderUserData =
851            pC->m_pVideoDecoderUserDataTable[decoderType];
852#endif /* M4VSS_ENABLE_EXTERNAL_DECODERS */
853
854    if (pC->m_pVideoDecoder == M4OSA_NULL)
855    {
856        M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
857             "Video decoder type not supported");
858        return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
859    }
860
861    return M4NO_ERROR;
862}
863
864/**
865 ************************************************************************
866 * M4OSA_ERR   M4MCS_setCurrentAudioDecoder()
867 * @brief    Set an audio decoder
868 * @param    context            (IN/OUT) MCS context.
869 * @param    decoderType        (IN) Decoder type
870 * @return    M4NO_ERROR:            No error
871 * @return    M4ERR_PARAMETER:    A parameter is null (in DEBUG only)
872 ************************************************************************
873 */
874M4OSA_ERR   M4MCS_setCurrentAudioDecoder(   M4MCS_Context pContext,
875                                            M4_StreamType mediaType)
876{
877    M4MCS_InternalContext* pC = (M4MCS_InternalContext*)pContext;
878    M4AD_Type decoderType;
879
880    M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER, "invalid context pointer");
881
882    switch (mediaType)
883    {
884        case M4DA_StreamTypeAudioAmrNarrowBand:
885            decoderType = M4AD_kTypeAMRNB;
886            break;
887        case M4DA_StreamTypeAudioAac:
888        case M4DA_StreamTypeAudioAacADTS:
889        case M4DA_StreamTypeAudioAacADIF:
890            decoderType = M4AD_kTypeAAC;
891            break;
892        case M4DA_StreamTypeAudioMp3:
893            decoderType = M4AD_kTypeMP3;
894            break;
895//EVRC
896//        case M4DA_StreamTypeAudioEvrc:
897//            decoderType = M4AD_kTypeEVRC;
898//            break;
899        default:
900            M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
901                 "Audio decoder type not supported");
902            return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
903    }
904
905    pC->m_pAudioDecoder = pC->m_pAudioDecoderItTable[decoderType];
906    pC->m_pCurrentAudioDecoderUserData =
907                    pC->m_pAudioDecoderUserDataTable[decoderType];
908
909    if (pC->m_pAudioDecoder == M4OSA_NULL)
910    {
911        M4OSA_DEBUG_IF1(M4OSA_TRUE, M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED,
912             "Audio decoder type not supported");
913        return M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED;
914    }
915
916    return M4NO_ERROR;
917}
918
919