VideoEditor3gpReader.cpp revision 53f69c194d7ae8105b4c6d0c9901eb96281c7bf9
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   VideoEditor3gpReader.cpp
19* @brief  StageFright shell 3GP Reader
20*************************************************************************
21*/
22
23#define LOG_NDEBUG 1
24#define LOG_TAG "VIDEOEDITOR_3GPREADER"
25
26/**
27 * HEADERS
28 *
29 */
30#define VIDEOEDITOR_BITSTREAM_PARSER
31
32#include "M4OSA_Debug.h"
33#include "VideoEditor3gpReader.h"
34#include "M4SYS_AccessUnit.h"
35#include "VideoEditorUtils.h"
36#include "M4READER_3gpCom.h"
37#include "M4_Common.h"
38#include "M4OSA_FileWriter.h"
39
40#ifdef VIDEOEDITOR_BITSTREAM_PARSER
41#include "M4OSA_CoreID.h"
42#include "M4OSA_Error.h"
43#include "M4OSA_Memory.h"
44#include "M4_Utils.h"
45#endif
46
47#include "ESDS.h"
48#include "utils/Log.h"
49#include <media/stagefright/foundation/ADebug.h>
50#include <media/stagefright/MediaBufferGroup.h>
51#include <media/stagefright/DataSource.h>
52#include <media/stagefright/FileSource.h>
53#include <media/stagefright/MediaBuffer.h>
54#include <media/stagefright/MediaDefs.h>
55#include <media/stagefright/MediaExtractor.h>
56#include <media/stagefright/MediaSource.h>
57#include <media/stagefright/MetaData.h>
58
59/**
60 * SOURCE CLASS
61 */
62namespace android {
63/**
64 * ENGINE INTERFACE
65 */
66
67/**
68 ************************************************************************
69 * @brief   Array of AMR NB/WB bitrates
70 * @note    Array to match the mode and the bit rate
71 ************************************************************************
72*/
73const M4OSA_UInt32 VideoEditor3gpReader_AmrBitRate [2 /* 8kHz / 16kHz     */]
74                                                   [9 /* the bitrate mode */] =
75{
76    {4750, 5150, 5900,  6700,  7400,  7950,  10200, 12200, 0},
77    {6600, 8850, 12650, 14250, 15850, 18250, 19850, 23050, 23850}
78};
79
80/**
81 *******************************************************************************
82 * structure VideoEditor3gpReader_Context
83 * @brief:This structure defines the context of the StageFright 3GP shell Reader
84 *******************************************************************************
85*/
86typedef struct {
87    sp<DataSource>              mDataSource;
88    sp<MediaExtractor>          mExtractor;
89    sp<MediaSource>             mAudioSource;
90    sp<MediaSource>             mVideoSource;
91    M4_StreamHandler*           mAudioStreamHandler;
92    M4_StreamHandler*           mVideoStreamHandler;
93    M4SYS_AccessUnit            mAudioAu;
94    M4SYS_AccessUnit            mVideoAu;
95    M4OSA_Time                  mMaxDuration;
96    int64_t                     mFileSize;
97    M4_StreamType               mStreamType;
98    M4OSA_UInt32                mStreamId;
99    int32_t                     mTracks;
100    int32_t                     mCurrTrack;
101    M4OSA_Bool                  mAudioSeeking;
102    M4OSA_Time                  mAudioSeekTime;
103    M4OSA_Bool                  mVideoSeeking;
104    M4OSA_Time                  mVideoSeekTime;
105
106} VideoEditor3gpReader_Context;
107
108#ifdef VIDEOEDITOR_BITSTREAM_PARSER
109/**
110 ************************************************************************
111 * structure    VideoEditor3gpReader_BitStreamParserContext
112 * @brief       Internal BitStreamParser context
113 ************************************************************************
114*/
115typedef struct {
116    M4OSA_UInt32*   mPbitStream;   /**< bitstream pointer (32bits aligned) */
117    M4OSA_Int32     mSize;         /**< bitstream size in bytes */
118    M4OSA_Int32     mIndex;        /**< byte index */
119    M4OSA_Int32     mBitIndex;     /**< bit index */
120    M4OSA_Int32     mStructSize;   /**< size of structure */
121} VideoEditor3gpReader_BitStreamParserContext;
122
123/**
124 *******************************************************************************
125 * @brief   Allocates the context and initializes internal data.
126 * @param   pContext    (OUT)  Pointer to the BitStreamParser context to create.
127 * @param   bitStream   A pointer to the bitstream
128 * @param   size        The size of the bitstream in bytes
129 *******************************************************************************
130*/
131static void VideoEditor3gpReader_BitStreamParserInit(void** pContext,
132        void* pBitStream, M4OSA_Int32 size) {
133    VideoEditor3gpReader_BitStreamParserContext* pStreamContext;
134
135    *pContext=M4OSA_NULL;
136    pStreamContext = (VideoEditor3gpReader_BitStreamParserContext*)M4OSA_32bitAlignedMalloc(
137        sizeof(VideoEditor3gpReader_BitStreamParserContext), M4READER_3GP,
138            (M4OSA_Char*)"3GP BitStreamParser Context");
139    if (M4OSA_NULL == pStreamContext) {
140        return;
141    }
142    pStreamContext->mPbitStream=(M4OSA_UInt32*)pBitStream;
143    pStreamContext->mSize=size;
144    pStreamContext->mIndex=0;
145    pStreamContext->mBitIndex=0;
146    pStreamContext->mStructSize =
147        sizeof(VideoEditor3gpReader_BitStreamParserContext);
148
149    *pContext=pStreamContext;
150}
151/**
152 **********************************************************************
153 * @brief   Clean up context
154 * @param   pContext    (IN/OUT)  BitStreamParser context.
155 **********************************************************************
156*/
157static void VideoEditor3gpReader_BitStreamParserCleanUp(void* pContext) {
158    free((M4OSA_Int32*)pContext);
159}
160/**
161 *****************************************************************************
162 * @brief   Read the next <length> bits in the bitstream.
163 * @note    The function does not update the bitstream pointer.
164 * @param   pContext    (IN/OUT) BitStreamParser context.
165 * @param   length      (IN) The number of bits to extract from the bitstream
166 * @return  the read bits
167 *****************************************************************************
168*/
169static M4OSA_UInt32 VideoEditor3gpReader_BitStreamParserShowBits(void* pContext,
170        M4OSA_Int32 length) {
171    VideoEditor3gpReader_BitStreamParserContext* pStreamContext =
172        (VideoEditor3gpReader_BitStreamParserContext*)pContext;
173
174    M4OSA_UInt32 u_mask;
175    M4OSA_UInt32 retval;
176    M4OSA_Int32 i_ovf;
177
178    M4OSA_DEBUG_IF1((M4OSA_NULL==pStreamContext), 0,
179        "VideoEditor3gpReader_BitStreamParserShowBits:invalid context pointer");
180
181    retval=(M4OSA_UInt32)GET_MEMORY32(pStreamContext->\
182        mPbitStream[ pStreamContext->mIndex ]);
183    i_ovf = pStreamContext->mBitIndex + length - 32;
184    u_mask = (length >= 32) ? 0xffffffff: (1 << length) - 1;
185
186    /* do we have enough bits availble in the current word(32bits)*/
187    if (i_ovf <= 0) {
188        retval=(retval >> (- i_ovf)) & u_mask;
189    } else {
190        M4OSA_UInt32 u_nextword = (M4OSA_UInt32)GET_MEMORY32(
191            pStreamContext->mPbitStream[ pStreamContext->mIndex + 1 ]);
192        M4OSA_UInt32 u_msb_mask, u_msb_value, u_lsb_mask, u_lsb_value;
193
194        u_msb_mask = ((1 << (32 - pStreamContext->mBitIndex)) - 1) << i_ovf;
195        u_msb_value = retval << i_ovf;
196        u_lsb_mask = (1 << i_ovf) - 1;
197        u_lsb_value = u_nextword >> (32 - i_ovf);
198        retval= (u_msb_value & u_msb_mask ) | (u_lsb_value & u_lsb_mask);
199    }
200    /* return the bits...*/
201    return retval;
202}
203/**
204 ************************************************************************
205 * @brief   Increment the bitstream pointer of <length> bits.
206 * @param   pContext    (IN/OUT) BitStreamParser context.
207 * @param   length      (IN) The number of bit to shift the bitstream
208 ************************************************************************
209*/
210static void VideoEditor3gpReader_BitStreamParserFlushBits(void* pContext,
211        M4OSA_Int32 length) {
212    VideoEditor3gpReader_BitStreamParserContext* pStreamContext=(
213        VideoEditor3gpReader_BitStreamParserContext*)pContext;
214    M4OSA_Int32 val;
215
216    if (M4OSA_NULL == pStreamContext) {
217        return;
218    }
219    val=pStreamContext->mBitIndex + length;
220    /* update the bits...*/
221    pStreamContext->mBitIndex += length;
222
223    if (val - 32 >= 0) {
224        /* update the bits...*/
225        pStreamContext->mBitIndex -= 32;
226        /* update the words*/
227        pStreamContext->mIndex++;
228    }
229}
230
231static M4OSA_UInt32 VideoEditor3gpReader_BitStreamParserGetBits(
232        void* pContext,M4OSA_Int32 bitPos, M4OSA_Int32 bitLength) {
233    VideoEditor3gpReader_BitStreamParserContext* pStreamContext =
234        (VideoEditor3gpReader_BitStreamParserContext*)pContext;
235
236    M4OSA_Int32 bitLocation, bitIndex;
237    M4OSA_UInt32 retval=0;
238
239    M4OSA_DEBUG_IF1((M4OSA_NULL==pStreamContext), 0,
240        "VideoEditor3gpReader_BitStreamParserGetBits: invalid context pointer");
241
242    /* computes the word location*/
243    bitLocation=bitPos/32;
244    bitIndex=(bitPos) % 32;
245
246    if (bitLocation < pStreamContext->mSize) {
247        M4OSA_UInt32 u_mask;
248        M4OSA_Int32 i_ovf = bitIndex + bitLength - 32;
249        retval=(M4OSA_UInt32)GET_MEMORY32(
250            pStreamContext->mPbitStream[ bitLocation ]);
251
252        u_mask = (bitLength >= 32) ? 0xffffffff: (1 << bitLength) - 1;
253
254        if (i_ovf <= 0) {
255            retval=(retval >> (- i_ovf)) & u_mask;
256        } else {
257            M4OSA_UInt32 u_nextword = (M4OSA_UInt32)GET_MEMORY32(
258                pStreamContext->mPbitStream[ bitLocation + 1 ]);
259            M4OSA_UInt32 u_msb_mask, u_msb_value, u_lsb_mask, u_lsb_value;
260
261            u_msb_mask = ((1 << (32 - bitIndex)) - 1) << i_ovf;
262            u_msb_value = retval << i_ovf;
263            u_lsb_mask = (1 << i_ovf) - 1;
264            u_lsb_value = u_nextword >> (32 - i_ovf);
265            retval= (u_msb_value & u_msb_mask ) | (u_lsb_value & u_lsb_mask);
266        }
267    }
268    return retval;
269}
270
271static void VideoEditor3gpReader_BitStreamParserRestart(void* pContext) {
272    VideoEditor3gpReader_BitStreamParserContext* pStreamContext =
273        (VideoEditor3gpReader_BitStreamParserContext*)pContext;
274
275    if (M4OSA_NULL == pStreamContext) {
276        return;
277    }
278    /* resets the bitstream pointers*/
279    pStreamContext->mIndex=0;
280    pStreamContext->mBitIndex=0;
281}
282/**
283 *******************************************************************************
284 * @brief  Get a pointer to the current byte pointed by the bitstream pointer.
285 * @note   It should be used carefully as the pointer is in the bitstream itself
286 *         and no copy is made.
287 * @param  pContext    (IN/OUT)  BitStreamParser context.
288 * @return Pointer to the current location in the bitstream
289 *******************************************************************************
290*/
291static M4OSA_UInt8*  VideoEditor3gpReader_GetCurrentbitStreamPointer(
292        void* pContext) {
293    VideoEditor3gpReader_BitStreamParserContext* pStreamContext =
294        (VideoEditor3gpReader_BitStreamParserContext*)pContext;
295    M4OSA_DEBUG_IF1((M4OSA_NULL==pStreamContext), 0, "invalid context pointer");
296
297    return (M4OSA_UInt8*)((M4OSA_UInt8*)pStreamContext->mPbitStream + \
298        pStreamContext->mIndex * sizeof(M4OSA_UInt32) + \
299        pStreamContext->mBitIndex/8) ;
300}
301
302static M4OSA_Int32 VideoEditor3gpReader_BitStreamParserGetSize(void* pContext) {
303    VideoEditor3gpReader_BitStreamParserContext* pStreamContext =
304        (VideoEditor3gpReader_BitStreamParserContext*)pContext;
305    M4OSA_DEBUG_IF1((M4OSA_NULL==pStreamContext), 0, "invalid context pointer");
306
307    return pStreamContext->mSize;
308}
309
310
311static void VideoEditor3gpReader_MPEG4BitStreamParserInit(void** pContext,
312        void* pBitStream, M4OSA_Int32 size) {
313    VideoEditor3gpReader_BitStreamParserInit(pContext, pBitStream, size);
314}
315static M4OSA_Int32 VideoEditor3gpReader_GetMpegLengthFromInteger(void* pContext,
316        M4OSA_UInt32 val) {
317    M4OSA_UInt32 length=0;
318    M4OSA_UInt32 numBytes=0;
319    M4OSA_UInt32 b=0;
320
321    M4OSA_DEBUG_IF1((M4OSA_NULL==pContext), 0, "invalid context pointer");
322
323    /* the length is encoded as a sequence of bytes. The highest bit is used
324    to indicate that the length continues on the next byte.
325
326    The length can be: 0x80 0x80 0x80 0x22
327    of just            0x22 (highest bit not set)
328
329    */
330
331    do {
332        b=(val & ((0xff)<< (8 * numBytes)))>> (8 * numBytes);
333        length=(length << 7) | (b & 0x7f);
334        numBytes++;
335    } while ((b & 0x80) && numBytes < 4);
336
337    return length;
338}
339
340/**
341 *******************************************************************************
342 * @brief  Decode an MPEG4 Systems descriptor size from an encoded SDL size data
343 * @note   The value is read from the current bitstream location.
344 * @param  pContext    (IN/OUT)  BitStreamParser context.
345 * @return Size in a human readable form
346 *******************************************************************************
347*/
348static M4OSA_Int32 VideoEditor3gpReader_GetMpegLengthFromStream(void* pContext){
349    M4OSA_UInt32 length=0;
350    M4OSA_UInt32 numBytes=0;
351    M4OSA_UInt32 b=0;
352
353    M4OSA_DEBUG_IF1((M4OSA_NULL==pContext), 0, "invalid context pointer");
354
355    /* the length is encoded as a sequence of bytes. The highest bit is used
356    to indicate that the length continues on the next byte.
357
358    The length can be: 0x80 0x80 0x80 0x22
359    of just            0x22 (highest bit not set)
360    */
361
362    do {
363        b=VideoEditor3gpReader_BitStreamParserShowBits(pContext, 8);
364        VideoEditor3gpReader_BitStreamParserFlushBits(pContext, 8);
365        length=(length << 7) | (b & 0x7f);
366        numBytes++;
367    } while ((b & 0x80) && numBytes < 4);
368
369    return length;
370}
371#endif /* VIDEOEDITOR_BITSTREAM_PARSER */
372/**
373************************************************************************
374* @brief    create an instance of the 3gp reader
375 * @note    allocates the context
376 *
377 * @param   pContext:       (OUT)   pointer on a reader context
378 *
379 * @return  M4NO_ERROR              there is no error
380 * @return  M4ERR_ALLOC             a memory allocation has failed
381 * @return  M4ERR_PARAMETER         at least one parameter is not valid
382************************************************************************
383*/
384
385M4OSA_ERR VideoEditor3gpReader_create(M4OSA_Context *pContext) {
386    VideoEditor3gpReader_Context* pC = NULL;
387    M4OSA_ERR err = M4NO_ERROR;
388    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext , M4ERR_PARAMETER);
389
390    ALOGV("VideoEditor3gpReader_create begin");
391
392    /* Context allocation & initialization */
393    SAFE_MALLOC(pC, VideoEditor3gpReader_Context, 1, "VideoEditor3gpReader");
394
395    memset(pC, sizeof(VideoEditor3gpReader_Context), 0);
396
397    pC->mAudioStreamHandler  = M4OSA_NULL;
398    pC->mAudioAu.dataAddress = M4OSA_NULL;
399    pC->mVideoStreamHandler  = M4OSA_NULL;
400    pC->mVideoAu.dataAddress = M4OSA_NULL;
401
402    pC->mAudioSeeking = M4OSA_FALSE;
403    pC->mAudioSeekTime = 0;
404
405    pC->mVideoSeeking = M4OSA_FALSE;
406    pC->mVideoSeekTime = 0;
407
408    pC->mMaxDuration = 0;
409
410    *pContext=pC;
411
412cleanUp:
413    if ( M4NO_ERROR == err ) {
414        ALOGV("VideoEditor3gpReader_create no error");
415    } else {
416        ALOGV("VideoEditor3gpReader_create ERROR 0x%X", err);
417    }
418    ALOGV("VideoEditor3gpReader_create end ");
419    return err;
420}
421
422/**
423**************************************************************************
424* @brief    destroy the instance of the 3gp reader
425* @note after this call the context is invalid
426* @param    context:        (IN)    Context of the reader
427* @return   M4NO_ERROR              there is no error
428* @return   M4ERR_PARAMETER         pContext parameter is not properly set
429**************************************************************************
430*/
431
432M4OSA_ERR VideoEditor3gpReader_destroy(M4OSA_Context pContext) {
433    M4OSA_ERR err = M4NO_ERROR;
434    VideoEditor3gpReader_Context* pC = M4OSA_NULL;
435
436    ALOGV("VideoEditor3gpReader_destroy begin");
437
438    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
439    pC = (VideoEditor3gpReader_Context*)pContext;
440
441    SAFE_FREE(pC->mAudioAu.dataAddress);
442    pC->mAudioAu.dataAddress = M4OSA_NULL;
443    SAFE_FREE(pC->mVideoAu.dataAddress);
444    pC->mVideoAu.dataAddress = M4OSA_NULL;
445    SAFE_FREE(pC);
446    pContext = M4OSA_NULL;
447
448cleanUp:
449    if( M4NO_ERROR == err ) {
450        ALOGV("VideoEditor3gpReader_destroy no error");
451    }
452    else
453    {
454        ALOGV("VideoEditor3gpReader_destroy ERROR 0x%X", err);
455    }
456
457    ALOGV("VideoEditor3gpReader_destroy end ");
458    return err;
459}
460
461/**
462************************************************************************
463* @brief    open the reader and initializes its created instance
464* @note     this function open the media file
465* @param    context:            (IN)    Context of the reader
466* @param    pFileDescriptor:    (IN)    Pointer to proprietary data identifying
467*                                       the media to open
468* @return   M4NO_ERROR                  there is no error
469* @return   M4ERR_PARAMETER             the context is NULL
470* @return   M4ERR_UNSUPPORTED_MEDIA_TYPE
471*                                       the media is DRM protected
472************************************************************************
473*/
474
475M4OSA_ERR VideoEditor3gpReader_open(M4OSA_Context pContext,
476        M4OSA_Void* pFileDescriptor) {
477    VideoEditor3gpReader_Context* pC = (VideoEditor3gpReader_Context*)pContext;
478    M4OSA_ERR err = M4NO_ERROR;
479
480    ALOGV("VideoEditor3gpReader_open start ");
481    M4OSA_DEBUG_IF1((M4OSA_NULL == pC),  M4ERR_PARAMETER,
482        "VideoEditor3gpReader_open: invalid context pointer");
483    M4OSA_DEBUG_IF1((M4OSA_NULL == pFileDescriptor), M4ERR_PARAMETER,
484        "VideoEditor3gpReader_open: invalid pointer pFileDescriptor");
485
486    ALOGV("VideoEditor3gpReader_open Datasource start %s",
487        (char*)pFileDescriptor);
488    //pC->mDataSource = DataSource::CreateFromURI((char*)pFileDescriptor);
489    pC->mDataSource = new FileSource ((char*)pFileDescriptor);
490
491    if (pC->mDataSource == NULL) {
492        ALOGV("VideoEditor3gpReader_open Datasource error");
493        return M4ERR_PARAMETER;
494    }
495
496    pC->mExtractor = MediaExtractor::Create(pC->mDataSource,
497        MEDIA_MIMETYPE_CONTAINER_MPEG4);
498
499    if (pC->mExtractor == NULL) {
500        ALOGV("VideoEditor3gpReader_open extractor error");
501        return M4ERR_PARAMETER;
502    }
503
504    int32_t isDRMProtected = 0;
505    sp<MetaData> meta = pC->mExtractor->getMetaData();
506    meta->findInt32(kKeyIsDRM, &isDRMProtected);
507    if (isDRMProtected) {
508        ALOGV("VideoEditorMp3Reader_open error - DRM Protected");
509        return M4ERR_UNSUPPORTED_MEDIA_TYPE;
510    }
511
512    ALOGV("VideoEditor3gpReader_open end ");
513    return err;
514}
515
516/**
517************************************************************************
518* @brief    close the reader
519* @note     close the 3GP file
520* @param    context:        (IN)    Context of the reader
521* @return   M4NO_ERROR              there is no error
522* @return   M4ERR_PARAMETER         the context is NULL
523* @return   M4ERR_BAD_CONTEXT       provided context is not a valid one
524************************************************************************
525*/
526M4OSA_ERR VideoEditor3gpReader_close(M4OSA_Context context) {
527    VideoEditor3gpReader_Context *pC = (VideoEditor3gpReader_Context*)context;
528    M4READER_AudioSbrUserdata *pAudioSbrUserData;
529    M4_AccessUnit *pAU;
530    M4OSA_ERR err = M4NO_ERROR;
531
532    ALOGV("VideoEditor3gpReader_close begin");
533
534    M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER,
535        "VideoEditor3gpReader_close: invalid context pointer");
536
537    if (pC->mAudioStreamHandler) {
538        ALOGV("VideoEditor3gpReader_close Audio");
539
540        if (M4OSA_NULL != pC->mAudioStreamHandler->m_pDecoderSpecificInfo) {
541            free(pC->mAudioStreamHandler->\
542                m_pDecoderSpecificInfo);
543            pC->mAudioStreamHandler->m_decoderSpecificInfoSize = 0;
544            pC->mAudioStreamHandler->m_pDecoderSpecificInfo = M4OSA_NULL;
545        }
546
547        if ((M4DA_StreamTypeAudioAac == pC->mAudioStreamHandler->m_streamType)
548            && (M4OSA_NULL != pC->mAudioStreamHandler->m_pUserData)) {
549            pAudioSbrUserData = (M4READER_AudioSbrUserdata*)(\
550                pC->mAudioStreamHandler->m_pUserData);
551
552            pAU = (M4_AccessUnit*)pAudioSbrUserData->m_pFirstAU;
553            if (M4OSA_NULL != pAU) {
554                free(pAU);
555            }
556
557            if (M4OSA_NULL != pAudioSbrUserData->m_pAacDecoderUserConfig) {
558                free(pAudioSbrUserData->\
559                    m_pAacDecoderUserConfig);
560            }
561            free(pAudioSbrUserData);
562            pC->mAudioStreamHandler->m_pUserData = M4OSA_NULL;
563        }
564
565        if (pC->mAudioStreamHandler->m_pESDSInfo != M4OSA_NULL) {
566            free(pC->mAudioStreamHandler->m_pESDSInfo);
567            pC->mAudioStreamHandler->m_pESDSInfo = M4OSA_NULL;
568            pC->mAudioStreamHandler->m_ESDSInfoSize = 0;
569        }
570        /* Finally destroy the stream handler */
571        free(pC->mAudioStreamHandler);
572        pC->mAudioStreamHandler = M4OSA_NULL;
573
574        pC->mAudioSource->stop();
575        pC->mAudioSource.clear();
576    }
577    if (pC->mVideoStreamHandler) {
578        ALOGV("VideoEditor3gpReader_close Video ");
579
580        if(M4OSA_NULL != pC->mVideoStreamHandler->m_pDecoderSpecificInfo) {
581            free(pC->mVideoStreamHandler->\
582                m_pDecoderSpecificInfo);
583            pC->mVideoStreamHandler->m_decoderSpecificInfoSize = 0;
584            pC->mVideoStreamHandler->m_pDecoderSpecificInfo = M4OSA_NULL;
585        }
586
587        if(M4OSA_NULL != pC->mVideoStreamHandler->m_pH264DecoderSpecificInfo) {
588            free(pC->mVideoStreamHandler->\
589                m_pH264DecoderSpecificInfo);
590            pC->mVideoStreamHandler->m_H264decoderSpecificInfoSize = 0;
591            pC->mVideoStreamHandler->m_pH264DecoderSpecificInfo = M4OSA_NULL;
592        }
593
594        if(pC->mVideoStreamHandler->m_pESDSInfo != M4OSA_NULL) {
595            free(pC->mVideoStreamHandler->m_pESDSInfo);
596            pC->mVideoStreamHandler->m_pESDSInfo = M4OSA_NULL;
597            pC->mVideoStreamHandler->m_ESDSInfoSize = 0;
598        }
599
600        /* Finally destroy the stream handler */
601        free(pC->mVideoStreamHandler);
602        pC->mVideoStreamHandler = M4OSA_NULL;
603
604        pC->mVideoSource->stop();
605        pC->mVideoSource.clear();
606    }
607    pC->mExtractor.clear();
608    pC->mDataSource.clear();
609
610    ALOGV("VideoEditor3gpReader_close end");
611    return err;
612}
613
614/**
615************************************************************************
616* @brief    get an option from the 3gp reader
617* @note     it allows the caller to retrieve a property value:
618*
619* @param    context:        (IN)    Context of the reader
620* @param    optionId:       (IN)    indicates the option to get
621* @param    pValue:         (OUT)   pointer to structure or value (allocated
622*                                   by user) where option is stored
623*
624* @return   M4NO_ERROR              there is no error
625* @return   M4ERR_BAD_CONTEXT       provided context is not a valid one
626* @return   M4ERR_PARAMETER         at least one parameter is not properly set
627* @return   M4ERR_BAD_OPTION_ID     when the option ID is not a valid one
628* @return   M4ERR_VIDEO_NOT_H263    No video stream H263 in file.
629* @return   M4ERR_NO_VIDEO_STREAM_RETRIEVED_YET
630*           Function 3gpReader_getNextStreamHandler must be called before
631************************************************************************
632*/
633M4OSA_ERR VideoEditor3gpReader_getOption(M4OSA_Context context,
634        M4OSA_OptionID optionId, M4OSA_DataOption pValue) {
635    VideoEditor3gpReader_Context* pC = (VideoEditor3gpReader_Context*)context;
636    M4OSA_ERR err = M4NO_ERROR;
637
638    ALOGV("VideoEditor3gpReader_getOption begin %d", optionId);
639
640    M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER,
641        "invalid context pointer");
642    M4OSA_DEBUG_IF1((M4OSA_NULL == pValue), M4ERR_PARAMETER,
643        "VideoEditor3gpReader_getOption: invalid pointer on value");
644
645    switch (optionId) {
646    case M4READER_kOptionID_Duration:
647        {
648            ALOGV("VideoEditor3gpReader_getOption duration %d",pC->mMaxDuration);
649            *(M4OSA_Time*)pValue = pC->mMaxDuration;
650        }
651        break;
652    case M4READER_kOptionID_Version:
653        /* not used */
654        ALOGV("VideoEditor3gpReader_getOption: M4READER_kOptionID_Version");
655        break;
656
657    case M4READER_kOptionID_Copyright:
658        /* not used */
659        ALOGV(">>>>>>>   M4READER_kOptionID_Copyright");
660        break;
661
662    case M4READER_kOptionID_CreationTime:
663        /* not used */
664        ALOGV("VideoEditor3gpReader_getOption M4READER_kOptionID_CreationTime");
665    break;
666
667    case M4READER_kOptionID_Bitrate:
668        {
669            M4OSA_UInt32* pBitrate = (M4OSA_UInt32*)pValue;
670
671            if (pC->mMaxDuration != 0) {
672                M4OSA_UInt32 ui32Tmp = (M4OSA_UInt32)pC->mMaxDuration;
673                *pBitrate = (M4OSA_UInt32)(pC->mFileSize * 8000.0 / pC->mMaxDuration);
674            }
675            ALOGV("VideoEditor3gpReader_getOption bitrate %ld", *pBitrate);
676        }
677    break;
678    case M4READER_3GP_kOptionID_H263Properties:
679        {
680            if(M4OSA_NULL == pC->mVideoStreamHandler) {
681                ALOGV("VideoEditor3gpReader_getOption no videoStream retrieved");
682
683                err = M4ERR_NO_VIDEO_STREAM_RETRIEVED_YET;
684                break;
685            }
686            if((M4DA_StreamTypeVideoH263 != pC->mVideoStreamHandler->\
687                m_streamType) || (pC->mVideoStreamHandler->\
688                m_decoderSpecificInfoSize < 7)) {
689                ALOGV("VideoEditor3gpReader_getOption DSI Size %d",
690                    pC->mVideoStreamHandler->m_decoderSpecificInfoSize);
691
692                err = M4ERR_VIDEO_NOT_H263;
693                break;
694            }
695
696            /* MAGICAL in the decoder confi H263: the 7th byte is the profile
697             * number, 6th byte is the level number */
698            ((M4READER_3GP_H263Properties *)pValue)->uiProfile =
699                pC->mVideoStreamHandler->m_pDecoderSpecificInfo[6];
700            ((M4READER_3GP_H263Properties *)pValue)->uiLevel =
701                pC->mVideoStreamHandler->m_pDecoderSpecificInfo[5];
702            ALOGV("VideoEditor3gpReader_getOption M4READER_3GP_kOptionID_\
703            H263Properties end");
704        }
705        break;
706    case M4READER_3GP_kOptionID_PurpleLabsDrm:
707        ALOGV("VideoEditor3gpReaderOption M4READER_3GP_kOptionID_PurpleLabsDrm");
708        /* not used */
709        break;
710
711    case M4READER_kOptionID_GetNumberOfAudioAu:
712        /* not used */
713        ALOGV("VideoEditor3gpReadeOption M4READER_kOptionID_GetNumberOfAudioAu");
714    break;
715
716    case M4READER_kOptionID_GetNumberOfVideoAu:
717        /* not used */
718        ALOGV("VideoEditor3gpReader_getOption :GetNumberOfVideoAu");
719    break;
720
721    case M4READER_kOptionID_GetMetadata:
722        /* not used */
723        ALOGV("VideoEditor3gpReader_getOption M4READER_kOptionID_GetMetadata");
724    break;
725
726    case M4READER_kOptionID_3gpFtypBox:
727        /* used only for SEMC */
728        ALOGV("VideoEditor3gpReader_getOption M4READER_kOptionID_3gpFtypBox");
729        err = M4ERR_BAD_OPTION_ID; //check this
730        break;
731
732#ifdef OPTIONID_GET_NEXT_VIDEO_CTS
733    case M4READER_3GP_kOptionID_getNextVideoCTS:
734        /* not used */
735        ALOGV("VideoEditor3gpReader_getOption: getNextVideoCTS");
736        break;
737#endif
738    default:
739        {
740            err = M4ERR_BAD_OPTION_ID;
741            ALOGV("VideoEditor3gpReader_getOption M4ERR_BAD_OPTION_ID");
742        }
743        break;
744    }
745    ALOGV("VideoEditor3gpReader_getOption end: optionID: x%x", optionId);
746    return err;
747}
748/**
749************************************************************************
750* @brief    set an option on the 3gp reader
751* @note No option can be set yet.
752* @param    context:        (IN)    Context of the reader
753* @param    optionId:       (IN)    indicates the option to set
754* @param    pValue:         (IN)    pointer to structure or value (allocated
755*                                   by user) where option is stored
756* @return   M4NO_ERROR              there is no error
757* @return   M4ERR_BAD_CONTEXT       provided context is not a valid one
758* @return   M4ERR_PARAMETER         at least one parameter is not properly set
759* @return   M4ERR_BAD_OPTION_ID     when the option ID is not a valid one
760************************************************************************
761*/
762M4OSA_ERR VideoEditor3gpReader_setOption(M4OSA_Context context,
763        M4OSA_OptionID optionId, M4OSA_DataOption pValue) {
764    VideoEditor3gpReader_Context* pC = (VideoEditor3gpReader_Context*)context;
765    M4OSA_ERR err = M4NO_ERROR;
766
767    /* Check function parameters */
768    M4OSA_DEBUG_IF1((M4OSA_NULL == pC), M4ERR_PARAMETER,
769        "invalid context pointer");
770    M4OSA_DEBUG_IF1((M4OSA_NULL == pValue), M4ERR_PARAMETER,
771        "invalid value pointer");
772
773    ALOGV("VideoEditor3gpReader_setOption begin %d",optionId);
774
775    switch(optionId) {
776        case M4READER_kOptionID_SetOsaFileReaderFctsPtr:
777        break;
778
779        case M4READER_3GP_kOptionID_AudioOnly:
780        break;
781
782        case M4READER_3GP_kOptionID_VideoOnly:
783        break;
784
785        case M4READER_3GP_kOptionID_FastOpenMode:
786        break;
787
788        case M4READER_kOptionID_MaxMetadataSize:
789        break;
790
791        default:
792        {
793            ALOGV("VideoEditor3gpReader_setOption: returns M4ERR_BAD_OPTION_ID");
794            err = M4ERR_BAD_OPTION_ID;
795        }
796        break;
797    }
798    ALOGV("VideoEditor3gpReader_setOption end ");
799    return err;
800}
801/**
802 ************************************************************************
803 * @brief   fill the access unit structure with initialization values
804 * @param   context:        (IN)     Context of the reader
805 * @param   pStreamHandler: (IN)     pointer to the stream handler to which
806 *                                   the access unit will be associated
807 * @param   pAccessUnit:    (IN/OUT) pointer to the access unit (allocated
808 *                                   by the caller) to initialize
809 * @return  M4NO_ERROR               there is no error
810 * @return  M4ERR_PARAMETER          at least one parameter is not properly set
811 ************************************************************************
812*/
813M4OSA_ERR VideoEditor3gpReader_fillAuStruct(M4OSA_Context context,
814        M4_StreamHandler *pStreamHandler, M4_AccessUnit *pAccessUnit) {
815    VideoEditor3gpReader_Context* pC = (VideoEditor3gpReader_Context*)context;
816    M4OSA_ERR err= M4NO_ERROR;
817
818    M4OSA_DEBUG_IF1((pC == 0),             M4ERR_PARAMETER,
819        "VideoEditor3gpReader_fillAuStruct: invalid context");
820    M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
821        "VideoEditor3gpReader_fillAuStruc invalid pointer to M4_StreamHandler");
822    M4OSA_DEBUG_IF1((pAccessUnit == 0),    M4ERR_PARAMETER,
823        "VideoEditor3gpReader_fillAuStruct: invalid pointer to M4_AccessUnit");
824
825    ALOGV("VideoEditor3gpReader_fillAuStruct begin");
826
827    /* Initialize pAccessUnit structure */
828    pAccessUnit->m_size         = 0;
829    pAccessUnit->m_CTS          = 0;
830    pAccessUnit->m_DTS          = 0;
831    pAccessUnit->m_attribute    = 0;
832    pAccessUnit->m_dataAddress  = M4OSA_NULL;
833    pAccessUnit->m_maxsize      = pStreamHandler->m_maxAUSize;
834    pAccessUnit->m_streamID     = pStreamHandler->m_streamId;
835    pAccessUnit->m_structSize   = sizeof(M4_AccessUnit);
836
837    ALOGV("VideoEditor3gpReader_fillAuStruct end");
838    return M4NO_ERROR;
839}
840
841/**
842********************************************************************************
843* @brief    jump into the stream at the specified time
844* @note
845* @param    context:        (IN)   Context of the reader
846* @param    pStreamHandler  (IN)   the stream handler of the stream to make jump
847* @param    pTime           (I/O)IN  the time to jump to (in ms)
848*                                OUT the time to which the stream really jumped
849* @return   M4NO_ERROR             there is no error
850* @return   M4ERR_PARAMETER        at least one parameter is not properly set
851********************************************************************************
852*/
853M4OSA_ERR VideoEditor3gpReader_jump(M4OSA_Context context,
854        M4_StreamHandler *pStreamHandler, M4OSA_Int32* pTime) {
855    VideoEditor3gpReader_Context* pC = (VideoEditor3gpReader_Context*)context;
856    M4OSA_ERR err = M4NO_ERROR;
857    M4SYS_AccessUnit* pAu;
858    M4OSA_Time time64;
859
860    M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER,
861        "VideoEditor3gpReader_jump: invalid context");
862    M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
863        "VideoEditor3gpReader_jump: invalid pointer to M4_StreamHandler");
864    M4OSA_DEBUG_IF1((pTime == 0), M4ERR_PARAMETER,
865        "VideoEditor3gpReader_jump: invalid time pointer");
866
867    ALOGV("VideoEditor3gpReader_jump begin");
868
869    if (*pTime == (pStreamHandler->m_duration)) {
870        *pTime -= 1;
871    }
872    time64 = (M4OSA_Time)*pTime;
873
874    ALOGV("VideoEditor3gpReader_jump time us %ld ", time64);
875
876    if ((pC->mAudioStreamHandler != M4OSA_NULL) &&
877            (pStreamHandler->m_streamId == pC->mAudioStreamHandler->m_streamId))
878            {
879        pAu = &pC->mAudioAu;
880        pAu->CTS = time64;
881        pAu->DTS = time64;
882
883        time64 = time64 * 1000; /* Convert the time into micro sec */
884        pC->mAudioSeeking = M4OSA_TRUE;
885        pC->mAudioSeekTime = time64;
886        ALOGV("VideoEditor3gpReader_jump AUDIO time us %ld ", time64);
887    } else if ((pC->mVideoStreamHandler != M4OSA_NULL) &&
888            (pStreamHandler->m_streamId == pC->mVideoStreamHandler->m_streamId))
889            {
890        pAu = &pC->mVideoAu;
891        pAu->CTS = time64;
892        pAu->DTS = time64;
893
894        time64 = time64 * 1000; /* Convert the time into micro sec */
895        pC->mVideoSeeking = M4OSA_TRUE;
896        pC->mVideoSeekTime = time64;
897        ALOGV("VideoEditor3gpReader_jump VIDEO time us %ld ", time64);
898    } else {
899        ALOGV("VideoEditor3gpReader_jump passed StreamHandler is not known\n");
900        return M4ERR_PARAMETER;
901    }
902    time64 = time64 / 1000; /* Convert the time into milli sec */
903    ALOGV("VideoEditor3gpReader_jump time ms before seekset %ld ", time64);
904
905    *pTime = (M4OSA_Int32)time64;
906
907    ALOGV("VideoEditor3gpReader_jump end");
908    err = M4NO_ERROR;
909    return err;
910}
911/**
912********************************************************************************
913* @brief    reset the stream, that is seek it to beginning and make it ready
914* @note
915* @param    context:        (IN)    Context of the reader
916* @param    pStreamHandler  (IN)    The stream handler of the stream to reset
917* @return   M4NO_ERROR              there is no error
918* @return   M4ERR_PARAMETER         at least one parameter is not properly set
919********************************************************************************
920*/
921M4OSA_ERR VideoEditor3gpReader_reset(M4OSA_Context context,
922        M4_StreamHandler *pStreamHandler) {
923    VideoEditor3gpReader_Context* pC = (VideoEditor3gpReader_Context*)context;
924    M4OSA_ERR err = M4NO_ERROR;
925    M4SYS_StreamID streamIdArray[2];
926    M4SYS_AccessUnit* pAu;
927    M4OSA_Time time64 = 0;
928
929    M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER,
930        "VideoEditor3gpReader_reset: invalid context");
931    M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
932        "VideoEditor3gpReader_reset: invalid pointer to M4_StreamHandler");
933
934    ALOGV("VideoEditor3gpReader_reset begin");
935
936    if (pStreamHandler == (M4_StreamHandler*)pC->mAudioStreamHandler) {
937        pAu = &pC->mAudioAu;
938    } else if (pStreamHandler == (M4_StreamHandler*)pC->mVideoStreamHandler) {
939        pAu = &pC->mVideoAu;
940    } else {
941        ALOGV("VideoEditor3gpReader_reset passed StreamHandler is not known\n");
942        return M4ERR_PARAMETER;
943    }
944
945    pAu->CTS = time64;
946    pAu->DTS = time64;
947
948    ALOGV("VideoEditor3gpReader_reset end");
949    return err;
950}
951
952/**
953********************************************************************************
954* @brief  Gets an access unit (AU) from the stream handler source.
955* @note   An AU is the smallest possible amount of data to be decoded by decoder
956*
957* @param    context:        (IN) Context of the reader
958* @param    pStreamHandler  (IN) The stream handler of the stream to make jump
959* @param    pAccessUnit     (IO) Pointer to access unit to fill with read data
960* @return   M4NO_ERROR           there is no error
961* @return   M4ERR_PARAMETER      at least one parameter is not properly set
962* @returns  M4ERR_ALLOC          memory allocation failed
963* @returns  M4WAR_NO_MORE_AU     there are no more access unit in the stream
964********************************************************************************
965*/
966M4OSA_ERR VideoEditor3gpReader_getNextAu(M4OSA_Context context,
967        M4_StreamHandler *pStreamHandler, M4_AccessUnit *pAccessUnit) {
968    VideoEditor3gpReader_Context* pC=(VideoEditor3gpReader_Context*)context;
969    M4OSA_ERR err = M4NO_ERROR;
970    M4SYS_AccessUnit* pAu;
971    int64_t tempTime64 = 0;
972    MediaBuffer *mMediaBuffer = NULL;
973    MediaSource::ReadOptions options;
974    M4OSA_Bool flag = M4OSA_FALSE;
975    status_t error;
976    int32_t i32Tmp = 0;
977
978    M4OSA_DEBUG_IF1((pReaderContext == 0), M4ERR_PARAMETER,
979        "VideoEditor3gpReader_getNextAu: invalid context");
980    M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
981        "VideoEditor3gpReader_getNextAu: invalid pointer to M4_StreamHandler");
982    M4OSA_DEBUG_IF1((pAccessUnit == 0),    M4ERR_PARAMETER,
983        "VideoEditor3gpReader_getNextAu: invalid pointer to M4_AccessUnit");
984
985    ALOGV("VideoEditor3gpReader_getNextAu begin");
986
987    if (pStreamHandler == (M4_StreamHandler*)pC->mAudioStreamHandler) {
988        ALOGV("VideoEditor3gpReader_getNextAu audio stream");
989        pAu = &pC->mAudioAu;
990        if (pC->mAudioSeeking == M4OSA_TRUE) {
991            ALOGV("VideoEditor3gpReader_getNextAu audio seek time: %ld",
992                pC->mAudioSeekTime);
993            options.setSeekTo(pC->mAudioSeekTime);
994            pC->mAudioSource->read(&mMediaBuffer, &options);
995
996            mMediaBuffer->meta_data()->findInt64(kKeyTime,
997                (int64_t*)&tempTime64);
998            options.clearSeekTo();
999            pC->mAudioSeeking = M4OSA_FALSE;
1000            flag = M4OSA_TRUE;
1001        } else {
1002            ALOGV("VideoEditor3gpReader_getNextAu audio no seek:");
1003            pC->mAudioSource->read(&mMediaBuffer, &options);
1004            if (mMediaBuffer != NULL) {
1005                mMediaBuffer->meta_data()->findInt64(kKeyTime,
1006                    (int64_t*)&tempTime64);
1007            }
1008        }
1009    } else if (pStreamHandler == (M4_StreamHandler*)pC->mVideoStreamHandler) {
1010        ALOGV("VideoEditor3gpReader_getNextAu video steram ");
1011        pAu = &pC->mVideoAu;
1012        if(pC->mVideoSeeking == M4OSA_TRUE) {
1013            flag = M4OSA_TRUE;
1014            ALOGV("VideoEditor3gpReader_getNextAu seek: %ld",pC->mVideoSeekTime);
1015            options.setSeekTo(pC->mVideoSeekTime,
1016                MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
1017            do
1018            {
1019                if (mMediaBuffer != NULL) {
1020                    ALOGV("VideoEditor3gpReader_getNextAu free the MediaBuffer");
1021                    mMediaBuffer->release();
1022                }
1023                error = pC->mVideoSource->read(&mMediaBuffer, &options);
1024                ALOGV("VE3gpReader_getNextAu MediaBuffer %x , error %d",
1025                    mMediaBuffer, error);
1026                if (mMediaBuffer != NULL)
1027                {
1028                    if (mMediaBuffer->meta_data()->findInt32(kKeyIsSyncFrame,
1029                        &i32Tmp) && i32Tmp) {
1030                            ALOGV("SYNC FRAME FOUND--%d", i32Tmp);
1031                        pAu->attribute = AU_RAP;
1032                    }
1033                    else {
1034                        pAu->attribute = AU_P_Frame;
1035                    }
1036                    mMediaBuffer->meta_data()->findInt64(kKeyTime,
1037                        (int64_t*)&tempTime64);
1038                } else {
1039                    break;
1040                }
1041                options.clearSeekTo();
1042            } while(tempTime64 < pC->mVideoSeekTime);
1043
1044            ALOGV("VE3gpReader_getNextAu: video  time with seek  = %lld:",
1045                tempTime64);
1046            pC->mVideoSeeking = M4OSA_FALSE;
1047        } else {
1048            ALOGV("VideoEditor3gpReader_getNextAu video no seek:");
1049            pC->mVideoSource->read(&mMediaBuffer, &options);
1050
1051            if(mMediaBuffer != NULL) {
1052                if (mMediaBuffer->meta_data()->findInt32(kKeyIsSyncFrame,
1053                    &i32Tmp) && i32Tmp) {
1054                    ALOGV("SYNC FRAME FOUND--%d", i32Tmp);
1055                    pAu->attribute = AU_RAP;
1056                }
1057                else {
1058                    pAu->attribute = AU_P_Frame;
1059                }
1060                mMediaBuffer->meta_data()->findInt64(kKeyTime,
1061                    (int64_t*)&tempTime64);
1062                ALOGV("VE3gpReader_getNextAu: video no seek time = %lld:",
1063                    tempTime64);
1064            }else {
1065                ALOGV("VE3gpReader_getNextAu:video no seek time buffer is NULL");
1066            }
1067        }
1068    } else {
1069        ALOGV("VideoEditor3gpReader_getNextAu M4ERR_PARAMETER");
1070        return M4ERR_PARAMETER;
1071    }
1072
1073    if (mMediaBuffer != NULL) {
1074        if( (pAu->dataAddress == NULL) ||  (pAu->size < \
1075            mMediaBuffer->range_length())) {
1076            if(pAu->dataAddress != NULL) {
1077                free((M4OSA_Int32*)pAu->dataAddress);
1078                pAu->dataAddress = NULL;
1079            }
1080            ALOGV("Buffer lenght = %d ,%d",(mMediaBuffer->range_length() +\
1081                3) & ~0x3,(mMediaBuffer->range_length()));
1082
1083            pAu->dataAddress = (M4OSA_Int32*)M4OSA_32bitAlignedMalloc(
1084                (mMediaBuffer->range_length() + 3) & ~0x3,M4READER_3GP,
1085                    (M4OSA_Char*)"pAccessUnit->m_dataAddress" );
1086            if(pAu->dataAddress == NULL) {
1087                ALOGV("VideoEditor3gpReader_getNextAu malloc failed");
1088                return M4ERR_ALLOC;
1089            }
1090        }
1091        pAu->size = mMediaBuffer->range_length();
1092
1093        memcpy((void *)pAu->dataAddress,
1094            (void *)((const char *)mMediaBuffer->data() + mMediaBuffer->range_offset()),
1095            mMediaBuffer->range_length());
1096
1097        if( (pStreamHandler == (M4_StreamHandler*)pC->mVideoStreamHandler)  &&
1098            (pStreamHandler->m_streamType == M4DA_StreamTypeVideoMpeg4Avc) ) {
1099            M4OSA_UInt32 size = mMediaBuffer->range_length();
1100            M4OSA_UInt8 *lbuffer;
1101
1102            lbuffer = (M4OSA_UInt8 *) pAu->dataAddress;
1103            ALOGV("pAccessUnit->m_dataAddress size = %x",size);
1104
1105            lbuffer[0] = (size >> 24) & 0xFF;
1106            lbuffer[1] = (size >> 16) & 0xFF;
1107            lbuffer[2] = (size >> 8) & 0xFF;
1108            lbuffer[3] = (size) & 0xFF;
1109        }
1110
1111        pAu->CTS = tempTime64;
1112
1113        pAu->CTS = pAu->CTS / 1000; //converting the microsec to millisec
1114        ALOGV("VideoEditor3gpReader_getNextAu CTS = %ld",pAu->CTS);
1115
1116        pAu->DTS  = pAu->CTS;
1117        if (pStreamHandler == (M4_StreamHandler*)pC->mAudioStreamHandler) {
1118            pAu->attribute = M4SYS_kFragAttrOk;
1119        }
1120        mMediaBuffer->release();
1121
1122        pAccessUnit->m_dataAddress = (M4OSA_Int8*) pAu->dataAddress;
1123        pAccessUnit->m_size = pAu->size;
1124        pAccessUnit->m_maxsize = pAu->size;
1125        pAccessUnit->m_CTS = pAu->CTS;
1126        pAccessUnit->m_DTS = pAu->DTS;
1127        pAccessUnit->m_attribute = pAu->attribute;
1128
1129    } else {
1130        ALOGV("VideoEditor3gpReader_getNextAu: M4WAR_NO_MORE_AU (EOS) reached");
1131        pAccessUnit->m_size = 0;
1132        err = M4WAR_NO_MORE_AU;
1133    }
1134    options.clearSeekTo();
1135
1136    pAu->nbFrag = 0;
1137    mMediaBuffer = NULL;
1138    ALOGV("VideoEditor3gpReader_getNextAu end ");
1139
1140    return err;
1141}
1142/**
1143 *******************************************************************************
1144 * @brief   Split the AVC DSI in its different components and write it in
1145 *          ONE memory buffer
1146 * @note
1147 * @param   pStreamHandler:         (IN/OUT) The MPEG4-AVC stream
1148 * @param   pDecoderConfigLocal:    (IN) The DSI buffer
1149 * @param   decoderConfigSizeLocal: (IN) The DSI buffer size
1150 * @return  M4NO_ERROR              there is no error
1151 * @return  ERR_FILE_SYNTAX_ERROR   pDecoderConfigLocal is NULL
1152 *******************************************************************************
1153*/
1154static M4OSA_ERR VideoEditor3gpReader_AnalyseAvcDsi(
1155        M4_StreamHandler *pStreamHandler, M4OSA_Int32* pDecoderConfigLocal,
1156        M4OSA_Int32 decoderConfigSizeLocal) {
1157    struct _avcSpecificInfo *pAvcSpecInfo = M4OSA_NULL;
1158    M4OSA_UInt32 uiSpecInfoSize;
1159    M4OSA_Context pBitParserContext = M4OSA_NULL;
1160    M4OSA_MemAddr8 pPos;
1161
1162    /**
1163     * First parsing to get the total allocation size (we must not do
1164     * multiple malloc, but only one instead) */
1165    {
1166        M4OSA_Int32 val;
1167        M4OSA_UInt32 i,j;
1168        M4OSA_UInt8 nalUnitLength;
1169        M4OSA_UInt8  numOfSequenceParameterSets;
1170        M4OSA_UInt32 uiTotalSizeOfSPS = 0;
1171        M4OSA_UInt8  numOfPictureParameterSets;
1172        M4OSA_UInt32 uiTotalSizeOfPPS = 0;
1173        M4OSA_UInt32 uiSize;
1174        struct _avcSpecificInfo avcSpIf;
1175
1176        avcSpIf.m_nalUnitLength = 0;
1177
1178        if (M4OSA_NULL == pDecoderConfigLocal) {
1179            return M4ERR_READER3GP_DECODER_CONFIG_ERROR;
1180        }
1181
1182        VideoEditor3gpReader_MPEG4BitStreamParserInit(&pBitParserContext,
1183            pDecoderConfigLocal, decoderConfigSizeLocal);
1184
1185        if (M4OSA_NULL == pBitParserContext) {
1186            return M4ERR_ALLOC;
1187        }
1188
1189        VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1190                                       /* 8 bits -- configuration version */
1191        VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1192                                       /* 8 bits -- avc profile indication*/
1193        VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1194                                       /* 8 bits -- profile compatibility */
1195        VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1196                                       /* 8 bits -- avc level indication*/
1197        val=VideoEditor3gpReader_BitStreamParserShowBits(pBitParserContext, 8);
1198                       /* 6 bits reserved 111111b 2 bits length Size minus one*/
1199        VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1200                                       /* m_nalUnitLength */
1201
1202        nalUnitLength = (M4OSA_UInt8)((val & 0x03) + 1);/*0b11111100*/
1203        if (nalUnitLength > 4) {
1204            pStreamHandler->m_decoderSpecificInfoSize = 0;
1205            pStreamHandler->m_pDecoderSpecificInfo = M4OSA_NULL;
1206            VideoEditor3gpReader_BitStreamParserCleanUp(pBitParserContext);
1207        } else {
1208            /**
1209             * SPS table */
1210            val=VideoEditor3gpReader_BitStreamParserShowBits(pBitParserContext,
1211            8);/* 3 bits-reserved 111b-5 bits number of sequence parameter set*/
1212            numOfSequenceParameterSets = val & 0x1F;
1213            /*1F instead of E0*/ /*0b11100000*/ /*Number of seq parameter sets*/
1214            VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1215            for (i=0; i < numOfSequenceParameterSets; i++) {
1216                /**
1217                 * Get the size of this element */
1218                uiSize =
1219                    (M4OSA_UInt32)VideoEditor3gpReader_BitStreamParserShowBits(
1220                    pBitParserContext, 16);
1221                uiTotalSizeOfSPS += uiSize;
1222                VideoEditor3gpReader_BitStreamParserFlushBits(
1223                    pBitParserContext, 16);
1224                /**
1225                 *Read the element(dont keep it, we only want size right now) */
1226                for (j=0; j<uiSize; j++) {
1227                    VideoEditor3gpReader_BitStreamParserFlushBits(
1228                        pBitParserContext, 8);
1229                }
1230            }
1231
1232            /**
1233             * SPS table */
1234            numOfPictureParameterSets=(M4OSA_UInt8)\
1235                VideoEditor3gpReader_BitStreamParserShowBits(pBitParserContext,
1236                    8);
1237            VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1238            for (i=0; i < numOfPictureParameterSets; i++) {
1239                /**
1240                 * Get the size of this element */
1241                uiSize = (M4OSA_UInt32)
1242                    VideoEditor3gpReader_BitStreamParserShowBits(
1243                    pBitParserContext, 16);
1244                uiTotalSizeOfPPS += uiSize;
1245                VideoEditor3gpReader_BitStreamParserFlushBits(
1246                    pBitParserContext, 16);
1247                /**
1248                 *Read the element(dont keep it,we only want size right now)*/
1249                for (j=0; j<uiSize; j++) {
1250                    VideoEditor3gpReader_BitStreamParserFlushBits(
1251                        pBitParserContext, 8);
1252                }
1253            }
1254
1255            /**
1256             * Compute the size of the full buffer */
1257            uiSpecInfoSize = sizeof(struct _avcSpecificInfo) +
1258                     numOfSequenceParameterSets * sizeof(struct _parameterSet)
1259                     + /**< size of the table of SPS elements */
1260                     numOfPictureParameterSets  * sizeof(struct _parameterSet)
1261                     + /**< size of the table of PPS elements */
1262                     uiTotalSizeOfSPS +
1263                     uiTotalSizeOfPPS;
1264            /**
1265             * Allocate the buffer */
1266            pAvcSpecInfo =(struct _avcSpecificInfo*)M4OSA_32bitAlignedMalloc(uiSpecInfoSize,
1267                M4READER_3GP, (M4OSA_Char*)"MPEG-4 AVC DecoderSpecific");
1268            if (M4OSA_NULL == pAvcSpecInfo) {
1269                VideoEditor3gpReader_BitStreamParserCleanUp(pBitParserContext);
1270                return M4ERR_ALLOC;
1271            }
1272
1273            /**
1274             * Set the pointers to the correct part of the buffer */
1275            pAvcSpecInfo->m_nalUnitLength = nalUnitLength;
1276            pAvcSpecInfo->m_numOfSequenceParameterSets =
1277                numOfSequenceParameterSets;
1278            pAvcSpecInfo->m_numOfPictureParameterSets  =
1279                numOfPictureParameterSets;
1280
1281            /* We place the SPS param sets table after m_pPictureParameterSet */
1282            pAvcSpecInfo->m_pSequenceParameterSet= (struct _parameterSet*)(
1283                (M4OSA_MemAddr8)(&pAvcSpecInfo->m_pPictureParameterSet) +
1284                sizeof(pAvcSpecInfo->m_pPictureParameterSet));
1285            /*We place the PPS param sets table after the SPS param sets table*/
1286            pAvcSpecInfo->m_pPictureParameterSet = (struct _parameterSet*)(
1287                (M4OSA_MemAddr8)(pAvcSpecInfo->m_pSequenceParameterSet) +
1288                (numOfSequenceParameterSets * sizeof(struct _parameterSet)));
1289            /**< The data will be placed after the PPS param sets table */
1290            pPos = (M4OSA_MemAddr8)pAvcSpecInfo->m_pPictureParameterSet +
1291                (numOfPictureParameterSets * sizeof(struct _parameterSet));
1292
1293            /**
1294             * reset the bit parser */
1295            VideoEditor3gpReader_BitStreamParserCleanUp(pBitParserContext);
1296        }
1297    }
1298
1299    /**
1300     * Second parsing to copy the data */
1301    if (M4OSA_NULL != pAvcSpecInfo) {
1302        M4OSA_Int32 i,j;
1303
1304        VideoEditor3gpReader_MPEG4BitStreamParserInit(&pBitParserContext,
1305            pDecoderConfigLocal, decoderConfigSizeLocal);
1306
1307        if (M4OSA_NULL == pBitParserContext) {
1308            free(pAvcSpecInfo);
1309            return M4ERR_ALLOC;
1310        }
1311
1312        VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1313            /* 8 bits -- configuration version */
1314        VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1315            /* 8 bits -- avc profile indication*/
1316        VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1317            /* 8 bits -- profile compatibility */
1318        VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1319            /* 8 bits -- avc level indication*/
1320        VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1321            /* m_nalUnitLength */
1322        VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1323        /* 3 bits -- reserved 111b -- 5 bits number of sequence parameter set*/
1324
1325        for (i=0; i < pAvcSpecInfo->m_numOfSequenceParameterSets; i++) {
1326            pAvcSpecInfo->m_pSequenceParameterSet[i].m_length =
1327                (M4OSA_UInt16)VideoEditor3gpReader_BitStreamParserShowBits(
1328                pBitParserContext, 16);
1329            VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext,16);
1330
1331            pAvcSpecInfo->m_pSequenceParameterSet[i].m_pParameterSetUnit =
1332                (M4OSA_UInt8*)pPos;  /**< current position in the buffer */
1333            pPos += pAvcSpecInfo->m_pSequenceParameterSet[i].m_length;
1334                /**< increment the position in the buffer */
1335            for (j=0; j<pAvcSpecInfo->m_pSequenceParameterSet[i].m_length;j++){
1336                pAvcSpecInfo->m_pSequenceParameterSet[i].m_pParameterSetUnit[j]=
1337                    (M4OSA_UInt8)VideoEditor3gpReader_BitStreamParserShowBits(
1338                    pBitParserContext, 8);
1339                VideoEditor3gpReader_BitStreamParserFlushBits(
1340                    pBitParserContext, 8);
1341            }
1342        }
1343
1344        VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext, 8);
1345            /* number of pîcture parameter set*/
1346
1347        for (i=0; i < pAvcSpecInfo->m_numOfPictureParameterSets; i++) {
1348            pAvcSpecInfo->m_pPictureParameterSet[i].m_length =
1349                (M4OSA_UInt16)VideoEditor3gpReader_BitStreamParserShowBits(
1350                pBitParserContext, 16);
1351            VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext,16);
1352
1353            pAvcSpecInfo->m_pPictureParameterSet[i].m_pParameterSetUnit =
1354                (M4OSA_UInt8*)pPos;   /**< current position in the buffer */
1355            pPos += pAvcSpecInfo->m_pPictureParameterSet[i].m_length;
1356                /**< increment the position in the buffer */
1357            for (j=0; j<pAvcSpecInfo->m_pPictureParameterSet[i].m_length; j++) {
1358                pAvcSpecInfo->m_pPictureParameterSet[i].m_pParameterSetUnit[j] =
1359                    (M4OSA_UInt8)VideoEditor3gpReader_BitStreamParserShowBits(
1360                    pBitParserContext, 8);
1361                VideoEditor3gpReader_BitStreamParserFlushBits(
1362                    pBitParserContext, 8);
1363            }
1364        }
1365        VideoEditor3gpReader_BitStreamParserCleanUp(pBitParserContext);
1366        pStreamHandler->m_decoderSpecificInfoSize = uiSpecInfoSize;
1367        pStreamHandler->m_pDecoderSpecificInfo = (M4OSA_UInt8*)pAvcSpecInfo;
1368    }
1369    pStreamHandler->m_H264decoderSpecificInfoSize  =  decoderConfigSizeLocal;
1370    pStreamHandler->m_pH264DecoderSpecificInfo  = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1371        decoderConfigSizeLocal, M4READER_3GP,
1372        (M4OSA_Char*)"MPEG-4 AVC DecoderSpecific");
1373    if (M4OSA_NULL == pStreamHandler->m_pH264DecoderSpecificInfo) {
1374        goto cleanup;
1375    }
1376
1377    memcpy((void * ) pStreamHandler->m_pH264DecoderSpecificInfo,
1378        (void * )pDecoderConfigLocal,
1379        pStreamHandler->m_H264decoderSpecificInfoSize);
1380    return M4NO_ERROR;
1381cleanup:
1382    VideoEditor3gpReader_BitStreamParserCleanUp(pBitParserContext);
1383    return M4ERR_READER3GP_DECODER_CONFIG_ERROR;
1384}
1385/**
1386********************************************************************************
1387* @brief    Get the next stream found in the 3gp file
1388* @note
1389* @param    context:     (IN)    Context of the reader
1390* @param    pMediaFamily: OUT)   pointer to a user allocated
1391*                                M4READER_MediaFamily that will be filled
1392*                                with the media family of the found stream
1393* @param    pStreamHandler:(OUT) pointer to StreamHandler that will be allocated
1394*                                and filled with the found stream description
1395* @return   M4NO_ERROR              there is no error
1396* @return   M4ERR_BAD_CONTEXT       provided context is not a valid one
1397* @return   M4ERR_PARAMETER         at least one parameter is not properly set
1398* @return   M4WAR_NO_MORE_STREAM    no more available stream in the media
1399********************************************************************************
1400*/
1401M4OSA_ERR VideoEditor3gpReader_getNextStreamHandler(M4OSA_Context context,
1402        M4READER_MediaFamily *pMediaFamily,
1403        M4_StreamHandler **pStreamHandler) {
1404    VideoEditor3gpReader_Context* pC=(VideoEditor3gpReader_Context*)context;
1405    M4OSA_ERR err = M4NO_ERROR;
1406    M4SYS_StreamID streamIdArray[2];
1407    M4SYS_StreamDescription streamDesc;
1408    M4_AudioStreamHandler* pAudioStreamHandler;
1409    M4_VideoStreamHandler* pVideoStreamHandler;
1410    M4OSA_Int8 *DecoderSpecificInfo = M4OSA_NULL;
1411    M4OSA_Int32 decoderSpecificInfoSize =0, maxAUSize = 0;
1412
1413    M4_StreamType streamType = M4DA_StreamTypeUnknown;
1414    M4OSA_UInt8 temp, i, trackCount;
1415    M4OSA_Bool haveAudio = M4OSA_FALSE;
1416    M4OSA_Bool haveVideo = M4OSA_FALSE;
1417    sp<MetaData> meta  = NULL;
1418    int64_t Duration = 0;
1419    M4OSA_UInt8* DecoderSpecific = M4OSA_NULL ;
1420    uint32_t type;
1421    const void *data;
1422    size_t size;
1423    const void *codec_specific_data;
1424    size_t codec_specific_data_size;
1425    M4OSA_Int32  ptempTime;
1426    M4OSA_Int32  avgFPS=0;
1427
1428    ALOGV("VideoEditor3gpReader_getNextStreamHandler begin");
1429
1430    M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER,
1431        "VideoEditor3gpReader_getNextStreamHandler: invalid context");
1432    M4OSA_DEBUG_IF1((pMediaFamily   == 0), M4ERR_PARAMETER,
1433        "getNextStreamHandler: invalid pointer to MediaFamily");
1434    M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
1435        "getNextStreamHandler: invalid pointer to StreamHandler");
1436
1437    trackCount = pC->mExtractor->countTracks();
1438    temp = pC->mCurrTrack;
1439
1440    if(temp >= trackCount) {
1441        ALOGV("VideoEditor3gpReader_getNextStreamHandler error = %d",
1442            M4WAR_NO_MORE_STREAM);
1443        return (M4WAR_NO_MORE_STREAM);
1444    } else {
1445        const char *mime;
1446        meta = pC->mExtractor->getTrackMetaData(temp);
1447        CHECK(meta->findCString(kKeyMIMEType, &mime));
1448
1449        if (!haveVideo && !strncasecmp(mime, "video/", 6)) {
1450            pC->mVideoSource = pC->mExtractor->getTrack(temp);
1451            pC->mVideoSource->start();
1452
1453            *pMediaFamily = M4READER_kMediaFamilyVideo;
1454            haveVideo = true;
1455            ALOGV("VideoEditor3gpReader_getNextStreamHandler getTrack called");
1456            if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
1457                streamType = M4DA_StreamTypeVideoMpeg4Avc;
1458            } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) {
1459                streamType = M4DA_StreamTypeVideoH263;
1460            } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) {
1461                streamType = M4DA_StreamTypeVideoMpeg4;
1462            } else {
1463                ALOGV("VideoEditor3gpReaderGetNextStreamHandler streamTypeNONE");
1464            }
1465            ALOGV("VideoEditor3gpReader_getNextStreamHandler: stream type: %d ",
1466                streamType);
1467
1468            if(streamType != M4DA_StreamTypeUnknown) {
1469                pC->mStreamType = streamType;
1470                pC->mStreamId = pC->mCurrTrack;
1471
1472                pVideoStreamHandler = (M4_VideoStreamHandler*)M4OSA_32bitAlignedMalloc
1473                    (sizeof(M4_VideoStreamHandler), M4READER_3GP,
1474                    (M4OSA_Char*)"M4_VideoStreamHandler");
1475                if (M4OSA_NULL == pVideoStreamHandler) {
1476                    return M4ERR_ALLOC;
1477                }
1478                pVideoStreamHandler->m_structSize=sizeof(M4_VideoStreamHandler);
1479
1480                meta->findInt32(kKeyWidth,
1481                    (int32_t*)&(pVideoStreamHandler->m_videoWidth));
1482                meta->findInt32(kKeyHeight,
1483                    (int32_t*)&(pVideoStreamHandler->m_videoHeight));
1484
1485                (*pStreamHandler)  = (M4_StreamHandler*)(pVideoStreamHandler);
1486                meta->findInt64(kKeyDuration, (int64_t*)&(Duration));
1487                ((*pStreamHandler)->m_duration) = (int32_t)((Duration)/1000); // conversion to mS
1488                pC->mMaxDuration = ((*pStreamHandler)->m_duration);
1489                if (pC->mMaxDuration == 0) {
1490                    ALOGE("Video is too short: %lld Us", Duration);
1491                    delete pVideoStreamHandler;
1492                    pVideoStreamHandler = NULL;
1493                    return M4ERR_PARAMETER;
1494                }
1495                ALOGV("VideoEditor3gpReader_getNextStreamHandler m_duration %d",
1496                    (*pStreamHandler)->m_duration);
1497
1498                off64_t fileSize = 0;
1499                pC->mDataSource->getSize(&fileSize);
1500                pC->mFileSize  = fileSize;
1501
1502                ALOGV("VideoEditor3gpReader_getNextStreamHandler m_fileSize %d",
1503                    pC->mFileSize);
1504
1505                meta->findInt32(kKeyMaxInputSize, (int32_t*)&(maxAUSize));
1506                if(maxAUSize == 0) {
1507                    maxAUSize = 70000;
1508                }
1509                (*pStreamHandler)->m_maxAUSize = maxAUSize;
1510                ALOGV("<<<<<<<<<<   video: mMaxAUSize from MP4 extractor: %d",
1511                    (*pStreamHandler)->m_maxAUSize);
1512
1513                ((M4_StreamHandler*)pVideoStreamHandler)->m_averageBitRate =
1514                        (pC->mFileSize * 8000)/pC->mMaxDuration;
1515                ALOGV("VideoEditor3gpReader_getNextStreamHandler m_averageBitrate %d",
1516                    ((M4_StreamHandler*)pVideoStreamHandler)->m_averageBitRate);
1517
1518
1519                meta->findInt32(kKeyFrameRate,
1520                    (int32_t*)&(avgFPS));
1521                ALOGV("<<<<<<<<<<   video: Average FPS from MP4 extractor: %d",
1522                    avgFPS);
1523
1524                pVideoStreamHandler->m_averageFrameRate =(M4OSA_Float) avgFPS;
1525                ALOGV("<<<<<<<<<<   video: Average FPS from MP4 extractor in FLOAT: %f",
1526                    pVideoStreamHandler->m_averageFrameRate);
1527
1528                // Get the video rotation degree
1529                int32_t rotationDegree;
1530                if(!meta->findInt32(kKeyRotation, &rotationDegree)) {
1531                    rotationDegree = 0;
1532                }
1533                pVideoStreamHandler->videoRotationDegrees = rotationDegree;
1534
1535                pC->mVideoStreamHandler =
1536                    (M4_StreamHandler*)(pVideoStreamHandler);
1537
1538                /* Get the DSI info */
1539                if(M4DA_StreamTypeVideoH263 == streamType) {
1540                    if (meta->findData(kKeyD263, &type, &data, &size)) {
1541                        (*pStreamHandler)->m_decoderSpecificInfoSize = size;
1542                        if ((*pStreamHandler)->m_decoderSpecificInfoSize != 0) {
1543                            DecoderSpecific = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1544                                (*pStreamHandler)->m_decoderSpecificInfoSize,
1545                                M4READER_3GP,(M4OSA_Char*)"H263 DSI");
1546                            if (M4OSA_NULL == DecoderSpecific) {
1547                                return M4ERR_ALLOC;
1548                            }
1549                            memcpy((void *)DecoderSpecific,
1550                                (void *)data, size);
1551                            (*pStreamHandler)->m_pDecoderSpecificInfo =
1552                                DecoderSpecific;
1553                        }
1554                        else {
1555                            (*pStreamHandler)->m_pDecoderSpecificInfo =
1556                                M4OSA_NULL;
1557                            (*pStreamHandler)->m_decoderSpecificInfoSize = 0;
1558                        }
1559                        (*pStreamHandler)->m_pESDSInfo = M4OSA_NULL;
1560                        (*pStreamHandler)->m_ESDSInfoSize = 0;
1561                        (*pStreamHandler)->m_pH264DecoderSpecificInfo = M4OSA_NULL;
1562                        (*pStreamHandler)->m_H264decoderSpecificInfoSize = 0;
1563                    } else {
1564                        ALOGV("VE_getNextStreamHandler: H263 dsi not found");
1565                        (*pStreamHandler)->m_pDecoderSpecificInfo = M4OSA_NULL;
1566                        (*pStreamHandler)->m_decoderSpecificInfoSize = 0;
1567                        (*pStreamHandler)->m_H264decoderSpecificInfoSize = 0;
1568                        (*pStreamHandler)->m_pH264DecoderSpecificInfo =
1569                            M4OSA_NULL;
1570                        (*pStreamHandler)->m_pESDSInfo = M4OSA_NULL;
1571                        (*pStreamHandler)->m_ESDSInfoSize = 0;
1572                    }
1573                }
1574                else if(M4DA_StreamTypeVideoMpeg4Avc == streamType) {
1575                    if(meta->findData(kKeyAVCC, &type, &data, &size)) {
1576                        decoderSpecificInfoSize = size;
1577                        if (decoderSpecificInfoSize != 0) {
1578                            DecoderSpecificInfo = (M4OSA_Int8*)M4OSA_32bitAlignedMalloc(
1579                                decoderSpecificInfoSize, M4READER_3GP,
1580                                (M4OSA_Char*)"H264 DecoderSpecific" );
1581                            if (M4OSA_NULL == DecoderSpecificInfo) {
1582                                ALOGV("VideoEditor3gp_getNextStream is NULL ");
1583                                return M4ERR_ALLOC;
1584                            }
1585                            memcpy((void *)DecoderSpecificInfo,
1586                                (void *)data, decoderSpecificInfoSize);
1587                        } else {
1588                            ALOGV("DSI Size %d", decoderSpecificInfoSize);
1589                            DecoderSpecificInfo = M4OSA_NULL;
1590                        }
1591                    }
1592                    (*pStreamHandler)->m_pESDSInfo = M4OSA_NULL;
1593                    (*pStreamHandler)->m_ESDSInfoSize = 0;
1594
1595                    err = VideoEditor3gpReader_AnalyseAvcDsi(*pStreamHandler,
1596                    (M4OSA_Int32*)DecoderSpecificInfo, decoderSpecificInfoSize);
1597
1598                    if (M4NO_ERROR != err) {
1599                        return err;
1600                    }
1601                    ALOGV("decsize %d, h264decsize %d: %d", (*pStreamHandler)->\
1602                        m_decoderSpecificInfoSize, (*pStreamHandler)->\
1603                        m_H264decoderSpecificInfoSize);
1604
1605                    if(M4OSA_NULL != DecoderSpecificInfo) {
1606                        free(DecoderSpecificInfo);
1607                        DecoderSpecificInfo = M4OSA_NULL;
1608                    }
1609                } else if( (M4DA_StreamTypeVideoMpeg4 == streamType) ) {
1610                    if (meta->findData(kKeyESDS, &type, &data, &size)) {
1611                        ESDS esds((const char *)data, size);
1612                        CHECK_EQ(esds.InitCheck(), (status_t)OK);
1613
1614                        (*pStreamHandler)->m_ESDSInfoSize = size;
1615                        (*pStreamHandler)->m_pESDSInfo = (M4OSA_UInt8*)\
1616                        M4OSA_32bitAlignedMalloc((*pStreamHandler)->m_ESDSInfoSize,
1617                        M4READER_3GP, (M4OSA_Char*)"M4V DecoderSpecific" );
1618                        if (M4OSA_NULL == (*pStreamHandler)->m_pESDSInfo) {
1619                            return M4ERR_ALLOC;
1620                        }
1621                        memcpy((void *)(*pStreamHandler)->\
1622                            m_pESDSInfo, (void *)data, size);
1623
1624                        esds.getCodecSpecificInfo(&codec_specific_data,
1625                            &codec_specific_data_size);
1626                        ALOGV("VE MP4 dsisize: %d, %x", codec_specific_data_size,
1627                            codec_specific_data);
1628
1629                        (*pStreamHandler)->m_decoderSpecificInfoSize =
1630                            codec_specific_data_size;
1631                        if ((*pStreamHandler)->m_decoderSpecificInfoSize != 0) {
1632                            DecoderSpecific = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1633                                (*pStreamHandler)->m_decoderSpecificInfoSize,
1634                                M4READER_3GP, (M4OSA_Char*)" DecoderSpecific" );
1635                            if (M4OSA_NULL == DecoderSpecific) {
1636                                return M4ERR_ALLOC;
1637                            }
1638                            memcpy((void *)DecoderSpecific,
1639                                (void *)codec_specific_data,
1640                                codec_specific_data_size);
1641                            (*pStreamHandler)->m_pDecoderSpecificInfo =
1642                                DecoderSpecific;
1643                        }
1644                        else {
1645                            (*pStreamHandler)->m_pDecoderSpecificInfo =
1646                                M4OSA_NULL;
1647                        }
1648                        (*pStreamHandler)->m_pH264DecoderSpecificInfo =
1649                            M4OSA_NULL;
1650                        (*pStreamHandler)->m_H264decoderSpecificInfoSize = 0;
1651                    }
1652                } else {
1653                    ALOGV("VideoEditor3gpReader_getNextStream NO video stream");
1654                    return M4ERR_READER_UNKNOWN_STREAM_TYPE;
1655                }
1656            }
1657            else {
1658                ALOGV("VideoEditor3gpReader_getNextStream NO video stream");
1659                return M4ERR_READER_UNKNOWN_STREAM_TYPE;
1660            }
1661
1662        } else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
1663            ALOGV("VideoEditor3gpReader_getNextStream audio getTrack called");
1664            pC->mAudioSource = pC->mExtractor->getTrack(pC->mCurrTrack);
1665            pC->mAudioSource->start();
1666            *pMediaFamily = M4READER_kMediaFamilyAudio;
1667
1668            if(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
1669                streamType = M4DA_StreamTypeAudioAmrNarrowBand;
1670            } else if(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
1671                streamType = M4DA_StreamTypeAudioAmrWideBand;
1672            }
1673            else if(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1674                streamType = M4DA_StreamTypeAudioAac;
1675            } else {
1676                ALOGV("VideoEditor3gpReader_getNextStrea streamtype Unknown ");
1677            }
1678            if(streamType != M4DA_StreamTypeUnknown) {
1679                pC->mStreamType = streamType;
1680                pC->mStreamId = pC->mCurrTrack;
1681
1682                ALOGV("VE streamtype %d ,id %d",  streamType, pC->mCurrTrack);
1683
1684                pAudioStreamHandler = (M4_AudioStreamHandler*)M4OSA_32bitAlignedMalloc
1685                    (sizeof(M4_AudioStreamHandler), M4READER_3GP,
1686                    (M4OSA_Char*)"M4_AudioStreamHandler");
1687                if (M4OSA_NULL == pAudioStreamHandler) {
1688                    return M4ERR_ALLOC;
1689                }
1690                pAudioStreamHandler->m_structSize=sizeof(M4_AudioStreamHandler);
1691                pAudioStreamHandler->m_byteSampleSize   = 0;
1692                pAudioStreamHandler->m_nbChannels       = 0;
1693                pAudioStreamHandler->m_samplingFrequency= 0;
1694                pAudioStreamHandler->m_byteFrameLength  = 0;
1695
1696                (*pStreamHandler) = (M4_StreamHandler*)(pAudioStreamHandler);
1697                pC->mAudioStreamHandler =
1698                    (M4_StreamHandler*)(pAudioStreamHandler);
1699                (*pStreamHandler)->m_averageBitRate = 0;
1700                haveAudio = true;
1701                pC->mAudioStreamHandler=(M4_StreamHandler*)pAudioStreamHandler;
1702                pC->mAudioStreamHandler->m_pESDSInfo = M4OSA_NULL;
1703                pC->mAudioStreamHandler->m_ESDSInfoSize = 0;
1704
1705                meta->findInt32(kKeyMaxInputSize, (int32_t*)&(maxAUSize));
1706                if(maxAUSize == 0) {
1707                    maxAUSize = 70000;
1708                }
1709                (*pStreamHandler)->m_maxAUSize = maxAUSize;
1710                ALOGV("VE Audio mMaxAUSize from MP4 extractor: %d", maxAUSize);
1711            }
1712            if((M4DA_StreamTypeAudioAmrNarrowBand == streamType) ||
1713                (M4DA_StreamTypeAudioAmrWideBand == streamType)) {
1714                M4OSA_UInt32 freqIndex = 0; /**< AMR NB */
1715                M4OSA_UInt32 modeSet;
1716                M4OSA_UInt32 i;
1717                M4OSA_Context pBitParserContext = M4OSA_NULL;
1718
1719                if(M4DA_StreamTypeAudioAmrWideBand == streamType) {
1720                    freqIndex = 1; /**< AMR WB */
1721                }
1722
1723                if (meta->findData(kKeyESDS, &type, &data, &size)) {
1724                    ESDS esds((const char *)data, size);
1725                    CHECK_EQ(esds.InitCheck(), (status_t)OK);
1726
1727                    esds.getCodecSpecificInfo(&codec_specific_data,
1728                        &codec_specific_data_size);
1729                    (*pStreamHandler)->m_decoderSpecificInfoSize =
1730                        codec_specific_data_size;
1731
1732                    if ((*pStreamHandler)->m_decoderSpecificInfoSize != 0) {
1733                        DecoderSpecific = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1734                            (*pStreamHandler)->m_decoderSpecificInfoSize,
1735                            M4READER_3GP, (M4OSA_Char*)"AMR DecoderSpecific" );
1736                        if (M4OSA_NULL == DecoderSpecific) {
1737                            return M4ERR_ALLOC;
1738                        }
1739                        memcpy((void *)DecoderSpecific,
1740                            (void *)codec_specific_data,
1741                            codec_specific_data_size);
1742                        (*pStreamHandler)->m_pDecoderSpecificInfo =
1743                            DecoderSpecific;
1744                    } else {
1745                        (*pStreamHandler)->m_pDecoderSpecificInfo = M4OSA_NULL;
1746                    }
1747                } else {
1748                    M4OSA_UChar AmrDsi[] =
1749                        {'P','H','L','P',0x00, 0x00, 0x80, 0x00, 0x01,};
1750                    (*pStreamHandler)->m_decoderSpecificInfoSize = 9;
1751                    DecoderSpecific = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1752                        (*pStreamHandler)->m_decoderSpecificInfoSize,
1753                        M4READER_3GP, (M4OSA_Char*)"PHLP DecoderSpecific" );
1754                    if (M4OSA_NULL == DecoderSpecific) {
1755                        return M4ERR_ALLOC;
1756                    }
1757                    if(freqIndex ==0) {
1758                        AmrDsi[8] = 0x01;
1759                    } else {
1760                        AmrDsi[8] = 0x02;
1761                    }
1762                    for(i = 0; i< 9; i++) {
1763                        DecoderSpecific[i] = AmrDsi[i];
1764                    }
1765                    (*pStreamHandler)->m_pDecoderSpecificInfo = DecoderSpecific;
1766                }
1767                (*pStreamHandler)->m_averageBitRate =
1768                    VideoEditor3gpReader_AmrBitRate[freqIndex][7];
1769            } else if((M4DA_StreamTypeAudioAac == streamType)) {
1770                if (meta->findData(kKeyESDS, &type, &data, &size)) {
1771                    ESDS esds((const char *)data, size);
1772                    CHECK_EQ(esds.InitCheck(), (status_t)OK);
1773
1774                    (*pStreamHandler)->m_ESDSInfoSize = size;
1775                    (*pStreamHandler)->m_pESDSInfo = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1776                        (*pStreamHandler)->m_ESDSInfoSize, M4READER_3GP,
1777                        (M4OSA_Char*)"AAC DecoderSpecific" );
1778                    if (M4OSA_NULL == (*pStreamHandler)->m_pESDSInfo) {
1779                        return M4ERR_ALLOC;
1780                    }
1781                    memcpy((void *)(*pStreamHandler)->m_pESDSInfo,
1782                    (void *)data, size);
1783                    esds.getCodecSpecificInfo(&codec_specific_data,
1784                        &codec_specific_data_size);
1785
1786                    ALOGV("VEdsi %d,%x",codec_specific_data_size,
1787                        codec_specific_data);
1788
1789                    (*pStreamHandler)->m_decoderSpecificInfoSize =
1790                        codec_specific_data_size;
1791                    if ((*pStreamHandler)->m_decoderSpecificInfoSize != 0) {
1792                        DecoderSpecific = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1793                            (*pStreamHandler)->m_decoderSpecificInfoSize,
1794                            M4READER_3GP, (M4OSA_Char*)"AAC DecoderSpecific" );
1795                        if (M4OSA_NULL == DecoderSpecific) {
1796                            return M4ERR_ALLOC;
1797                        }
1798                        memcpy((void *)DecoderSpecific,
1799                            (void *)codec_specific_data,
1800                            codec_specific_data_size);
1801                        (*pStreamHandler)->m_pDecoderSpecificInfo =
1802                            DecoderSpecific;
1803                    } else {
1804                        (*pStreamHandler)->m_pDecoderSpecificInfo = M4OSA_NULL;
1805                    }
1806                }
1807            } else {
1808                ALOGV("VideoEditor3gpReader_getNextStream mStreamType: none ");
1809                return M4ERR_READER_UNKNOWN_STREAM_TYPE;
1810            }
1811        } else {
1812            ALOGV("VE noaudio-video stream:pC->mCurrTrack = %d ",pC->mCurrTrack);
1813            pC->mCurrTrack++; //Increment current track to get the next track
1814            return M4ERR_READER_UNKNOWN_STREAM_TYPE;
1815        }
1816        ALOGV("VE StreamType: %d, stremhandler %x",streamType, *pStreamHandler );
1817        (*pStreamHandler)->m_streamType = streamType;
1818        (*pStreamHandler)->m_streamId   = pC->mStreamId;
1819        (*pStreamHandler)->m_pUserData  = M4OSA_NULL;
1820        (*pStreamHandler)->m_structSize = sizeof(M4_StreamHandler);
1821        (*pStreamHandler)->m_bStreamIsOK = M4OSA_TRUE;
1822
1823        meta->findInt64(kKeyDuration,
1824            (int64_t*)&(Duration));
1825
1826        (*pStreamHandler)->m_duration = (int32_t)(Duration / 1000);
1827
1828        pC->mMaxDuration = ((*pStreamHandler)->m_duration);
1829        ALOGV("VE str duration duration: %d ", (*pStreamHandler)->m_duration);
1830
1831        /* In AAC case: Put the first AU in pAudioStreamHandler->m_pUserData
1832         *since decoder has to know if stream contains SBR data(Implicit sig) */
1833        if(M4DA_StreamTypeAudioAac == (*pStreamHandler)->m_streamType) {
1834            M4READER_AudioSbrUserdata*  pAudioSbrUserdata;
1835
1836            pAudioSbrUserdata = (M4READER_AudioSbrUserdata*)M4OSA_32bitAlignedMalloc(
1837                sizeof(M4READER_AudioSbrUserdata),M4READER_3GP,
1838                (M4OSA_Char*)"M4READER_AudioSbrUserdata");
1839            if (M4OSA_NULL == pAudioSbrUserdata) {
1840                err = M4ERR_ALLOC;
1841                goto Error;
1842            }
1843            (*pStreamHandler)->m_pUserData = pAudioSbrUserdata;
1844            pAudioSbrUserdata->m_bIsSbrEnabled = M4OSA_FALSE;
1845
1846            pAudioSbrUserdata->m_pFirstAU = (M4_AccessUnit*)M4OSA_32bitAlignedMalloc(
1847                sizeof(M4_AccessUnit),M4READER_3GP, (M4OSA_Char*)"1st AAC AU");
1848            if (M4OSA_NULL == pAudioSbrUserdata->m_pFirstAU) {
1849                pAudioSbrUserdata->m_pAacDecoderUserConfig = M4OSA_NULL;
1850                err = M4ERR_ALLOC;
1851                goto Error;
1852            }
1853            pAudioSbrUserdata->m_pAacDecoderUserConfig = (M4_AacDecoderConfig*)\
1854                M4OSA_32bitAlignedMalloc(sizeof(M4_AacDecoderConfig),M4READER_3GP,
1855                (M4OSA_Char*)"m_pAacDecoderUserConfig");
1856            if (M4OSA_NULL == pAudioSbrUserdata->m_pAacDecoderUserConfig) {
1857                err = M4ERR_ALLOC;
1858                goto Error;
1859            }
1860        }
1861        if(M4DA_StreamTypeAudioAac == (*pStreamHandler)->m_streamType) {
1862            M4_AudioStreamHandler* pAudioStreamHandler =
1863                (M4_AudioStreamHandler*)(*pStreamHandler);
1864            M4READER_AudioSbrUserdata* pUserData = (M4READER_AudioSbrUserdata*)\
1865                (pAudioStreamHandler->m_basicProperties.m_pUserData);
1866
1867            err = VideoEditor3gpReader_fillAuStruct(pC, (*pStreamHandler),
1868                (M4_AccessUnit*)pUserData->m_pFirstAU);
1869            if (M4NO_ERROR != err) {
1870                goto Error;
1871            }
1872            err = VideoEditor3gpReader_getNextAu(pC, (*pStreamHandler),
1873                (M4_AccessUnit*)pUserData->m_pFirstAU);
1874
1875            /*
1876             * 1. "M4WAR_NO_MORE_AU == err" indicates that there is no more
1877             * access unit from the current track. In other words, there
1878             * is only a single access unit from the current track, and
1879             * the parsing of this track has reached EOS. The reason why
1880             * the first access unit needs to be parsed here is because for
1881             * some audio codec (like AAC), the very first access unit
1882             * must be decoded before its configuration/encoding parameters
1883             * (such as # of channels and sample rate) can be correctly
1884             * determined.
1885             *
1886             * 2. "trackCount > pC->mCurrTrack" indicates that there are other
1887             * tracks to be parsed, in addition to the current track.
1888             *
1889             * When both conditions 1 & 2 hold, other tracks should be
1890             * parsed. Thus, we should not bail out.
1891             */
1892            if (M4WAR_NO_MORE_AU == err && trackCount > pC->mCurrTrack) {
1893                err = M4NO_ERROR;
1894            }
1895
1896            if (M4NO_ERROR != err) {
1897                goto Error;
1898            }
1899            err = VideoEditor3gpReader_reset(pC, (*pStreamHandler));
1900            if (M4NO_ERROR != err) {
1901                goto Error;
1902            }
1903        }
1904    }
1905    pC->mCurrTrack++; //Increment the current track to get next track
1906    ALOGV("pC->mCurrTrack = %d",pC->mCurrTrack);
1907
1908    if (!haveAudio && !haveVideo) {
1909        *pMediaFamily=M4READER_kMediaFamilyUnknown;
1910        return M4ERR_READER_UNKNOWN_STREAM_TYPE;
1911    }
1912Error:
1913    ALOGV("VideoEditor3gpReader_getNextStreamHandler end error = %d",err);
1914    return err;
1915}
1916
1917M4OSA_ERR VideoEditor3gpReader_getPrevRapTime(M4OSA_Context context,
1918    M4_StreamHandler *pStreamHandler, M4OSA_Int32* pTime)
1919{
1920    VideoEditor3gpReader_Context *pC = (VideoEditor3gpReader_Context*)context;
1921    M4OSA_ERR err = M4NO_ERROR;
1922    MediaBuffer *mMediaBuffer = M4OSA_NULL;
1923    MediaSource::ReadOptions options;
1924    M4OSA_Time time64;
1925    int64_t tempTime64 = 0;
1926    status_t error;
1927
1928    ALOGV("VideoEditor3gpReader_getPrevRapTime begin");
1929
1930    M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER,
1931        "VideoEditor3gpReader_getPrevRapTime: invalid context");
1932    M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
1933        "VideoEditor3gpReader_getPrevRapTime invalid pointer to StreamHandler");
1934    M4OSA_DEBUG_IF1((pTime == 0), M4ERR_PARAMETER,
1935        "VideoEditor3gpReader_getPrevRapTime: invalid time pointer");
1936    if (*pTime == (pStreamHandler->m_duration)) {
1937        *pTime -= 1;
1938    }
1939
1940    time64 = (M4OSA_Time)*pTime * 1000;
1941
1942    ALOGV("VideoEditor3gpReader_getPrevRapTime seek time: %ld",time64);
1943    options.setSeekTo(time64, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
1944    error = pC->mVideoSource->read(&mMediaBuffer, &options);
1945    if (error != OK) {
1946        //Can not get the previous Sync.
1947        //Must be end of stream.
1948        return M4WAR_NO_MORE_AU;
1949    }
1950
1951    mMediaBuffer->meta_data()->findInt64(kKeyTime, (int64_t*)&tempTime64);
1952    ALOGV("VideoEditor3gpReader_getPrevRapTime read time %ld, %x", tempTime64,
1953        mMediaBuffer);
1954
1955    *pTime = (M4OSA_Int32)(tempTime64 / 1000);
1956
1957    if(mMediaBuffer != M4OSA_NULL) {
1958        ALOGV(" mMediaBuffer size = %d length %d", mMediaBuffer->size(),
1959            mMediaBuffer->range_length());
1960        mMediaBuffer->release();
1961        mMediaBuffer = M4OSA_NULL;
1962    }
1963    options.clearSeekTo();
1964
1965    if(error != OK) {
1966        ALOGV("VideoEditor3gpReader_getPrevRapTime end \
1967            M4WAR_READER_INFORMATION_NOT_PRESENT");
1968        return M4WAR_READER_INFORMATION_NOT_PRESENT;
1969    } else {
1970        ALOGV("VideoEditor3gpReader_getPrevRapTime end: err %x", err);
1971        err = M4NO_ERROR;
1972        return err;
1973    }
1974}
1975
1976extern "C" {
1977M4OSA_ERR VideoEditor3gpReader_getInterface(M4READER_MediaType *pMediaType,
1978        M4READER_GlobalInterface **pRdrGlobalInterface,
1979        M4READER_DataInterface **pRdrDataInterface) {
1980
1981    M4OSA_ERR err = M4NO_ERROR;
1982
1983    VIDEOEDITOR_CHECK(M4OSA_NULL != pMediaType,      M4ERR_PARAMETER);
1984    VIDEOEDITOR_CHECK(M4OSA_NULL != pRdrGlobalInterface, M4ERR_PARAMETER);
1985    VIDEOEDITOR_CHECK(M4OSA_NULL != pRdrDataInterface, M4ERR_PARAMETER);
1986
1987    ALOGV("VideoEditor3gpReader_getInterface begin");
1988    ALOGV("VideoEditor3gpReader_getInterface %d 0x%x 0x%x", *pMediaType,
1989        *pRdrGlobalInterface,*pRdrDataInterface);
1990
1991    SAFE_MALLOC(*pRdrGlobalInterface, M4READER_GlobalInterface, 1,
1992        "VideoEditor3gpReader_getInterface");
1993    SAFE_MALLOC(*pRdrDataInterface, M4READER_DataInterface, 1,
1994        "VideoEditor3gpReader_getInterface");
1995
1996    *pMediaType = M4READER_kMediaType3GPP;
1997
1998    (*pRdrGlobalInterface)->m_pFctCreate       = VideoEditor3gpReader_create;
1999    (*pRdrGlobalInterface)->m_pFctDestroy      = VideoEditor3gpReader_destroy;
2000    (*pRdrGlobalInterface)->m_pFctOpen         = VideoEditor3gpReader_open;
2001    (*pRdrGlobalInterface)->m_pFctClose        = VideoEditor3gpReader_close;
2002    (*pRdrGlobalInterface)->m_pFctGetOption    = VideoEditor3gpReader_getOption;
2003    (*pRdrGlobalInterface)->m_pFctSetOption    = VideoEditor3gpReader_setOption;
2004    (*pRdrGlobalInterface)->m_pFctGetNextStream =
2005        VideoEditor3gpReader_getNextStreamHandler;
2006    (*pRdrGlobalInterface)->m_pFctFillAuStruct =
2007        VideoEditor3gpReader_fillAuStruct;
2008    (*pRdrGlobalInterface)->m_pFctStart        = M4OSA_NULL;
2009    (*pRdrGlobalInterface)->m_pFctStop         = M4OSA_NULL;
2010    (*pRdrGlobalInterface)->m_pFctJump         = VideoEditor3gpReader_jump;
2011    (*pRdrGlobalInterface)->m_pFctReset        = VideoEditor3gpReader_reset;
2012    (*pRdrGlobalInterface)->m_pFctGetPrevRapTime =
2013        VideoEditor3gpReader_getPrevRapTime;
2014    (*pRdrDataInterface)->m_pFctGetNextAu      = VideoEditor3gpReader_getNextAu;
2015    (*pRdrDataInterface)->m_readerContext      = M4OSA_NULL;
2016
2017cleanUp:
2018    if( M4NO_ERROR == err ) {
2019        ALOGV("VideoEditor3gpReader_getInterface no error");
2020    } else {
2021        SAFE_FREE(*pRdrGlobalInterface);
2022        SAFE_FREE(*pRdrDataInterface);
2023
2024        ALOGV("VideoEditor3gpReader_getInterface ERROR 0x%X", err);
2025    }
2026    ALOGV("VideoEditor3gpReader_getInterface end");
2027    return err;
2028}
2029
2030}  /* extern "C" */
2031
2032}  /* namespace android */
2033
2034
2035