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