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