Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 /**
     17 *************************************************************************
     18 * @file   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  */
     62 namespace 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 */
     73 const 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 */
     86 typedef 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 */
    115 typedef 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 */
    131 static 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 */
    157 static 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 */
    169 static 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 */
    210 static 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 
    231 static 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 
    271 static 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 */
    291 static 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 
    302 static 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 
    311 static void VideoEditor3gpReader_MPEG4BitStreamParserInit(void** pContext,
    312         void* pBitStream, M4OSA_Int32 size) {
    313     VideoEditor3gpReader_BitStreamParserInit(pContext, pBitStream, size);
    314 }
    315 static 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 */
    348 static 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 
    385 M4OSA_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 
    412 cleanUp:
    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 
    432 M4OSA_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 
    448 cleanUp:
    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 
    475 M4OSA_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 */
    526 M4OSA_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 */
    633 M4OSA_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 */
    762 M4OSA_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 */
    813 M4OSA_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 */
    853 M4OSA_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 */
    921 M4OSA_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 */
    966 M4OSA_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(( pC== 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 */
   1154 static 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 pcture 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;
   1381 cleanup:
   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 */
   1401 M4OSA_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     }
   1912 Error:
   1913     ALOGV("VideoEditor3gpReader_getNextStreamHandler end error = %d",err);
   1914     return err;
   1915 }
   1916 
   1917 M4OSA_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 
   1976 extern "C" {
   1977 M4OSA_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 
   2017 cleanUp:
   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