M4READER_Pcm.c revision aa382f3637a68361989d5b70e3184bddcc472d3d
1/*
2 * Copyright (C) 2004-2011 NXP Software
3 * Copyright (C) 2011 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17/**
18 ************************************************************************
19 * @file   M4READER_Wav.c
20 * @brief  Generic encapsulation of the core pcm reader
21 * @note   This file implements the generic M4READER interface
22 *         on top of the PCM reader
23 ************************************************************************
24*/
25
26#include "M4OSA_Types.h"
27#include "M4OSA_Error.h"
28#include "M4OSA_Memory.h"
29#include "M4OSA_Debug.h"
30#include "M4OSA_CoreID.h"
31#include "M4TOOL_VersionInfo.h"
32#include "M4PCMR_CoreReader.h"
33#include "M4READER_Pcm.h"
34/**
35 ************************************************************************
36 * structure    M4READER_WAV_Context
37 * @brief       This structure defines the internal context of a wav reader instance
38 * @note        The context is allocated and de-allocated by the reader
39 ************************************************************************
40 */
41typedef struct _M4READER_PCM_Context
42{
43    M4OSA_Context           m_coreContext;        /**< core wav reader context */
44    M4_StreamHandler*       m_pAudioStream;       /**< pointer on the audio stream description
45                                                        returned by the core */
46    M4SYS_AccessUnit        m_audioAu;            /**< audio access unit to be filled by the core */
47    M4OSA_FileReadPointer*  m_pOsaFileReaderFcts; /**< OSAL file read functions */
48
49} M4READER_PCM_Context;
50
51
52/**
53 ************************************************************************
54 * @brief   Creates a wav reader instance
55 * @note    allocates the context
56 * @param   pContext:            (OUT)  Pointer to a wav reader context
57 * @return  M4NO_ERROR:                 there is no error
58 * @return  M4ERR_ALLOC:                a memory allocation has failed
59 * @return  M4ERR_PARAMETER:            at least one parameter is not properly set (in DEBUG only)
60 ************************************************************************
61 */
62M4OSA_ERR M4READER_PCM_create(M4OSA_Context* pContext)
63{
64    M4READER_PCM_Context*   pReaderContext;
65
66    M4OSA_DEBUG_IF1((pContext == 0),       M4ERR_PARAMETER,
67         "M4READER_PCM_create: invalid context pointer");
68
69    pReaderContext = (M4READER_PCM_Context*)M4OSA_32bitAlignedMalloc(sizeof(M4READER_PCM_Context),
70         M4READER_WAV, (M4OSA_Char *)"M4READER_PCM_Context");
71    if (pReaderContext == M4OSA_NULL)
72    {
73        return M4ERR_ALLOC;
74    }
75
76    pReaderContext->m_coreContext         = M4OSA_NULL;
77    pReaderContext->m_pAudioStream        = M4OSA_NULL;
78    pReaderContext->m_audioAu.dataAddress = M4OSA_NULL;
79    pReaderContext->m_pOsaFileReaderFcts  = M4OSA_NULL;
80
81    *pContext = pReaderContext;
82
83    return M4NO_ERROR;
84}
85
86/**
87 ************************************************************************
88 * @brief   Destroy the instance of the reader
89 * @note    the context is un-allocated
90 * @param   context:         (IN) context of the network reader
91 * @return  M4NO_ERROR:           there is no error
92 * @return  M4ERR_PARAMETER:      at least one parameter is not properly set (in DEBUG only)
93 ************************************************************************
94 */
95M4OSA_ERR M4READER_PCM_destroy(M4OSA_Context context)
96{
97    M4READER_PCM_Context* pC = (M4READER_PCM_Context*)context;
98
99    /* Check function parameters */
100    M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER,
101         "M4READER_PCM_destroy: invalid context pointer");
102
103    free(pC);
104
105    return M4NO_ERROR;
106}
107
108/**
109 ************************************************************************
110 * @brief   Initializes the reader instance
111 * @param   context:           (IN)    context of the network reader
112 * @param   pFileDescriptor:   (IN)    Pointer to proprietary data identifying the media to open
113 * @return  M4NO_ERROR:                there is no error
114 * @return  M4ERR_PARAMETER:           at least one parameter is not properly set (in DEBUG only)
115 ************************************************************************
116 */
117M4OSA_ERR M4READER_PCM_open(M4OSA_Context context, M4OSA_Void* pFileDescriptor)
118{
119    M4READER_PCM_Context*   pC = (M4READER_PCM_Context*)context;
120    M4OSA_ERR               err;
121
122    /* Check function parameters */
123    M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER,
124         "M4READER_PCM_open: invalid context pointer");
125    M4OSA_DEBUG_IF1((M4OSA_NULL == pFileDescriptor),   M4ERR_PARAMETER,
126         "M4READER_PCM_open: invalid pointer pFileDescriptor");
127
128    err = M4PCMR_openRead(&(pC->m_coreContext), (M4OSA_Char*)pFileDescriptor,
129         pC->m_pOsaFileReaderFcts);
130
131    return err;
132}
133
134/**
135 ************************************************************************
136 * @brief     close the reader
137 * @note
138 * @param     context:        (IN)    Context of the reader
139 * @return    M4NO_ERROR                 there is no error
140 * @return    M4ERR_PARAMETER            the context is NULL
141 * @return    M4ERR_BAD_CONTEXT        provided context is not a valid one
142 ************************************************************************
143 */
144M4OSA_ERR M4READER_PCM_close(M4OSA_Context context)
145{
146    M4READER_PCM_Context*   pC = (M4READER_PCM_Context*)context;
147    M4OSA_ERR               err;
148
149    /* Check function parameters */
150    M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER,
151         "M4READER_PCM_close: invalid context pointer");
152
153    /* Free audio AU and audio stream */
154    if (M4OSA_NULL != pC->m_pAudioStream)
155    {
156        if (M4OSA_NULL != pC->m_audioAu.dataAddress)
157        {
158            err = M4PCMR_freeAU(pC->m_coreContext, pC->m_pAudioStream->m_streamId,
159                 &pC->m_audioAu);
160            if (err != M4NO_ERROR)
161            {
162                M4OSA_TRACE1_0("M4READER_PCM_close: Error when freeing audio access unit");
163                return err;
164            }
165        }
166        free(pC->m_pAudioStream);
167        pC->m_pAudioStream = M4OSA_NULL;
168    }
169
170
171    if (M4OSA_NULL != pC->m_coreContext)
172    {
173        /* Close tha PCM file */
174       err = M4PCMR_closeRead(pC->m_coreContext);
175       pC->m_coreContext = M4OSA_NULL;
176    }
177
178
179    return err;
180}
181
182/**
183 ************************************************************************
184 * @brief   set en option value of the reader
185 * @note    this function follows the set/get option mechanism described in OSAL 3.0
186 *          it allows the caller to set a property value:
187 * @param    context:        (IN)    Context of the reader
188 * @param    optionId:       (IN)    indicates the option to set
189 * @param    pValue:         (IN)    pointer to structure or value (allocated by user)
190 *                                    where option is stored
191 *
192 * @return    M4NO_ERROR             there is no error
193 * @return    M4ERR_BAD_CONTEXT      provided context is not a valid one
194 * @return    M4ERR_PARAMETER        at least one parameter is not properly set
195 * @return    M4ERR_BAD_OPTION_ID    when the option ID is not a valid one
196 ************************************************************************
197 */
198M4OSA_ERR M4READER_PCM_setOption(M4OSA_Context context, M4OSA_OptionID optionId, void* pValue)
199{
200    M4READER_PCM_Context* pC = (M4READER_PCM_Context*)context;
201    M4OSA_ERR err = M4NO_ERROR;
202
203    /* Check function parameters */
204    M4OSA_DEBUG_IF1((M4OSA_NULL == pC),     M4ERR_PARAMETER,
205         "M4READER_PCM_setOption: invalid context pointer");
206    M4OSA_DEBUG_IF1((M4OSA_NULL == pValue), M4ERR_PARAMETER,
207         "M4READER_PCM_setOption: invalid value pointer");
208
209    switch(optionId)
210    {
211    case M4READER_kOptionID_SetOsaFileReaderFctsPtr :
212        {
213            pC->m_pOsaFileReaderFcts = (M4OSA_FileReadPointer*)pValue;
214        }
215        break;
216    default :
217        {
218            err = M4ERR_PARAMETER;
219        }
220    }
221
222    return err;
223}
224
225/**
226 ************************************************************************
227 * @brief   Retrieves the an option value from the reader, given an option ID.
228 * @note    this function follows the set/get option mechanism described in OSAL 3.0
229 *          it allows the caller to retrieve a property value:
230 *
231 * @param   context:  (IN) context of the network reader
232 * @param   optionId: (IN) option identificator whose option value is to be retrieved.
233 * @param   pValue:  (OUT) option value retrieved.
234 *
235 * @return  M4NO_ERROR:          there is no error
236 * @return  M4ERR_PARAMETER:     at least one parameter is not properly set (in DEBUG only)
237 * @return  M4ERR_BAD_OPTION_ID: the required option identificator is unknown
238 ************************************************************************
239 */
240M4OSA_ERR M4READER_PCM_getOption(M4OSA_Context context, M4OSA_OptionID optionId, void* pValue)
241{
242    M4READER_PCM_Context*   pContext = (M4READER_PCM_Context*)context;
243    M4OSA_ERR               err      = M4NO_ERROR;
244
245    /* no check of context at this level because some option does not need it */
246    M4OSA_DEBUG_IF1((pValue == 0), M4ERR_PARAMETER,
247         "M4READER_PCM_getOption: invalid pointer on value");
248
249    switch (optionId)
250    {
251    case M4READER_kOptionID_Duration:
252        *((M4OSA_UInt32*)pValue) = pContext->m_pAudioStream->m_duration;
253        break;
254
255    case M4READER_kOptionID_Version:
256        err = M4PCMR_getVersion((M4_VersionInfo*)pValue);
257        break;
258
259    case M4READER_kOptionID_Copyright:
260        return M4ERR_NOT_IMPLEMENTED;
261        break;
262
263    case M4READER_kOptionID_Bitrate:
264        {
265            M4OSA_UInt32* pBitrate = (M4OSA_UInt32*)pValue;
266            if (M4OSA_NULL != pContext->m_pAudioStream)
267            {
268                *pBitrate = pContext->m_pAudioStream->m_averageBitRate;
269            }
270            else
271            {
272                pBitrate = 0;
273                err = M4ERR_PARAMETER;
274            }
275        }
276        break;
277
278    default:
279        err = M4ERR_BAD_OPTION_ID;
280        M4OSA_TRACE1_0("M4READER_PCM_getOption: unsupported optionId");
281        break;
282    }
283
284    return err;
285}
286
287/**
288 ************************************************************************
289 * @brief   Get the next stream found in the media
290 * @note
291 *
292 * @param   context:        (IN)  context of the network reader
293 * @param   pMediaFamily:   (OUT) pointer to a user allocated M4READER_MediaFamily that will
294 *                                be filled
295 * @param   pStreamHandler: (OUT) pointer to a stream handler that will be allocated and filled
296 *                                with the found stream description
297 *
298 * @return  M4NO_ERROR:       there is no error.
299 * @return  M4ERR_PARAMETER:  at least one parameter is not properly set (in DEBUG only)
300 * @return  M4WAR_NO_MORE_STREAM    no more available stream in the media (all streams found)
301 ************************************************************************
302 */
303M4OSA_ERR M4READER_PCM_getNextStream(M4OSA_Context context, M4READER_MediaFamily *pMediaFamily,
304                                     M4_StreamHandler **pStreamHandler)
305{
306    M4READER_PCM_Context*   pC=(M4READER_PCM_Context*)context;
307    M4OSA_ERR               err;
308/*    M4_StreamHandler*       pStreamHandler = M4OSA_NULL;*/
309    M4SYS_StreamDescription streamDesc;
310    M4_AudioStreamHandler*  pAudioStreamHandler;
311    M4OSA_Double            fDuration;
312    M4SYS_StreamID          streamIdArray[2];
313    M4PCMC_DecoderSpecificInfo* pDsi;
314
315    M4OSA_DEBUG_IF1((pC == 0),             M4ERR_PARAMETER,
316         "M4READER_PCM_getNextStream: invalid context");
317    M4OSA_DEBUG_IF1((pMediaFamily == 0),   M4ERR_PARAMETER,
318         "M4READER_PCM_getNextStream: invalid pointer to MediaFamily");
319    M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
320         "M4READER_PCM_getNextStream: invalid pointer to StreamHandler");
321
322    err = M4PCMR_getNextStream( pC->m_coreContext, &streamDesc);
323    if (err == M4WAR_NO_MORE_STREAM)
324    {
325        streamIdArray[0] = 0;
326        streamIdArray[1] = 0;
327        err = M4PCMR_startReading(pC->m_coreContext, streamIdArray); /*to put in open function*/
328
329        return M4WAR_NO_MORE_STREAM;
330    }
331    else if (M4NO_ERROR != err)
332    {
333        return err; /*also return M4WAR_NO_MORE_STREAM*/
334    }
335
336    switch (streamDesc.streamType)
337    {
338        case M4SYS_kAudioUnknown:
339        case M4SYS_kPCM_16bitsS:
340        case M4SYS_kPCM_16bitsU:
341        case M4SYS_kPCM_8bitsU:
342            *pMediaFamily = M4READER_kMediaFamilyAudio;
343            M4OSA_TRACE2_0("M4READER_PCM_getNextStream: found audio stream");
344            break;
345        default:
346            *pMediaFamily = M4READER_kMediaFamilyUnknown;
347            M4OSA_TRACE2_0("M4READER_PCM_getNextStream: found UNKNOWN stream");
348            return M4NO_ERROR;
349    }
350
351    pAudioStreamHandler = (M4_AudioStreamHandler*)M4OSA_32bitAlignedMalloc(sizeof(M4_AudioStreamHandler),
352         M4READER_WAV, (M4OSA_Char *)"M4_AudioStreamHandler");
353    if (pAudioStreamHandler == M4OSA_NULL)
354    {
355        return M4ERR_ALLOC;
356    }
357    pAudioStreamHandler->m_structSize = sizeof(M4_AudioStreamHandler);
358    pC->m_pAudioStream = (M4_StreamHandler*)(pAudioStreamHandler);
359
360    pDsi = (M4PCMC_DecoderSpecificInfo*)(streamDesc.decoderSpecificInfo);
361    M4OSA_DEBUG_IF1((pDsi == 0), M4ERR_PARAMETER,
362         "M4READER_PCM_getNextStream: invalid decoder specific info in stream");
363
364    pAudioStreamHandler->m_samplingFrequency = pDsi->SampleFrequency;
365    pAudioStreamHandler->m_byteSampleSize    = (M4OSA_UInt32)(pDsi->BitsPerSample/8);
366    /* m_byteFrameLength is badly named: it is not in bytes but in samples number */
367    if(pAudioStreamHandler->m_samplingFrequency == 8000)
368    {
369        /* AMR case */
370        pAudioStreamHandler->m_byteFrameLength   =
371             (((streamDesc.averageBitrate/8)/50)/pDsi->nbChannels)\
372                /pAudioStreamHandler->m_byteSampleSize;/*/50 to get around 20 ms of audio*/
373    }
374    else
375    {
376        /* AAC Case */
377        pAudioStreamHandler->m_byteFrameLength =
378             (M4OSA_UInt32)(((streamDesc.averageBitrate/8)/15.625)/pDsi->nbChannels)\
379                /pAudioStreamHandler->m_byteSampleSize;
380    }
381
382    pAudioStreamHandler->m_nbChannels        = pDsi->nbChannels;
383
384    M4OSA_TIME_TO_MS( fDuration, streamDesc.duration, streamDesc.timeScale);
385    pC->m_pAudioStream->m_duration                = (M4OSA_Int32)fDuration;
386    pC->m_pAudioStream->m_pDecoderSpecificInfo    = (M4OSA_UInt8*)(streamDesc.decoderSpecificInfo);
387    pC->m_pAudioStream->m_decoderSpecificInfoSize = streamDesc.decoderSpecificInfoSize;
388    pC->m_pAudioStream->m_streamId                = streamDesc.streamID;
389    pC->m_pAudioStream->m_pUserData               =
390        (void*)streamDesc.timeScale; /*trick to change*/
391    pC->m_pAudioStream->m_averageBitRate          = streamDesc.averageBitrate;
392    pC->m_pAudioStream->m_maxAUSize               =
393         pAudioStreamHandler->m_byteFrameLength*pAudioStreamHandler->m_byteSampleSize\
394            *pAudioStreamHandler->m_nbChannels;
395    pC->m_pAudioStream->m_streamType              = M4DA_StreamTypeAudioPcm;
396
397    *pStreamHandler = pC->m_pAudioStream;
398    return err;
399}
400
401/**
402 ************************************************************************
403 * @brief   fill the access unit structure with initialization values
404 * @note
405 *
406 * @param   context:        (IN) context of the network reader
407 * @param   pStreamHandler: (IN) pointer to the stream handler to which the access unit will
408 *                                 be associated
409 * @param   pAccessUnit:    (IN) pointer to the access unit(allocated by the caller) to initialize
410 * @return  M4NO_ERROR:       there is no error.
411 * @return  M4ERR_PARAMETER:  at least one parameter is not properly set (in DEBUG only)
412 ************************************************************************
413 */
414M4OSA_ERR M4READER_PCM_fillAuStruct(M4OSA_Context context, M4_StreamHandler *pStreamHandler,
415                                     M4_AccessUnit *pAccessUnit)
416{
417    M4READER_PCM_Context*   pC = (M4READER_PCM_Context*)context;
418    M4SYS_AccessUnit*       pAu;
419
420    M4OSA_DEBUG_IF1((pC == 0),             M4ERR_PARAMETER,
421         "M4READER_PCM_fillAuStruct: invalid context");
422    M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
423         "M4READER_PCM_fillAuStruct: invalid pointer to M4_StreamHandler");
424    M4OSA_DEBUG_IF1((pAccessUnit == 0),    M4ERR_PARAMETER,
425         "M4READER_PCM_fillAuStruct: invalid pointer to M4_AccessUnit");
426
427    if (pStreamHandler == (M4_StreamHandler*)pC->m_pAudioStream)
428    {
429        pAu = &pC->m_audioAu;
430    }
431    else
432    {
433        M4OSA_TRACE1_0("M4READER_PCM_fillAuStruct: passed StreamHandler is not known");
434        return M4ERR_PARAMETER;
435    }
436
437    pAu->dataAddress = M4OSA_NULL;
438    pAu->size        = 0;
439    pAu->CTS         = 0;
440    pAu->DTS         = 0;
441    pAu->attribute   = 0;
442    pAu->nbFrag      = 0;
443
444    pAccessUnit->m_size         = 0;
445    pAccessUnit->m_CTS          = 0;
446    pAccessUnit->m_DTS          = 0;
447    pAccessUnit->m_attribute    = 0;
448    pAccessUnit->m_dataAddress  = M4OSA_NULL;/*pBuffer;*/
449    pAccessUnit->m_maxsize      = pStreamHandler->m_maxAUSize;
450    pAccessUnit->m_streamID     = pStreamHandler->m_streamId;
451    pAccessUnit->m_structSize   = sizeof(M4_AccessUnit);
452
453    return M4NO_ERROR;
454}
455
456/**
457 ************************************************************************
458 * @brief   reset the stream, that is: seek it to beginning and make it ready to be read
459 * @note
460 * @param   context:        (IN) context of the network reader
461 * @param   pStreamHandler: (IN) The stream handler of the stream to reset
462 * @return  M4NO_ERROR: there is no error.
463 ************************************************************************
464 */
465M4OSA_ERR M4READER_PCM_reset(M4OSA_Context context, M4_StreamHandler *pStreamHandler)
466{
467    M4READER_PCM_Context*   pC = (M4READER_PCM_Context*)context;
468    M4SYS_StreamID          streamIdArray[2];
469    M4OSA_ERR               err;
470    M4SYS_AccessUnit*       pAu;
471    M4OSA_Time                time64 = 0;
472
473    M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER, "M4READER_PCM_reset: invalid context");
474    M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
475         "M4READER_PCM_reset: invalid pointer to M4_StreamHandler");
476
477    if (pStreamHandler == (M4_StreamHandler*)pC->m_pAudioStream)
478    {
479        pAu = &pC->m_audioAu;
480    }
481    else
482    {
483        M4OSA_TRACE1_0("M4READER_PCM_reset: passed StreamHandler is not known");
484        return M4ERR_PARAMETER;
485    }
486
487    if (pAu->dataAddress != M4OSA_NULL)
488    {
489        err = M4PCMR_freeAU(pC->m_coreContext, pStreamHandler->m_streamId, pAu);
490        if (err != M4NO_ERROR)
491        {
492            M4OSA_TRACE1_0("M4READER_PCM_reset: error when freeing access unit");
493            return err;
494        }
495        pAu->dataAddress = M4OSA_NULL;
496    }
497
498    streamIdArray[0] = pStreamHandler->m_streamId;
499    streamIdArray[1] = 0;
500
501    pAu->CTS = 0;
502    pAu->DTS = 0;
503
504    /* This call is needed only when replay during playback */
505    err = M4PCMR_seek(pC->m_coreContext, streamIdArray, time64, M4SYS_kBeginning, &time64);
506
507    return err;
508}
509
510/**
511 ************************************************************************
512 * @brief   Get the next access unit of the specified stream
513 * @note
514 * @param   context:        (IN)        Context of the reader
515 * @param   pStreamHandler  (IN)        The stream handler of the stream to make jump
516 * @param   pAccessUnit     (IN/OUT)    Pointer to an access unit to fill with read data
517 *                                      (the au structure is allocated by the user, and must be
518 *                                        initialized
519 *                                      by calling M4READER_fillAuStruct_fct after creation)
520 * @return  M4NO_ERROR                  there is no error
521 * @return  M4ERR_BAD_CONTEXT           provided context is not a valid one
522 * @return  M4ERR_PARAMETER             at least one parameter is not properly set
523 * @returns M4ERR_ALLOC                 memory allocation failed
524 * @returns M4ERR_BAD_STREAM_ID         at least one of the stream Id. does not exist.
525 * @returns M4WAR_NO_DATA_YET           there is no enough data on the stream for new access unit
526 * @returns M4WAR_NO_MORE_AU            there are no more access unit in the stream (end of stream)
527 ************************************************************************
528 */
529M4OSA_ERR M4READER_PCM_getNextAu(M4OSA_Context context, M4_StreamHandler *pStreamHandler,
530                                 M4_AccessUnit *pAccessUnit)
531{
532    M4READER_PCM_Context*   pC = (M4READER_PCM_Context*)context;
533    M4OSA_ERR               err = M4NO_ERROR;
534    M4SYS_AccessUnit*       pAu;
535
536    M4OSA_DEBUG_IF1((pC == 0),             M4ERR_PARAMETER,
537         "M4READER_PCM_getNextAu: invalid context");
538    M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
539         "M4READER_PCM_getNextAu: invalid pointer to M4_StreamHandler");
540    M4OSA_DEBUG_IF1((pAccessUnit == 0),    M4ERR_PARAMETER,
541         "M4READER_PCM_getNextAu: invalid pointer to M4_AccessUnit");
542
543    /* keep trace of the allocated buffers in AU to be able to free them at destroy()
544       but be aware that system is risky and would need upgrade if more than
545       one video and one audio AU is needed */
546    if (pStreamHandler == (M4_StreamHandler*)pC->m_pAudioStream)
547    {
548        pAu = &pC->m_audioAu;
549    }
550    else
551    {
552        M4OSA_TRACE1_0("M4READER_PCM_getNextAu: passed StreamHandler is not known");
553        return M4ERR_PARAMETER;
554    }
555
556    if (pAu->dataAddress != M4OSA_NULL)
557    {
558        err = M4PCMR_freeAU(pC->m_coreContext, pStreamHandler->m_streamId, pAu);
559        if (err != M4NO_ERROR)
560        {
561            M4OSA_TRACE1_0("M4READER_PCM_getNextAu: error when freeing access unit");
562            return err;
563        }
564    }
565
566    pAu->nbFrag = 0;
567    err = M4PCMR_nextAU(pC->m_coreContext, pStreamHandler->m_streamId, pAu);
568
569    if (err == M4NO_ERROR)
570    {
571        pAccessUnit->m_dataAddress = (M4OSA_MemAddr8)pAu->dataAddress;
572        pAccessUnit->m_size = pAu->size;
573        pAccessUnit->m_CTS  = (M4OSA_Double)pAu->CTS;
574        pAccessUnit->m_DTS  = (M4OSA_Double)pAu->DTS;
575        pAccessUnit->m_attribute = pAu->attribute;
576    }
577    else
578    {
579        pAccessUnit->m_size=0;
580    }
581
582    return err;
583}
584
585
586/**
587 ************************************************************************
588 * @brief   jump into the stream at the specified time
589 * @note
590 * @param   context:        (IN)     Context of the reader
591 * @param   pStreamHandler  (IN)     the stream handler of the stream to make jump
592 * @param   pTime           (IN/OUT) IN:  the time to jump to (in ms)
593 *                                   OUT: the time to which the stream really jumped
594 *                                        But in this reader, we do not modify the time
595 * @return  M4NO_ERROR              there is no error
596 * @return  M4ERR_BAD_CONTEXT       provided context is not a valid one
597 * @return  M4ERR_PARAMETER         at least one parameter is not properly set
598 * @return  M4ERR_ALLOC             there is no more memory available
599 * @return  M4ERR_BAD_STREAM_ID     the streamID does not exist
600 ************************************************************************
601 */
602M4OSA_ERR M4READER_PCM_jump(M4OSA_Context context, M4_StreamHandler *pStreamHandler,
603     M4OSA_Int32* pTime)
604{
605    M4READER_PCM_Context*   pC = (M4READER_PCM_Context*)context;
606    M4SYS_StreamID          streamIdArray[2];
607    M4OSA_ERR               err;
608    M4SYS_AccessUnit*       pAu;
609    M4OSA_Time                time64;
610
611    M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER, "M4READER_PCM_jump: invalid context");
612    M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
613         "M4READER_PCM_jump: invalid pointer to M4_StreamHandler");
614    M4OSA_DEBUG_IF1((pTime == 0), M4ERR_PARAMETER, "M4READER_PCM_jump: invalid time pointer");
615
616    time64 = (M4OSA_Time)*pTime;
617
618    if (pStreamHandler == pC->m_pAudioStream)
619    {
620        pAu = &pC->m_audioAu;
621    }
622    else
623    {
624        M4OSA_TRACE1_0("M4READER_PCM_jump: passed StreamHandler is not known");
625        return M4ERR_PARAMETER;
626    }
627
628    if (pAu->dataAddress != M4OSA_NULL)
629    {
630        err = M4PCMR_freeAU(pC->m_coreContext, pStreamHandler->m_streamId, pAu);
631        if (err != M4NO_ERROR)
632        {
633            M4OSA_TRACE1_0("M4READER_PCM_jump: Error when freeing access unit");
634            return err;
635        }
636        pAu->dataAddress = M4OSA_NULL;
637    }
638
639    streamIdArray[0] = pStreamHandler->m_streamId;
640    streamIdArray[1] = 0;
641
642    pAu->CTS = time64;
643    pAu->DTS = time64;
644
645    err = M4PCMR_seek(pC->m_coreContext, streamIdArray, time64, M4SYS_kBeginning, &time64);
646
647    *pTime = (M4OSA_Int32)time64;
648
649    return err;
650}
651
652/**
653 *************************************************************************
654 * @brief Retrieves the generic interfaces implemented by the reader
655 *
656 * @param pMediaType          : Pointer on a M4READER_MediaType (allocated by the caller)
657 *                              that will be filled with the media type supported by this reader
658 * @param pRdrGlobalInterface : Address of a pointer that will be set to the global interface
659 *                              implemented by this reader. The interface is a structure allocated
660 *                              by the function and must be un-allocated by the caller.
661 * @param pRdrDataInterface   : Address of a pointer that will be set to the data interface
662 *                              implemented by this reader. The interface is a structure allocated
663 *                              by the function and must be un-allocated by the caller.
664 *
665 * @returns : M4NO_ERROR     if OK
666 *            ERR_ALLOC      if an allocation failed
667 *            ERR_PARAMETER  at least one parameter is not properly set (in DEBUG only)
668 *************************************************************************
669 */
670M4OSA_ERR   M4READER_PCM_getInterfaces(M4READER_MediaType *pMediaType,
671                                       M4READER_GlobalInterface **pRdrGlobalInterface,
672                                       M4READER_DataInterface **pRdrDataInterface)
673/************************************************************************/
674{
675    M4OSA_DEBUG_IF1((pMediaType == 0),          M4ERR_PARAMETER,
676         "M4READER_PCM_getInterfaces: invalid pointer to MediaType passed");
677    M4OSA_DEBUG_IF1((pRdrGlobalInterface == 0), M4ERR_PARAMETER,
678         "M4READER_PCM_getInterfaces: invalid pointer to M4READER_GlobalInterface");
679    M4OSA_DEBUG_IF1((pRdrDataInterface == 0),   M4ERR_PARAMETER,
680         "M4READER_PCM_getInterfaces: invalid pointer to M4READER_DataInterface");
681
682    *pRdrGlobalInterface =
683         (M4READER_GlobalInterface*)M4OSA_32bitAlignedMalloc( sizeof(M4READER_GlobalInterface), M4READER_WAV,
684             (M4OSA_Char *)"M4READER_PCM GlobalInterface");
685    if (M4OSA_NULL == *pRdrGlobalInterface)
686    {
687        return M4ERR_ALLOC;
688    }
689    *pRdrDataInterface =
690         (M4READER_DataInterface*)M4OSA_32bitAlignedMalloc( sizeof(M4READER_DataInterface), M4READER_WAV,
691            (M4OSA_Char *) "M4READER_PCM DataInterface");
692    if (M4OSA_NULL == *pRdrDataInterface)
693    {
694        free(*pRdrGlobalInterface);
695        return M4ERR_ALLOC;
696    }
697
698    *pMediaType = M4READER_kMediaTypePCM;
699
700    (*pRdrGlobalInterface)->m_pFctCreate           = M4READER_PCM_create;
701    (*pRdrGlobalInterface)->m_pFctDestroy          = M4READER_PCM_destroy;
702    (*pRdrGlobalInterface)->m_pFctOpen             = M4READER_PCM_open;
703    (*pRdrGlobalInterface)->m_pFctClose            = M4READER_PCM_close;
704    (*pRdrGlobalInterface)->m_pFctStart            = M4OSA_NULL;
705    (*pRdrGlobalInterface)->m_pFctStop             = M4OSA_NULL;
706    (*pRdrGlobalInterface)->m_pFctGetOption        = M4READER_PCM_getOption;
707    (*pRdrGlobalInterface)->m_pFctSetOption        = M4READER_PCM_setOption;
708    (*pRdrGlobalInterface)->m_pFctGetNextStream    = M4READER_PCM_getNextStream;
709    (*pRdrGlobalInterface)->m_pFctFillAuStruct     = M4READER_PCM_fillAuStruct;
710    (*pRdrGlobalInterface)->m_pFctJump             = M4READER_PCM_jump;
711    (*pRdrGlobalInterface)->m_pFctReset            = M4READER_PCM_reset;
712    (*pRdrGlobalInterface)->m_pFctGetPrevRapTime   = M4OSA_NULL; /*all AUs are RAP*/
713
714    (*pRdrDataInterface)->m_pFctGetNextAu          = M4READER_PCM_getNextAu;
715
716    (*pRdrDataInterface)->m_readerContext = M4OSA_NULL;
717
718    return M4NO_ERROR;
719}
720
721
722