• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
VideoEditor3gpReader_BitStreamParserInit(void ** pContext,void * pBitStream,M4OSA_Int32 size)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 */
VideoEditor3gpReader_BitStreamParserCleanUp(void * pContext)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 */
VideoEditor3gpReader_BitStreamParserShowBits(void * pContext,M4OSA_Int32 length)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 */
VideoEditor3gpReader_BitStreamParserFlushBits(void * pContext,M4OSA_Int32 length)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 
VideoEditor3gpReader_BitStreamParserGetBits(void * pContext,M4OSA_Int32 bitPos,M4OSA_Int32 bitLength)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 
VideoEditor3gpReader_BitStreamParserRestart(void * pContext)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 */
VideoEditor3gpReader_GetCurrentbitStreamPointer(void * pContext)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 
VideoEditor3gpReader_BitStreamParserGetSize(void * pContext)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 
VideoEditor3gpReader_MPEG4BitStreamParserInit(void ** pContext,void * pBitStream,M4OSA_Int32 size)311 static void VideoEditor3gpReader_MPEG4BitStreamParserInit(void** pContext,
312         void* pBitStream, M4OSA_Int32 size) {
313     VideoEditor3gpReader_BitStreamParserInit(pContext, pBitStream, size);
314 }
VideoEditor3gpReader_GetMpegLengthFromInteger(void * pContext,M4OSA_UInt32 val)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 */
VideoEditor3gpReader_GetMpegLengthFromStream(void * pContext)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 
VideoEditor3gpReader_create(M4OSA_Context * pContext)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 
VideoEditor3gpReader_destroy(M4OSA_Context pContext)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 
VideoEditor3gpReader_open(M4OSA_Context pContext,M4OSA_Void * pFileDescriptor)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 */
VideoEditor3gpReader_close(M4OSA_Context context)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 */
VideoEditor3gpReader_getOption(M4OSA_Context context,M4OSA_OptionID optionId,M4OSA_DataOption pValue)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 */
VideoEditor3gpReader_setOption(M4OSA_Context context,M4OSA_OptionID optionId,M4OSA_DataOption pValue)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 */
VideoEditor3gpReader_fillAuStruct(M4OSA_Context context,M4_StreamHandler * pStreamHandler,M4_AccessUnit * pAccessUnit)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 */
VideoEditor3gpReader_jump(M4OSA_Context context,M4_StreamHandler * pStreamHandler,M4OSA_Int32 * pTime)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 */
VideoEditor3gpReader_reset(M4OSA_Context context,M4_StreamHandler * pStreamHandler)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 */
VideoEditor3gpReader_getNextAu(M4OSA_Context context,M4_StreamHandler * pStreamHandler,M4_AccessUnit * pAccessUnit)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((pReaderContext == 0), M4ERR_PARAMETER,
979         "VideoEditor3gpReader_getNextAu: invalid context");
980     M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
981         "VideoEditor3gpReader_getNextAu: invalid pointer to M4_StreamHandler");
982     M4OSA_DEBUG_IF1((pAccessUnit == 0),    M4ERR_PARAMETER,
983         "VideoEditor3gpReader_getNextAu: invalid pointer to M4_AccessUnit");
984 
985     ALOGV("VideoEditor3gpReader_getNextAu begin");
986 
987     if (pStreamHandler == (M4_StreamHandler*)pC->mAudioStreamHandler) {
988         ALOGV("VideoEditor3gpReader_getNextAu audio stream");
989         pAu = &pC->mAudioAu;
990         if (pC->mAudioSeeking == M4OSA_TRUE) {
991             ALOGV("VideoEditor3gpReader_getNextAu audio seek time: %ld",
992                 pC->mAudioSeekTime);
993             options.setSeekTo(pC->mAudioSeekTime);
994             pC->mAudioSource->read(&mMediaBuffer, &options);
995 
996             mMediaBuffer->meta_data()->findInt64(kKeyTime,
997                 (int64_t*)&tempTime64);
998             options.clearSeekTo();
999             pC->mAudioSeeking = M4OSA_FALSE;
1000             flag = M4OSA_TRUE;
1001         } else {
1002             ALOGV("VideoEditor3gpReader_getNextAu audio no seek:");
1003             pC->mAudioSource->read(&mMediaBuffer, &options);
1004             if (mMediaBuffer != NULL) {
1005                 mMediaBuffer->meta_data()->findInt64(kKeyTime,
1006                     (int64_t*)&tempTime64);
1007             }
1008         }
1009     } else if (pStreamHandler == (M4_StreamHandler*)pC->mVideoStreamHandler) {
1010         ALOGV("VideoEditor3gpReader_getNextAu video steram ");
1011         pAu = &pC->mVideoAu;
1012         if(pC->mVideoSeeking == M4OSA_TRUE) {
1013             flag = M4OSA_TRUE;
1014             ALOGV("VideoEditor3gpReader_getNextAu seek: %ld",pC->mVideoSeekTime);
1015             options.setSeekTo(pC->mVideoSeekTime,
1016                 MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
1017             do
1018             {
1019                 if (mMediaBuffer != NULL) {
1020                     ALOGV("VideoEditor3gpReader_getNextAu free the MediaBuffer");
1021                     mMediaBuffer->release();
1022                 }
1023                 error = pC->mVideoSource->read(&mMediaBuffer, &options);
1024                 ALOGV("VE3gpReader_getNextAu MediaBuffer %x , error %d",
1025                     mMediaBuffer, error);
1026                 if (mMediaBuffer != NULL)
1027                 {
1028                     if (mMediaBuffer->meta_data()->findInt32(kKeyIsSyncFrame,
1029                         &i32Tmp) && i32Tmp) {
1030                             ALOGV("SYNC FRAME FOUND--%d", i32Tmp);
1031                         pAu->attribute = AU_RAP;
1032                     }
1033                     else {
1034                         pAu->attribute = AU_P_Frame;
1035                     }
1036                     mMediaBuffer->meta_data()->findInt64(kKeyTime,
1037                         (int64_t*)&tempTime64);
1038                 } else {
1039                     break;
1040                 }
1041                 options.clearSeekTo();
1042             } while(tempTime64 < pC->mVideoSeekTime);
1043 
1044             ALOGV("VE3gpReader_getNextAu: video  time with seek  = %lld:",
1045                 tempTime64);
1046             pC->mVideoSeeking = M4OSA_FALSE;
1047         } else {
1048             ALOGV("VideoEditor3gpReader_getNextAu video no seek:");
1049             pC->mVideoSource->read(&mMediaBuffer, &options);
1050 
1051             if(mMediaBuffer != NULL) {
1052                 if (mMediaBuffer->meta_data()->findInt32(kKeyIsSyncFrame,
1053                     &i32Tmp) && i32Tmp) {
1054                     ALOGV("SYNC FRAME FOUND--%d", i32Tmp);
1055                     pAu->attribute = AU_RAP;
1056                 }
1057                 else {
1058                     pAu->attribute = AU_P_Frame;
1059                 }
1060                 mMediaBuffer->meta_data()->findInt64(kKeyTime,
1061                     (int64_t*)&tempTime64);
1062                 ALOGV("VE3gpReader_getNextAu: video no seek time = %lld:",
1063                     tempTime64);
1064             }else {
1065                 ALOGV("VE3gpReader_getNextAu:video no seek time buffer is NULL");
1066             }
1067         }
1068     } else {
1069         ALOGV("VideoEditor3gpReader_getNextAu M4ERR_PARAMETER");
1070         return M4ERR_PARAMETER;
1071     }
1072 
1073     if (mMediaBuffer != NULL) {
1074         if( (pAu->dataAddress == NULL) ||  (pAu->size < \
1075             mMediaBuffer->range_length())) {
1076             if(pAu->dataAddress != NULL) {
1077                 free((M4OSA_Int32*)pAu->dataAddress);
1078                 pAu->dataAddress = NULL;
1079             }
1080             ALOGV("Buffer lenght = %d ,%d",(mMediaBuffer->range_length() +\
1081                 3) & ~0x3,(mMediaBuffer->range_length()));
1082 
1083             pAu->dataAddress = (M4OSA_Int32*)M4OSA_32bitAlignedMalloc(
1084                 (mMediaBuffer->range_length() + 3) & ~0x3,M4READER_3GP,
1085                     (M4OSA_Char*)"pAccessUnit->m_dataAddress" );
1086             if(pAu->dataAddress == NULL) {
1087                 ALOGV("VideoEditor3gpReader_getNextAu malloc failed");
1088                 return M4ERR_ALLOC;
1089             }
1090         }
1091         pAu->size = mMediaBuffer->range_length();
1092 
1093         memcpy((void *)pAu->dataAddress,
1094             (void *)((const char *)mMediaBuffer->data() + mMediaBuffer->range_offset()),
1095             mMediaBuffer->range_length());
1096 
1097         if( (pStreamHandler == (M4_StreamHandler*)pC->mVideoStreamHandler)  &&
1098             (pStreamHandler->m_streamType == M4DA_StreamTypeVideoMpeg4Avc) ) {
1099             M4OSA_UInt32 size = mMediaBuffer->range_length();
1100             M4OSA_UInt8 *lbuffer;
1101 
1102             lbuffer = (M4OSA_UInt8 *) pAu->dataAddress;
1103             ALOGV("pAccessUnit->m_dataAddress size = %x",size);
1104 
1105             lbuffer[0] = (size >> 24) & 0xFF;
1106             lbuffer[1] = (size >> 16) & 0xFF;
1107             lbuffer[2] = (size >> 8) & 0xFF;
1108             lbuffer[3] = (size) & 0xFF;
1109         }
1110 
1111         pAu->CTS = tempTime64;
1112 
1113         pAu->CTS = pAu->CTS / 1000; //converting the microsec to millisec
1114         ALOGV("VideoEditor3gpReader_getNextAu CTS = %ld",pAu->CTS);
1115 
1116         pAu->DTS  = pAu->CTS;
1117         if (pStreamHandler == (M4_StreamHandler*)pC->mAudioStreamHandler) {
1118             pAu->attribute = M4SYS_kFragAttrOk;
1119         }
1120         mMediaBuffer->release();
1121 
1122         pAccessUnit->m_dataAddress = (M4OSA_Int8*) pAu->dataAddress;
1123         pAccessUnit->m_size = pAu->size;
1124         pAccessUnit->m_maxsize = pAu->size;
1125         pAccessUnit->m_CTS = pAu->CTS;
1126         pAccessUnit->m_DTS = pAu->DTS;
1127         pAccessUnit->m_attribute = pAu->attribute;
1128 
1129     } else {
1130         ALOGV("VideoEditor3gpReader_getNextAu: M4WAR_NO_MORE_AU (EOS) reached");
1131         pAccessUnit->m_size = 0;
1132         err = M4WAR_NO_MORE_AU;
1133     }
1134     options.clearSeekTo();
1135 
1136     pAu->nbFrag = 0;
1137     mMediaBuffer = NULL;
1138     ALOGV("VideoEditor3gpReader_getNextAu end ");
1139 
1140     return err;
1141 }
1142 /**
1143  *******************************************************************************
1144  * @brief   Split the AVC DSI in its different components and write it in
1145  *          ONE memory buffer
1146  * @note
1147  * @param   pStreamHandler:         (IN/OUT) The MPEG4-AVC stream
1148  * @param   pDecoderConfigLocal:    (IN) The DSI buffer
1149  * @param   decoderConfigSizeLocal: (IN) The DSI buffer size
1150  * @return  M4NO_ERROR              there is no error
1151  * @return  ERR_FILE_SYNTAX_ERROR   pDecoderConfigLocal is NULL
1152  *******************************************************************************
1153 */
VideoEditor3gpReader_AnalyseAvcDsi(M4_StreamHandler * pStreamHandler,M4OSA_Int32 * pDecoderConfigLocal,M4OSA_Int32 decoderConfigSizeLocal)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 pîcture parameter set*/
1346 
1347         for (i=0; i < pAvcSpecInfo->m_numOfPictureParameterSets; i++) {
1348             pAvcSpecInfo->m_pPictureParameterSet[i].m_length =
1349                 (M4OSA_UInt16)VideoEditor3gpReader_BitStreamParserShowBits(
1350                 pBitParserContext, 16);
1351             VideoEditor3gpReader_BitStreamParserFlushBits(pBitParserContext,16);
1352 
1353             pAvcSpecInfo->m_pPictureParameterSet[i].m_pParameterSetUnit =
1354                 (M4OSA_UInt8*)pPos;   /**< current position in the buffer */
1355             pPos += pAvcSpecInfo->m_pPictureParameterSet[i].m_length;
1356                 /**< increment the position in the buffer */
1357             for (j=0; j<pAvcSpecInfo->m_pPictureParameterSet[i].m_length; j++) {
1358                 pAvcSpecInfo->m_pPictureParameterSet[i].m_pParameterSetUnit[j] =
1359                     (M4OSA_UInt8)VideoEditor3gpReader_BitStreamParserShowBits(
1360                     pBitParserContext, 8);
1361                 VideoEditor3gpReader_BitStreamParserFlushBits(
1362                     pBitParserContext, 8);
1363             }
1364         }
1365         VideoEditor3gpReader_BitStreamParserCleanUp(pBitParserContext);
1366         pStreamHandler->m_decoderSpecificInfoSize = uiSpecInfoSize;
1367         pStreamHandler->m_pDecoderSpecificInfo = (M4OSA_UInt8*)pAvcSpecInfo;
1368     }
1369     pStreamHandler->m_H264decoderSpecificInfoSize  =  decoderConfigSizeLocal;
1370     pStreamHandler->m_pH264DecoderSpecificInfo  = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1371         decoderConfigSizeLocal, M4READER_3GP,
1372         (M4OSA_Char*)"MPEG-4 AVC DecoderSpecific");
1373     if (M4OSA_NULL == pStreamHandler->m_pH264DecoderSpecificInfo) {
1374         goto cleanup;
1375     }
1376 
1377     memcpy((void * ) pStreamHandler->m_pH264DecoderSpecificInfo,
1378         (void * )pDecoderConfigLocal,
1379         pStreamHandler->m_H264decoderSpecificInfoSize);
1380     return M4NO_ERROR;
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 */
VideoEditor3gpReader_getNextStreamHandler(M4OSA_Context context,M4READER_MediaFamily * pMediaFamily,M4_StreamHandler ** pStreamHandler)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,
1487                     (int64_t*)&(Duration));
1488                 ((*pStreamHandler)->m_duration) =
1489                     (int32_t)((Duration)/1000); // conversion to mS
1490                 pC->mMaxDuration = ((*pStreamHandler)->m_duration);
1491                 ALOGV("VideoEditor3gpReader_getNextStreamHandler m_duration %d",
1492                     (*pStreamHandler)->m_duration);
1493 
1494                 off64_t fileSize = 0;
1495                 pC->mDataSource->getSize(&fileSize);
1496                 pC->mFileSize  = fileSize;
1497 
1498                 ALOGV("VideoEditor3gpReader_getNextStreamHandler m_fileSize %d",
1499                     pC->mFileSize);
1500 
1501                 meta->findInt32(kKeyMaxInputSize, (int32_t*)&(maxAUSize));
1502                 if(maxAUSize == 0) {
1503                     maxAUSize = 70000;
1504                 }
1505                 (*pStreamHandler)->m_maxAUSize = maxAUSize;
1506                 ALOGV("<<<<<<<<<<   video: mMaxAUSize from MP4 extractor: %d",
1507                     (*pStreamHandler)->m_maxAUSize);
1508 
1509                 ((M4_StreamHandler*)pVideoStreamHandler)->m_averageBitRate =
1510                         (pC->mFileSize * 8000)/pC->mMaxDuration;
1511                 ALOGV("VideoEditor3gpReader_getNextStreamHandler m_averageBitrate %d",
1512                     ((M4_StreamHandler*)pVideoStreamHandler)->m_averageBitRate);
1513 
1514 
1515                 meta->findInt32(kKeyFrameRate,
1516                     (int32_t*)&(avgFPS));
1517                 ALOGV("<<<<<<<<<<   video: Average FPS from MP4 extractor: %d",
1518                     avgFPS);
1519 
1520                 pVideoStreamHandler->m_averageFrameRate =(M4OSA_Float) avgFPS;
1521                 ALOGV("<<<<<<<<<<   video: Average FPS from MP4 extractor in FLOAT: %f",
1522                     pVideoStreamHandler->m_averageFrameRate);
1523 
1524                 // Get the video rotation degree
1525                 int32_t rotationDegree;
1526                 if(!meta->findInt32(kKeyRotation, &rotationDegree)) {
1527                     rotationDegree = 0;
1528                 }
1529                 pVideoStreamHandler->videoRotationDegrees = rotationDegree;
1530 
1531                 pC->mVideoStreamHandler =
1532                     (M4_StreamHandler*)(pVideoStreamHandler);
1533 
1534                 /* Get the DSI info */
1535                 if(M4DA_StreamTypeVideoH263 == streamType) {
1536                     if (meta->findData(kKeyD263, &type, &data, &size)) {
1537                         (*pStreamHandler)->m_decoderSpecificInfoSize = size;
1538                         if ((*pStreamHandler)->m_decoderSpecificInfoSize != 0) {
1539                             DecoderSpecific = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1540                                 (*pStreamHandler)->m_decoderSpecificInfoSize,
1541                                 M4READER_3GP,(M4OSA_Char*)"H263 DSI");
1542                             if (M4OSA_NULL == DecoderSpecific) {
1543                                 return M4ERR_ALLOC;
1544                             }
1545                             memcpy((void *)DecoderSpecific,
1546                                 (void *)data, size);
1547                             (*pStreamHandler)->m_pDecoderSpecificInfo =
1548                                 DecoderSpecific;
1549                         }
1550                         else {
1551                             (*pStreamHandler)->m_pDecoderSpecificInfo =
1552                                 M4OSA_NULL;
1553                             (*pStreamHandler)->m_decoderSpecificInfoSize = 0;
1554                         }
1555                         (*pStreamHandler)->m_pESDSInfo = M4OSA_NULL;
1556                         (*pStreamHandler)->m_ESDSInfoSize = 0;
1557                         (*pStreamHandler)->m_pH264DecoderSpecificInfo = M4OSA_NULL;
1558                         (*pStreamHandler)->m_H264decoderSpecificInfoSize = 0;
1559                     } else {
1560                         ALOGV("VE_getNextStreamHandler: H263 dsi not found");
1561                         (*pStreamHandler)->m_pDecoderSpecificInfo = M4OSA_NULL;
1562                         (*pStreamHandler)->m_decoderSpecificInfoSize = 0;
1563                         (*pStreamHandler)->m_H264decoderSpecificInfoSize = 0;
1564                         (*pStreamHandler)->m_pH264DecoderSpecificInfo =
1565                             M4OSA_NULL;
1566                         (*pStreamHandler)->m_pESDSInfo = M4OSA_NULL;
1567                         (*pStreamHandler)->m_ESDSInfoSize = 0;
1568                     }
1569                 }
1570                 else if(M4DA_StreamTypeVideoMpeg4Avc == streamType) {
1571                     if(meta->findData(kKeyAVCC, &type, &data, &size)) {
1572                         decoderSpecificInfoSize = size;
1573                         if (decoderSpecificInfoSize != 0) {
1574                             DecoderSpecificInfo = (M4OSA_Int8*)M4OSA_32bitAlignedMalloc(
1575                                 decoderSpecificInfoSize, M4READER_3GP,
1576                                 (M4OSA_Char*)"H264 DecoderSpecific" );
1577                             if (M4OSA_NULL == DecoderSpecificInfo) {
1578                                 ALOGV("VideoEditor3gp_getNextStream is NULL ");
1579                                 return M4ERR_ALLOC;
1580                             }
1581                             memcpy((void *)DecoderSpecificInfo,
1582                                 (void *)data, decoderSpecificInfoSize);
1583                         } else {
1584                             ALOGV("DSI Size %d", decoderSpecificInfoSize);
1585                             DecoderSpecificInfo = M4OSA_NULL;
1586                         }
1587                     }
1588                     (*pStreamHandler)->m_pESDSInfo = M4OSA_NULL;
1589                     (*pStreamHandler)->m_ESDSInfoSize = 0;
1590 
1591                     err = VideoEditor3gpReader_AnalyseAvcDsi(*pStreamHandler,
1592                     (M4OSA_Int32*)DecoderSpecificInfo, decoderSpecificInfoSize);
1593 
1594                     if (M4NO_ERROR != err) {
1595                         return err;
1596                     }
1597                     ALOGV("decsize %d, h264decsize %d: %d", (*pStreamHandler)->\
1598                         m_decoderSpecificInfoSize, (*pStreamHandler)->\
1599                         m_H264decoderSpecificInfoSize);
1600 
1601                     if(M4OSA_NULL != DecoderSpecificInfo) {
1602                         free(DecoderSpecificInfo);
1603                         DecoderSpecificInfo = M4OSA_NULL;
1604                     }
1605                 } else if( (M4DA_StreamTypeVideoMpeg4 == streamType) ) {
1606                     if (meta->findData(kKeyESDS, &type, &data, &size)) {
1607                         ESDS esds((const char *)data, size);
1608                         CHECK_EQ(esds.InitCheck(), (status_t)OK);
1609 
1610                         (*pStreamHandler)->m_ESDSInfoSize = size;
1611                         (*pStreamHandler)->m_pESDSInfo = (M4OSA_UInt8*)\
1612                         M4OSA_32bitAlignedMalloc((*pStreamHandler)->m_ESDSInfoSize,
1613                         M4READER_3GP, (M4OSA_Char*)"M4V DecoderSpecific" );
1614                         if (M4OSA_NULL == (*pStreamHandler)->m_pESDSInfo) {
1615                             return M4ERR_ALLOC;
1616                         }
1617                         memcpy((void *)(*pStreamHandler)->\
1618                             m_pESDSInfo, (void *)data, size);
1619 
1620                         esds.getCodecSpecificInfo(&codec_specific_data,
1621                             &codec_specific_data_size);
1622                         ALOGV("VE MP4 dsisize: %d, %x", codec_specific_data_size,
1623                             codec_specific_data);
1624 
1625                         (*pStreamHandler)->m_decoderSpecificInfoSize =
1626                             codec_specific_data_size;
1627                         if ((*pStreamHandler)->m_decoderSpecificInfoSize != 0) {
1628                             DecoderSpecific = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1629                                 (*pStreamHandler)->m_decoderSpecificInfoSize,
1630                                 M4READER_3GP, (M4OSA_Char*)" DecoderSpecific" );
1631                             if (M4OSA_NULL == DecoderSpecific) {
1632                                 return M4ERR_ALLOC;
1633                             }
1634                             memcpy((void *)DecoderSpecific,
1635                                 (void *)codec_specific_data,
1636                                 codec_specific_data_size);
1637                             (*pStreamHandler)->m_pDecoderSpecificInfo =
1638                                 DecoderSpecific;
1639                         }
1640                         else {
1641                             (*pStreamHandler)->m_pDecoderSpecificInfo =
1642                                 M4OSA_NULL;
1643                         }
1644                         (*pStreamHandler)->m_pH264DecoderSpecificInfo =
1645                             M4OSA_NULL;
1646                         (*pStreamHandler)->m_H264decoderSpecificInfoSize = 0;
1647                     }
1648                 } else {
1649                     ALOGV("VideoEditor3gpReader_getNextStream NO video stream");
1650                     return M4ERR_READER_UNKNOWN_STREAM_TYPE;
1651                 }
1652             }
1653             else {
1654                 ALOGV("VideoEditor3gpReader_getNextStream NO video stream");
1655                 return M4ERR_READER_UNKNOWN_STREAM_TYPE;
1656             }
1657 
1658         } else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
1659             ALOGV("VideoEditor3gpReader_getNextStream audio getTrack called");
1660             pC->mAudioSource = pC->mExtractor->getTrack(pC->mCurrTrack);
1661             pC->mAudioSource->start();
1662             *pMediaFamily = M4READER_kMediaFamilyAudio;
1663 
1664             if(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
1665                 streamType = M4DA_StreamTypeAudioAmrNarrowBand;
1666             } else if(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
1667                 streamType = M4DA_StreamTypeAudioAmrWideBand;
1668             }
1669             else if(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1670                 streamType = M4DA_StreamTypeAudioAac;
1671             } else {
1672                 ALOGV("VideoEditor3gpReader_getNextStrea streamtype Unknown ");
1673             }
1674             if(streamType != M4DA_StreamTypeUnknown) {
1675                 pC->mStreamType = streamType;
1676                 pC->mStreamId = pC->mCurrTrack;
1677 
1678                 ALOGV("VE streamtype %d ,id %d",  streamType, pC->mCurrTrack);
1679 
1680                 pAudioStreamHandler = (M4_AudioStreamHandler*)M4OSA_32bitAlignedMalloc
1681                     (sizeof(M4_AudioStreamHandler), M4READER_3GP,
1682                     (M4OSA_Char*)"M4_AudioStreamHandler");
1683                 if (M4OSA_NULL == pAudioStreamHandler) {
1684                     return M4ERR_ALLOC;
1685                 }
1686                 pAudioStreamHandler->m_structSize=sizeof(M4_AudioStreamHandler);
1687                 pAudioStreamHandler->m_byteSampleSize   = 0;
1688                 pAudioStreamHandler->m_nbChannels       = 0;
1689                 pAudioStreamHandler->m_samplingFrequency= 0;
1690                 pAudioStreamHandler->m_byteFrameLength  = 0;
1691 
1692                 (*pStreamHandler) = (M4_StreamHandler*)(pAudioStreamHandler);
1693                 pC->mAudioStreamHandler =
1694                     (M4_StreamHandler*)(pAudioStreamHandler);
1695                 (*pStreamHandler)->m_averageBitRate = 0;
1696                 haveAudio = true;
1697                 pC->mAudioStreamHandler=(M4_StreamHandler*)pAudioStreamHandler;
1698                 pC->mAudioStreamHandler->m_pESDSInfo = M4OSA_NULL;
1699                 pC->mAudioStreamHandler->m_ESDSInfoSize = 0;
1700 
1701                 meta->findInt32(kKeyMaxInputSize, (int32_t*)&(maxAUSize));
1702                 if(maxAUSize == 0) {
1703                     maxAUSize = 70000;
1704                 }
1705                 (*pStreamHandler)->m_maxAUSize = maxAUSize;
1706                 ALOGV("VE Audio mMaxAUSize from MP4 extractor: %d", maxAUSize);
1707             }
1708             if((M4DA_StreamTypeAudioAmrNarrowBand == streamType) ||
1709                 (M4DA_StreamTypeAudioAmrWideBand == streamType)) {
1710                 M4OSA_UInt32 freqIndex = 0; /**< AMR NB */
1711                 M4OSA_UInt32 modeSet;
1712                 M4OSA_UInt32 i;
1713                 M4OSA_Context pBitParserContext = M4OSA_NULL;
1714 
1715                 if(M4DA_StreamTypeAudioAmrWideBand == streamType) {
1716                     freqIndex = 1; /**< AMR WB */
1717                 }
1718 
1719                 if (meta->findData(kKeyESDS, &type, &data, &size)) {
1720                     ESDS esds((const char *)data, size);
1721                     CHECK_EQ(esds.InitCheck(), (status_t)OK);
1722 
1723                     esds.getCodecSpecificInfo(&codec_specific_data,
1724                         &codec_specific_data_size);
1725                     (*pStreamHandler)->m_decoderSpecificInfoSize =
1726                         codec_specific_data_size;
1727 
1728                     if ((*pStreamHandler)->m_decoderSpecificInfoSize != 0) {
1729                         DecoderSpecific = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1730                             (*pStreamHandler)->m_decoderSpecificInfoSize,
1731                             M4READER_3GP, (M4OSA_Char*)"AMR DecoderSpecific" );
1732                         if (M4OSA_NULL == DecoderSpecific) {
1733                             return M4ERR_ALLOC;
1734                         }
1735                         memcpy((void *)DecoderSpecific,
1736                             (void *)codec_specific_data,
1737                             codec_specific_data_size);
1738                         (*pStreamHandler)->m_pDecoderSpecificInfo =
1739                             DecoderSpecific;
1740                     } else {
1741                         (*pStreamHandler)->m_pDecoderSpecificInfo = M4OSA_NULL;
1742                     }
1743                 } else {
1744                     M4OSA_UChar AmrDsi[] =
1745                         {'P','H','L','P',0x00, 0x00, 0x80, 0x00, 0x01,};
1746                     (*pStreamHandler)->m_decoderSpecificInfoSize = 9;
1747                     DecoderSpecific = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1748                         (*pStreamHandler)->m_decoderSpecificInfoSize,
1749                         M4READER_3GP, (M4OSA_Char*)"PHLP DecoderSpecific" );
1750                     if (M4OSA_NULL == DecoderSpecific) {
1751                         return M4ERR_ALLOC;
1752                     }
1753                     if(freqIndex ==0) {
1754                         AmrDsi[8] = 0x01;
1755                     } else {
1756                         AmrDsi[8] = 0x02;
1757                     }
1758                     for(i = 0; i< 9; i++) {
1759                         DecoderSpecific[i] = AmrDsi[i];
1760                     }
1761                     (*pStreamHandler)->m_pDecoderSpecificInfo = DecoderSpecific;
1762                 }
1763                 (*pStreamHandler)->m_averageBitRate =
1764                     VideoEditor3gpReader_AmrBitRate[freqIndex][7];
1765             } else if((M4DA_StreamTypeAudioAac == streamType)) {
1766                 if (meta->findData(kKeyESDS, &type, &data, &size)) {
1767                     ESDS esds((const char *)data, size);
1768                     CHECK_EQ(esds.InitCheck(), (status_t)OK);
1769 
1770                     (*pStreamHandler)->m_ESDSInfoSize = size;
1771                     (*pStreamHandler)->m_pESDSInfo = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1772                         (*pStreamHandler)->m_ESDSInfoSize, M4READER_3GP,
1773                         (M4OSA_Char*)"AAC DecoderSpecific" );
1774                     if (M4OSA_NULL == (*pStreamHandler)->m_pESDSInfo) {
1775                         return M4ERR_ALLOC;
1776                     }
1777                     memcpy((void *)(*pStreamHandler)->m_pESDSInfo,
1778                     (void *)data, size);
1779                     esds.getCodecSpecificInfo(&codec_specific_data,
1780                         &codec_specific_data_size);
1781 
1782                     ALOGV("VEdsi %d,%x",codec_specific_data_size,
1783                         codec_specific_data);
1784 
1785                     (*pStreamHandler)->m_decoderSpecificInfoSize =
1786                         codec_specific_data_size;
1787                     if ((*pStreamHandler)->m_decoderSpecificInfoSize != 0) {
1788                         DecoderSpecific = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
1789                             (*pStreamHandler)->m_decoderSpecificInfoSize,
1790                             M4READER_3GP, (M4OSA_Char*)"AAC DecoderSpecific" );
1791                         if (M4OSA_NULL == DecoderSpecific) {
1792                             return M4ERR_ALLOC;
1793                         }
1794                         memcpy((void *)DecoderSpecific,
1795                             (void *)codec_specific_data,
1796                             codec_specific_data_size);
1797                         (*pStreamHandler)->m_pDecoderSpecificInfo =
1798                             DecoderSpecific;
1799                     } else {
1800                         (*pStreamHandler)->m_pDecoderSpecificInfo = M4OSA_NULL;
1801                     }
1802                 }
1803             } else {
1804                 ALOGV("VideoEditor3gpReader_getNextStream mStreamType: none ");
1805                 return M4ERR_READER_UNKNOWN_STREAM_TYPE;
1806             }
1807         } else {
1808             ALOGV("VE noaudio-video stream:pC->mCurrTrack = %d ",pC->mCurrTrack);
1809             pC->mCurrTrack++; //Increment current track to get the next track
1810             return M4ERR_READER_UNKNOWN_STREAM_TYPE;
1811         }
1812         ALOGV("VE StreamType: %d, stremhandler %x",streamType, *pStreamHandler );
1813         (*pStreamHandler)->m_streamType = streamType;
1814         (*pStreamHandler)->m_streamId   = pC->mStreamId;
1815         (*pStreamHandler)->m_pUserData  = M4OSA_NULL;
1816         (*pStreamHandler)->m_structSize = sizeof(M4_StreamHandler);
1817         (*pStreamHandler)->m_bStreamIsOK = M4OSA_TRUE;
1818 
1819         meta->findInt64(kKeyDuration,
1820             (int64_t*)&(Duration));
1821 
1822         (*pStreamHandler)->m_duration = (int32_t)(Duration / 1000);
1823 
1824         pC->mMaxDuration = ((*pStreamHandler)->m_duration);
1825         ALOGV("VE str duration duration: %d ", (*pStreamHandler)->m_duration);
1826 
1827         /* In AAC case: Put the first AU in pAudioStreamHandler->m_pUserData
1828          *since decoder has to know if stream contains SBR data(Implicit sig) */
1829         if(M4DA_StreamTypeAudioAac == (*pStreamHandler)->m_streamType) {
1830             M4READER_AudioSbrUserdata*  pAudioSbrUserdata;
1831 
1832             pAudioSbrUserdata = (M4READER_AudioSbrUserdata*)M4OSA_32bitAlignedMalloc(
1833                 sizeof(M4READER_AudioSbrUserdata),M4READER_3GP,
1834                 (M4OSA_Char*)"M4READER_AudioSbrUserdata");
1835             if (M4OSA_NULL == pAudioSbrUserdata) {
1836                 err = M4ERR_ALLOC;
1837                 goto Error;
1838             }
1839             (*pStreamHandler)->m_pUserData = pAudioSbrUserdata;
1840             pAudioSbrUserdata->m_bIsSbrEnabled = M4OSA_FALSE;
1841 
1842             pAudioSbrUserdata->m_pFirstAU = (M4_AccessUnit*)M4OSA_32bitAlignedMalloc(
1843                 sizeof(M4_AccessUnit),M4READER_3GP, (M4OSA_Char*)"1st AAC AU");
1844             if (M4OSA_NULL == pAudioSbrUserdata->m_pFirstAU) {
1845                 pAudioSbrUserdata->m_pAacDecoderUserConfig = M4OSA_NULL;
1846                 err = M4ERR_ALLOC;
1847                 goto Error;
1848             }
1849             pAudioSbrUserdata->m_pAacDecoderUserConfig = (M4_AacDecoderConfig*)\
1850                 M4OSA_32bitAlignedMalloc(sizeof(M4_AacDecoderConfig),M4READER_3GP,
1851                 (M4OSA_Char*)"m_pAacDecoderUserConfig");
1852             if (M4OSA_NULL == pAudioSbrUserdata->m_pAacDecoderUserConfig) {
1853                 err = M4ERR_ALLOC;
1854                 goto Error;
1855             }
1856         }
1857         if(M4DA_StreamTypeAudioAac == (*pStreamHandler)->m_streamType) {
1858             M4_AudioStreamHandler* pAudioStreamHandler =
1859                 (M4_AudioStreamHandler*)(*pStreamHandler);
1860             M4READER_AudioSbrUserdata* pUserData = (M4READER_AudioSbrUserdata*)\
1861                 (pAudioStreamHandler->m_basicProperties.m_pUserData);
1862 
1863             err = VideoEditor3gpReader_fillAuStruct(pC, (*pStreamHandler),
1864                 (M4_AccessUnit*)pUserData->m_pFirstAU);
1865             if (M4NO_ERROR != err) {
1866                 goto Error;
1867             }
1868             err = VideoEditor3gpReader_getNextAu(pC, (*pStreamHandler),
1869                 (M4_AccessUnit*)pUserData->m_pFirstAU);
1870 
1871             /*
1872              * 1. "M4WAR_NO_MORE_AU == err" indicates that there is no more
1873              * access unit from the current track. In other words, there
1874              * is only a single access unit from the current track, and
1875              * the parsing of this track has reached EOS. The reason why
1876              * the first access unit needs to be parsed here is because for
1877              * some audio codec (like AAC), the very first access unit
1878              * must be decoded before its configuration/encoding parameters
1879              * (such as # of channels and sample rate) can be correctly
1880              * determined.
1881              *
1882              * 2. "trackCount > pC->mCurrTrack" indicates that there are other
1883              * tracks to be parsed, in addition to the current track.
1884              *
1885              * When both conditions 1 & 2 hold, other tracks should be
1886              * parsed. Thus, we should not bail out.
1887              */
1888             if (M4WAR_NO_MORE_AU == err && trackCount > pC->mCurrTrack) {
1889                 err = M4NO_ERROR;
1890             }
1891 
1892             if (M4NO_ERROR != err) {
1893                 goto Error;
1894             }
1895             err = VideoEditor3gpReader_reset(pC, (*pStreamHandler));
1896             if (M4NO_ERROR != err) {
1897                 goto Error;
1898             }
1899         }
1900     }
1901     pC->mCurrTrack++; //Increment the current track to get next track
1902     ALOGV("pC->mCurrTrack = %d",pC->mCurrTrack);
1903 
1904     if (!haveAudio && !haveVideo) {
1905         *pMediaFamily=M4READER_kMediaFamilyUnknown;
1906         return M4ERR_READER_UNKNOWN_STREAM_TYPE;
1907     }
1908 Error:
1909     ALOGV("VideoEditor3gpReader_getNextStreamHandler end error = %d",err);
1910     return err;
1911 }
1912 
VideoEditor3gpReader_getPrevRapTime(M4OSA_Context context,M4_StreamHandler * pStreamHandler,M4OSA_Int32 * pTime)1913 M4OSA_ERR VideoEditor3gpReader_getPrevRapTime(M4OSA_Context context,
1914     M4_StreamHandler *pStreamHandler, M4OSA_Int32* pTime)
1915 {
1916     VideoEditor3gpReader_Context *pC = (VideoEditor3gpReader_Context*)context;
1917     M4OSA_ERR err = M4NO_ERROR;
1918     MediaBuffer *mMediaBuffer = M4OSA_NULL;
1919     MediaSource::ReadOptions options;
1920     M4OSA_Time time64;
1921     int64_t tempTime64 = 0;
1922     status_t error;
1923 
1924     ALOGV("VideoEditor3gpReader_getPrevRapTime begin");
1925 
1926     M4OSA_DEBUG_IF1((pC == 0), M4ERR_PARAMETER,
1927         "VideoEditor3gpReader_getPrevRapTime: invalid context");
1928     M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
1929         "VideoEditor3gpReader_getPrevRapTime invalid pointer to StreamHandler");
1930     M4OSA_DEBUG_IF1((pTime == 0), M4ERR_PARAMETER,
1931         "VideoEditor3gpReader_getPrevRapTime: invalid time pointer");
1932     if (*pTime == (pStreamHandler->m_duration)) {
1933         *pTime -= 1;
1934     }
1935 
1936     time64 = (M4OSA_Time)*pTime * 1000;
1937 
1938     ALOGV("VideoEditor3gpReader_getPrevRapTime seek time: %ld",time64);
1939     options.setSeekTo(time64, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
1940     error = pC->mVideoSource->read(&mMediaBuffer, &options);
1941     if (error != OK) {
1942         //Can not get the previous Sync.
1943         //Must be end of stream.
1944         return M4WAR_NO_MORE_AU;
1945     }
1946 
1947     mMediaBuffer->meta_data()->findInt64(kKeyTime, (int64_t*)&tempTime64);
1948     ALOGV("VideoEditor3gpReader_getPrevRapTime read time %ld, %x", tempTime64,
1949         mMediaBuffer);
1950 
1951     *pTime = (M4OSA_Int32)(tempTime64 / 1000);
1952 
1953     if(mMediaBuffer != M4OSA_NULL) {
1954         ALOGV(" mMediaBuffer size = %d length %d", mMediaBuffer->size(),
1955             mMediaBuffer->range_length());
1956         mMediaBuffer->release();
1957         mMediaBuffer = M4OSA_NULL;
1958     }
1959     options.clearSeekTo();
1960 
1961     if(error != OK) {
1962         ALOGV("VideoEditor3gpReader_getPrevRapTime end \
1963             M4WAR_READER_INFORMATION_NOT_PRESENT");
1964         return M4WAR_READER_INFORMATION_NOT_PRESENT;
1965     } else {
1966         ALOGV("VideoEditor3gpReader_getPrevRapTime end: err %x", err);
1967         err = M4NO_ERROR;
1968         return err;
1969     }
1970 }
1971 
1972 extern "C" {
VideoEditor3gpReader_getInterface(M4READER_MediaType * pMediaType,M4READER_GlobalInterface ** pRdrGlobalInterface,M4READER_DataInterface ** pRdrDataInterface)1973 M4OSA_ERR VideoEditor3gpReader_getInterface(M4READER_MediaType *pMediaType,
1974         M4READER_GlobalInterface **pRdrGlobalInterface,
1975         M4READER_DataInterface **pRdrDataInterface) {
1976 
1977     M4OSA_ERR err = M4NO_ERROR;
1978 
1979     VIDEOEDITOR_CHECK(M4OSA_NULL != pMediaType,      M4ERR_PARAMETER);
1980     VIDEOEDITOR_CHECK(M4OSA_NULL != pRdrGlobalInterface, M4ERR_PARAMETER);
1981     VIDEOEDITOR_CHECK(M4OSA_NULL != pRdrDataInterface, M4ERR_PARAMETER);
1982 
1983     ALOGV("VideoEditor3gpReader_getInterface begin");
1984     ALOGV("VideoEditor3gpReader_getInterface %d 0x%x 0x%x", *pMediaType,
1985         *pRdrGlobalInterface,*pRdrDataInterface);
1986 
1987     SAFE_MALLOC(*pRdrGlobalInterface, M4READER_GlobalInterface, 1,
1988         "VideoEditor3gpReader_getInterface");
1989     SAFE_MALLOC(*pRdrDataInterface, M4READER_DataInterface, 1,
1990         "VideoEditor3gpReader_getInterface");
1991 
1992     *pMediaType = M4READER_kMediaType3GPP;
1993 
1994     (*pRdrGlobalInterface)->m_pFctCreate       = VideoEditor3gpReader_create;
1995     (*pRdrGlobalInterface)->m_pFctDestroy      = VideoEditor3gpReader_destroy;
1996     (*pRdrGlobalInterface)->m_pFctOpen         = VideoEditor3gpReader_open;
1997     (*pRdrGlobalInterface)->m_pFctClose        = VideoEditor3gpReader_close;
1998     (*pRdrGlobalInterface)->m_pFctGetOption    = VideoEditor3gpReader_getOption;
1999     (*pRdrGlobalInterface)->m_pFctSetOption    = VideoEditor3gpReader_setOption;
2000     (*pRdrGlobalInterface)->m_pFctGetNextStream =
2001         VideoEditor3gpReader_getNextStreamHandler;
2002     (*pRdrGlobalInterface)->m_pFctFillAuStruct =
2003         VideoEditor3gpReader_fillAuStruct;
2004     (*pRdrGlobalInterface)->m_pFctStart        = M4OSA_NULL;
2005     (*pRdrGlobalInterface)->m_pFctStop         = M4OSA_NULL;
2006     (*pRdrGlobalInterface)->m_pFctJump         = VideoEditor3gpReader_jump;
2007     (*pRdrGlobalInterface)->m_pFctReset        = VideoEditor3gpReader_reset;
2008     (*pRdrGlobalInterface)->m_pFctGetPrevRapTime =
2009         VideoEditor3gpReader_getPrevRapTime;
2010     (*pRdrDataInterface)->m_pFctGetNextAu      = VideoEditor3gpReader_getNextAu;
2011     (*pRdrDataInterface)->m_readerContext      = M4OSA_NULL;
2012 
2013 cleanUp:
2014     if( M4NO_ERROR == err ) {
2015         ALOGV("VideoEditor3gpReader_getInterface no error");
2016     } else {
2017         SAFE_FREE(*pRdrGlobalInterface);
2018         SAFE_FREE(*pRdrDataInterface);
2019 
2020         ALOGV("VideoEditor3gpReader_getInterface ERROR 0x%X", err);
2021     }
2022     ALOGV("VideoEditor3gpReader_getInterface end");
2023     return err;
2024 }
2025 
2026 }  /* extern "C" */
2027 
2028 }  /* namespace android */
2029 
2030 
2031