VideoEditorMp3Reader.cpp revision 7c9d8018755adf1857571125ba1b3598c96ea506
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 VideoEditorMp3Reader.cpp 20* @brief StageFright shell MP3 Reader 21************************************************************************* 22*/ 23#define LOG_NDEBUG 1 24#define LOG_TAG "VIDEOEDITOR_MP3READER" 25 26/** 27 * HEADERS 28 * 29 */ 30#include "M4OSA_Debug.h" 31#include "M4SYS_AccessUnit.h" 32#include "VideoEditorMp3Reader.h" 33#include "VideoEditorUtils.h" 34 35#include "utils/Log.h" 36#include <media/stagefright/MediaBufferGroup.h> 37#include <media/stagefright/DataSource.h> 38#include <media/stagefright/FileSource.h> 39#include <media/stagefright/MediaBuffer.h> 40#include <media/stagefright/MediaDefs.h> 41#include <media/stagefright/MediaExtractor.h> 42#include <media/stagefright/MediaDebug.h> 43#include <media/stagefright/MediaSource.h> 44#include <media/stagefright/MetaData.h> 45 46/** 47 * SOURCE CLASS 48 */ 49 50namespace android { 51/** 52 * ENGINE INTERFACE 53 */ 54 55/** 56 ************************************************************************** 57 * structure VideoEditorMp3Reader_Context 58 * @brief This structure defines the context of the SF MP3 reader shell. 59 ************************************************************************** 60 */ 61typedef struct { 62 sp<DataSource> mDataSource; 63 sp<MediaExtractor> mExtractor; 64 sp<MediaSource> mMediaSource; 65 M4_AudioStreamHandler* mAudioStreamHandler; 66 M4SYS_AccessUnit mAudioAu; 67 M4OSA_Time mMaxDuration; 68 M4OSA_UInt8 mStreamNumber; 69 M4OSA_Bool mSeeking; 70 M4OSA_Time mSeekTime; 71 uint32_t mExtractorFlags; 72} VideoEditorMp3Reader_Context; 73 74/** 75 **************************************************************************** 76 * @brief create an instance of the MP3 reader 77 * @note allocates the context 78 * 79 * @param pContext: (OUT) pointer on a reader context 80 * 81 * @return M4NO_ERROR there is no error 82 * @return M4ERR_ALLOC a memory allocation has failed 83 * @return M4ERR_PARAMETER at least one parameter is not valid 84 **************************************************************************** 85*/ 86M4OSA_ERR VideoEditorMp3Reader_create(M4OSA_Context *pContext) { 87 M4OSA_ERR err = M4NO_ERROR; 88 VideoEditorMp3Reader_Context *pReaderContext = M4OSA_NULL; 89 90 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 91 92 LOGV("VideoEditorMp3Reader_create begin"); 93 94 /* Context allocation & initialization */ 95 SAFE_MALLOC(pReaderContext, VideoEditorMp3Reader_Context, 1, 96 "VideoEditorMp3Reader"); 97 98 pReaderContext->mAudioStreamHandler = M4OSA_NULL; 99 pReaderContext->mAudioAu.dataAddress = M4OSA_NULL; 100 M4OSA_INT64_FROM_INT32(pReaderContext->mMaxDuration, 0); 101 *pContext = pReaderContext; 102 103cleanUp: 104 if (M4NO_ERROR == err) { 105 LOGV("VideoEditorMp3Reader_create no error"); 106 } else { 107 LOGV("VideoEditorMp3Reader_create ERROR 0x%X", err); 108 } 109 LOGV("VideoEditorMp3Reader_create end"); 110 return err; 111} 112 113/** 114 ******************************************************************************* 115 * @brief destroy the instance of the MP3 reader 116 * @note after this call the context is invalid 117 * @param context: (IN) Context of the reader 118 * @return M4NO_ERROR there is no error 119 * @return M4ERR_PARAMETER The input parameter is not properly set 120 ******************************************************************************* 121*/ 122M4OSA_ERR VideoEditorMp3Reader_destroy(M4OSA_Context pContext) { 123 M4OSA_ERR err = M4NO_ERROR; 124 VideoEditorMp3Reader_Context *pReaderContext = 125 (VideoEditorMp3Reader_Context*)pContext; 126 127 VIDEOEDITOR_CHECK(M4OSA_NULL != pReaderContext, M4ERR_PARAMETER); 128 LOGV("VideoEditorMp3Reader_destroy begin"); 129 130 SAFE_FREE(pReaderContext); 131cleanUp: 132 if (M4NO_ERROR == err) { 133 LOGV("VideoEditorMp3Reader_destroy no error"); 134 } else { 135 LOGV("VideoEditorMp3Reader_destroy ERROR 0x%X", err); 136 } 137 LOGV("VideoEditorMp3Reader_destroy end"); 138 return err; 139} 140/** 141 ****************************************************************************** 142 * @brief open the reader and initializes its created instance 143 * @note this function opens the MP3 file 144 * @param context: (IN) Context of the reader 145 * @param pFileDescriptor: (IN) Pointer to proprietary data identifying 146 * the media to open 147 148 * @return M4NO_ERROR there is no error 149 * @return M4ERR_PARAMETER the context is NULL 150 * @return M4ERR_BAD_CONTEXT provided context is not a valid one 151 ****************************************************************************** 152*/ 153M4OSA_ERR VideoEditorMp3Reader_open(M4OSA_Context context, 154 M4OSA_Void* pFileDescriptor){ 155 VideoEditorMp3Reader_Context *pReaderContext = 156 (VideoEditorMp3Reader_Context*)context; 157 M4OSA_ERR err = M4NO_ERROR; 158 159 LOGV("VideoEditorMp3Reader_open begin"); 160 /* Check function parameters*/ 161 M4OSA_DEBUG_IF1((M4OSA_NULL == pReaderContext), M4ERR_PARAMETER, 162 "VideoEditorMp3Reader_open: invalid context pointer"); 163 M4OSA_DEBUG_IF1((M4OSA_NULL == pFileDescriptor), M4ERR_PARAMETER, 164 "VideoEditorMp3Reader_open: invalid pointer pFileDescriptor"); 165 166 LOGV("VideoEditorMp3Reader_open Datasource start %s", 167 (char*)pFileDescriptor); 168 pReaderContext->mDataSource = DataSource::CreateFromURI( 169 (char*)pFileDescriptor); 170 LOGV("VideoEditorMp3Reader_open Datasource end"); 171 172 if (pReaderContext->mDataSource == NULL) { 173 LOGV("VideoEditorMp3Reader_open Datasource error"); 174 return UNKNOWN_ERROR; 175 } 176 177 LOGV("VideoEditorMp3Reader_open extractor start"); 178 pReaderContext->mExtractor = MediaExtractor::Create( 179 pReaderContext->mDataSource,MEDIA_MIMETYPE_AUDIO_MPEG); 180 LOGV("VideoEditorMp3Reader_open extractor end"); 181 182 if (pReaderContext->mExtractor == NULL) { 183 LOGV("VideoEditorMp3Reader_open extractor error"); 184 return UNKNOWN_ERROR; 185 } 186 pReaderContext->mStreamNumber = 0; 187 188 LOGV("VideoEditorMp3Reader_open end"); 189 return err; 190} 191/** 192 ************************************************************************** 193 * @brief close the reader 194 * @note this function closes the MP3 reader 195 * @param context: (IN) Context of the reader 196 * @return M4NO_ERROR there is no error 197 * @return M4ERR_PARAMETER the context is NULL 198 ************************************************************************** 199*/ 200M4OSA_ERR VideoEditorMp3Reader_close(M4OSA_Context context) { 201 VideoEditorMp3Reader_Context *pReaderContext = 202 (VideoEditorMp3Reader_Context*)context; 203 M4OSA_ERR err = M4NO_ERROR; 204 205 LOGV("VideoEditorMp3Reader_close begin"); 206 /* Check function parameters */ 207 M4OSA_DEBUG_IF1((M4OSA_NULL == pReaderContext), M4ERR_PARAMETER, 208 "VideoEditorMp3Reader_close: invalid context pointer"); 209 210 if (pReaderContext->mAudioStreamHandler != NULL) { 211 if (M4OSA_NULL != pReaderContext->mAudioStreamHandler->\ 212 m_basicProperties.m_pDecoderSpecificInfo) { 213 M4OSA_free((M4OSA_MemAddr32)pReaderContext->mAudioStreamHandler->\ 214 m_basicProperties.m_pDecoderSpecificInfo); 215 pReaderContext->mAudioStreamHandler->m_basicProperties.\ 216 m_decoderSpecificInfoSize = 0; 217 pReaderContext->mAudioStreamHandler->m_basicProperties.\ 218 m_pDecoderSpecificInfo = M4OSA_NULL; 219 } 220 221 /* Finally destroy the stream handler */ 222 M4OSA_free((M4OSA_MemAddr32)pReaderContext->mAudioStreamHandler); 223 pReaderContext->mAudioStreamHandler = M4OSA_NULL; 224 225 if (pReaderContext->mAudioAu.dataAddress != NULL) { 226 M4OSA_free((M4OSA_MemAddr32)pReaderContext->mAudioAu.dataAddress); 227 pReaderContext->mAudioAu.dataAddress = NULL; 228 } 229 } 230 231 pReaderContext->mMediaSource->stop(); 232 pReaderContext->mMediaSource.clear(); 233 pReaderContext->mDataSource.clear(); 234 235 LOGV("VideoEditorMp3Reader_close end "); 236 return err; 237} 238/** 239 ****************************************************************************** 240 * @brief get an option value from the reader 241 * @note 242 * it allows the caller to retrieve a property value: 243 * 244 * @param context: (IN) Context of the reader 245 * @param optionId: (IN) indicates the option to get 246 * @param pValue: (OUT) pointer to structure or value (allocated 247 * by user) where option is stored 248 * 249 * @return M4NO_ERROR there is no error 250 * @return M4ERR_PARAMETER at least one parameter is not properly set 251 * @return M4ERR_BAD_OPTION_ID when the option ID is not a valid one 252 ****************************************************************************** 253*/ 254M4OSA_ERR VideoEditorMp3Reader_getOption(M4OSA_Context context, 255 M4OSA_OptionID optionId, M4OSA_DataOption pValue) { 256 VideoEditorMp3Reader_Context *pReaderContext = 257 (VideoEditorMp3Reader_Context*)context; 258 M4OSA_ERR err = M4NO_ERROR; 259 260 LOGV("VideoEditorMp3Reader_getOption begin: optionId= %d ",(int)optionId); 261 262 M4OSA_DEBUG_IF1((M4OSA_NULL == pReaderContext), M4ERR_PARAMETER, 263 "invalid value pointer"); 264 M4OSA_DEBUG_IF1((M4OSA_NULL == pValue), M4ERR_PARAMETER, 265 "invalid value pointer"); 266 267 switch(optionId) { 268 case M4READER_kOptionID_Duration: 269 { 270 LOGV("Mp3Reader duration=%ld",pReaderContext->mMaxDuration); 271 M4OSA_TIME_SET(*(M4OSA_Time*)pValue, pReaderContext->mMaxDuration); 272 } 273 break; 274 275 case M4READER_kOptionID_Bitrate: 276 { 277 M4OSA_UInt32* pBitrate = (M4OSA_UInt32*)pValue; 278 if (M4OSA_NULL != pReaderContext->mAudioStreamHandler) { 279 *pBitrate = pReaderContext->mAudioStreamHandler->\ 280 m_basicProperties.m_averageBitRate; 281 } else { 282 pBitrate = 0; 283 err = M4ERR_PARAMETER; 284 } 285 } 286 break; 287 288 case M4READER_kOptionID_Mp3Id3v1Tag: 289 break; 290 291 case M4READER_kOptionID_Mp3Id3v2Tag: 292 break; 293 294 case M4READER_kOptionID_GetMetadata: 295 break; 296 297 default : 298 { 299 LOGV("VideoEditorMp3Reader_getOption: M4ERR_BAD_OPTION_ID"); 300 err = M4ERR_BAD_OPTION_ID; 301 } 302 } 303 LOGV("VideoEditorMp3Reader_getOption end "); 304 return err; 305} 306/** 307 ****************************************************************************** 308 * @brief set an option value of the reader 309 * @note 310 * it allows the caller to set a property value: 311 * 312 * @param context: (IN) Context of the reader 313 * @param optionId: (IN) Identifier indicating the option to set 314 * @param pValue: (IN) Pointer to structure or value (allocated 315 * by user) where option is stored 316 * 317 * @return M4NO_ERROR There is no error 318 * @return M4ERR_BAD_OPTION_ID The option ID is not a valid one 319 * @return M4ERR_STATE State automaton is not applied 320 * @return M4ERR_PARAMETER The option parameter is invalid 321 ****************************************************************************** 322*/ 323M4OSA_ERR VideoEditorMp3Reader_setOption(M4OSA_Context context, 324 M4OSA_OptionID optionId, M4OSA_DataOption pValue) { 325 VideoEditorMp3Reader_Context *pReaderContext = 326 (VideoEditorMp3Reader_Context*)context; 327 M4OSA_ERR err = M4NO_ERROR; 328 329 LOGV("VideoEditorMp3Reader_Context begin: optionId: %d Value: %d ", 330 (int)optionId,(int)pValue); 331 332 M4OSA_DEBUG_IF1((M4OSA_NULL == pReaderContext), M4ERR_PARAMETER, 333 "invalid context pointer"); 334 M4OSA_DEBUG_IF1((M4OSA_NULL == pValue), M4ERR_PARAMETER, 335 "invalid value pointer"); 336 337 switch(optionId) { 338 case M4READER_kOptionID_SetOsaFileReaderFctsPtr: 339 default : 340 { 341 err = M4NO_ERROR; 342 } 343 } 344 LOGV("VideoEditorMp3Reader_Context end "); 345 return err; 346} 347/** 348 ****************************************************************************** 349 * @brief jump into the stream at the specified time 350 * @note 351 * @param context: (IN) Context of the reader 352 * @param pStreamHandler(IN) stream description of the stream to make jump 353 * @param pTime (I/O)IN:the time to jump to (in ms) 354 * OUT: the time to which the stream really jumped 355 * @return M4NO_ERROR there is no error 356 * @return M4ERR_PARAMETER at least one parameter is not properly set 357 ****************************************************************************** 358*/ 359M4OSA_ERR VideoEditorMp3Reader_jump(M4OSA_Context context, 360 M4_StreamHandler *pStreamHandler, M4OSA_Int32* pTime) { 361 VideoEditorMp3Reader_Context *pReaderContext = 362 (VideoEditorMp3Reader_Context*)context; 363 M4SYS_StreamID streamIdArray[2]; 364 M4OSA_ERR err = M4NO_ERROR; 365 M4SYS_AccessUnit* pAu; 366 M4OSA_Time time64; 367 M4OSA_Double timeDouble; 368 369 LOGV("VideoEditorMp3Reader_jump begin"); 370 M4OSA_DEBUG_IF1((pReaderContext == 0), M4ERR_PARAMETER, 371 "VideoEditorMp3Reader_jump: invalid context"); 372 M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, 373 "VideoEditorMp3Reader_jump: invalid pointer to M4_StreamHandler"); 374 M4OSA_DEBUG_IF1((pTime == 0), M4ERR_PARAMETER, 375 "VideoEditorMp3Reader_jump: invalid time pointer"); 376 377 M4OSA_INT64_FROM_INT32(time64, *pTime); 378 379 if(pStreamHandler == (M4_StreamHandler*)pReaderContext->\ 380 mAudioStreamHandler){ 381 pAu = &pReaderContext->mAudioAu; 382 } else { 383 LOGV("VideoEditorMp3Reader_jump: passed StreamHandler is not known"); 384 return M4ERR_PARAMETER; 385 } 386 387 streamIdArray[0] = pStreamHandler->m_streamId; 388 streamIdArray[1] = 0; 389 390 LOGV("VideoEditorMp3Reader_jump time ms %ld ", time64); 391 392 pAu->CTS = time64; 393 pAu->DTS = time64; 394 395 time64 = time64 * 1000; /* Convert the time into micro sec */ 396 LOGV("VideoEditorMp3Reader_jump time us %ld ", time64); 397 398 pReaderContext->mSeeking = M4OSA_TRUE; 399 pReaderContext->mSeekTime = time64; 400 401 time64 = time64 / 1000; /* Convert the time into milli sec */ 402 M4OSA_INT64_TO_DOUBLE(timeDouble, time64); 403 *pTime = (M4OSA_Int32)timeDouble; 404 LOGV("VideoEditorMp3Reader_jump end "); 405 return err; 406} 407/** 408 ******************************************************************************* 409 * @brief Get the next stream found in the media file 410 * 411 * @param context: (IN) Context of the reader 412 * @param pMediaFamily: (OUT) pointer to a user allocated 413 * M4READER_MediaFamily that will be filled with 414 * the media family of the found stream 415 * @param pStreamHandler: (OUT) pointer to a stream handler that will be 416 * allocated and filled with stream description 417 * 418 * @return M4NO_ERROR there is no error 419 * @return M4WAR_NO_MORE_STREAM no more available stream in the media 420 * @return M4ERR_PARAMETER at least one parameter is not properly set 421 ******************************************************************************* 422*/ 423M4OSA_ERR VideoEditorMp3Reader_getNextStream(M4OSA_Context context, 424 M4READER_MediaFamily *pMediaFamily, 425 M4_StreamHandler **pStreamHandlerParam) { 426 VideoEditorMp3Reader_Context *pReaderContext = 427 (VideoEditorMp3Reader_Context*)context; 428 M4OSA_ERR err = M4NO_ERROR; 429 M4SYS_StreamID streamIdArray[2]; 430 M4SYS_StreamDescription streamDesc; 431 M4_AudioStreamHandler* pAudioStreamHandler; 432 M4_StreamHandler* pStreamHandler; 433 M4OSA_UInt8 type, temp; 434 M4OSA_Bool haveAudio = M4OSA_FALSE; 435 sp<MetaData> meta = NULL; 436 int64_t Duration; 437 438 LOGV("VideoEditorMp3Reader_getNextStream begin"); 439 M4OSA_DEBUG_IF1((pReaderContext == 0), M4ERR_PARAMETER, 440 "VideoEditorMp3Reader_getNextStream: invalid context"); 441 M4OSA_DEBUG_IF1((pMediaFamily == 0), M4ERR_PARAMETER, 442 "VideoEditorMp3Reader_getNextStream: invalid pointer to MediaFamily"); 443 M4OSA_DEBUG_IF1((pStreamHandlerParam == 0), M4ERR_PARAMETER, 444 "VideoEditorMp3Reader_getNextStream: invalid pointer to StreamHandler"); 445 446 LOGV("VideoEditorMp3Reader_getNextStream stream number = %d", 447 pReaderContext->mStreamNumber); 448 if (pReaderContext->mStreamNumber >= 1) { 449 LOGV("VideoEditorMp3Reader_getNextStream max number of stream reached"); 450 return M4WAR_NO_MORE_STREAM; 451 } 452 pReaderContext->mStreamNumber = pReaderContext->mStreamNumber + 1; 453 LOGV("VideoEditorMp3Reader_getNextStream number of Tracks%d", 454 pReaderContext->mExtractor->countTracks()); 455 for (temp = 0; temp < pReaderContext->mExtractor->countTracks(); temp++) { 456 meta = pReaderContext->mExtractor->getTrackMetaData(temp); 457 const char *mime; 458 CHECK(meta->findCString(kKeyMIMEType, &mime)); 459 460 if (!haveAudio && !strncasecmp(mime, "audio/", 6)) { 461 pReaderContext->mMediaSource = 462 pReaderContext->mExtractor->getTrack(temp); 463 pReaderContext->mMediaSource->start(); 464 haveAudio = true; 465 } 466 467 if (haveAudio) { 468 break; 469 } 470 } 471 472 if (!haveAudio) { 473 LOGV("VideoEditorMp3Reader_getNextStream no more stream "); 474 pReaderContext->mDataSource.clear(); 475 return M4WAR_NO_MORE_STREAM; 476 } 477 478 pReaderContext->mExtractorFlags = pReaderContext->mExtractor->flags(); 479 *pMediaFamily = M4READER_kMediaFamilyAudio; 480 481 streamDesc.duration = meta->findInt64(kKeyDuration, &Duration); 482 streamDesc.duration = (M4OSA_Time)Duration/1000; 483 484 meta->findInt32(kKeyBitRate, (int32_t*)&streamDesc.averageBitrate); 485 meta->findInt32(kKeySampleRate, (int32_t*)&streamDesc.timeScale); 486 LOGV("Bitrate = %d, SampleRate = %d duration = %lld", 487 streamDesc.averageBitrate,streamDesc.timeScale,Duration/1000); 488 489 streamDesc.streamType = M4SYS_kMP3; 490 streamDesc.profileLevel = 0xFF ; 491 streamDesc.streamID = pReaderContext->mStreamNumber; 492 streamDesc.decoderSpecificInfo = M4OSA_NULL; 493 streamDesc.decoderSpecificInfoSize = 0; 494 streamDesc.maxBitrate = streamDesc.averageBitrate; 495 496 /* Allocate the audio stream handler and set its parameters */ 497 pAudioStreamHandler = (M4_AudioStreamHandler*)M4OSA_malloc( 498 sizeof(M4_AudioStreamHandler), M4READER_MP3, 499 (M4OSA_Char*)"M4_AudioStreamHandler"); 500 501 if (pAudioStreamHandler == M4OSA_NULL) { 502 LOGV("VideoEditorMp3Reader_getNextStream malloc failed"); 503 pReaderContext->mMediaSource->stop(); 504 pReaderContext->mMediaSource.clear(); 505 pReaderContext->mDataSource.clear(); 506 507 return M4ERR_ALLOC; 508 } 509 pStreamHandler =(M4_StreamHandler*)(pAudioStreamHandler); 510 *pStreamHandlerParam = pStreamHandler; 511 pReaderContext->mAudioStreamHandler = pAudioStreamHandler; 512 513 pAudioStreamHandler->m_structSize = sizeof(M4_AudioStreamHandler); 514 515 if (meta == NULL) { 516 LOGV("VideoEditorMp3Reader_getNextStream meta is NULL"); 517 } 518 519 pAudioStreamHandler->m_samplingFrequency = streamDesc.timeScale; 520 pStreamHandler->m_pDecoderSpecificInfo = 521 (M4OSA_UInt8*)(streamDesc.decoderSpecificInfo); 522 pStreamHandler->m_decoderSpecificInfoSize = 523 streamDesc.decoderSpecificInfoSize; 524 525 meta->findInt32(kKeyChannelCount, 526 (int32_t*)&pAudioStreamHandler->m_nbChannels); 527 pAudioStreamHandler->m_byteFrameLength = 1152; 528 pAudioStreamHandler->m_byteSampleSize = 2; 529 530 pStreamHandler->m_pUserData = NULL; 531 pStreamHandler->m_streamId = streamDesc.streamID; 532 pStreamHandler->m_duration = streamDesc.duration; 533 pReaderContext->mMaxDuration = streamDesc.duration; 534 pStreamHandler->m_averageBitRate = streamDesc.averageBitrate; 535 536 pStreamHandler->m_maxAUSize = 0; 537 pStreamHandler->m_streamType = M4DA_StreamTypeAudioMp3; 538 539 LOGV("VideoEditorMp3Reader_getNextStream end "); 540 return err; 541} 542 543/** 544 ******************************************************************************* 545 * @brief fill the access unit structure with initialization values 546 * @param context: (IN) Context of the reader 547 * @param pStreamHandler: (IN) pointer to the stream handler to which 548 * the access unit will be associated 549 * @param pAccessUnit: (IN/OUT) pointer to the access unit (allocated by 550 * the caller) to initialize 551 * @return M4NO_ERROR there is no error 552 * @return M4ERR_PARAMETER at least one parameter is not properly set 553 ******************************************************************************* 554*/ 555M4OSA_ERR VideoEditorMp3Reader_fillAuStruct(M4OSA_Context context, 556 M4_StreamHandler *pStreamHandler, M4_AccessUnit *pAccessUnit) { 557 VideoEditorMp3Reader_Context *pReaderContext = 558 (VideoEditorMp3Reader_Context*)context; 559 M4SYS_AccessUnit *pAu; 560 561 M4OSA_DEBUG_IF1((pReaderContext == 0), M4ERR_PARAMETER, 562 "VideoEditorMp3Reader_fillAuStruct: invalid context"); 563 M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, 564 "VideoEditorMp3Reader_fillAuStruct invalid pointer to StreamHandler"); 565 M4OSA_DEBUG_IF1((pAccessUnit == 0), M4ERR_PARAMETER, 566 "VideoEditorMp3Reader_fillAuStruct: invalid pointer to M4_AccessUnit"); 567 568 LOGV("VideoEditorMp3Reader_fillAuStruct start "); 569 if(pStreamHandler == (M4_StreamHandler*)pReaderContext->\ 570 mAudioStreamHandler){ 571 pAu = &pReaderContext->mAudioAu; 572 } else { 573 LOGV("VideoEditorMp3Reader_fillAuStruct StreamHandler is not known"); 574 return M4ERR_PARAMETER; 575 } 576 577 /* Initialize pAu structure */ 578 pAu->dataAddress = M4OSA_NULL; 579 pAu->size = 0; 580 pAu->CTS = 0; 581 pAu->DTS = 0; 582 pAu->attribute = 0; 583 pAu->nbFrag = 0; 584 585 /* Initialize pAccessUnit structure */ 586 pAccessUnit->m_size = 0; 587 pAccessUnit->m_CTS = 0; 588 pAccessUnit->m_DTS = 0; 589 pAccessUnit->m_attribute = 0; 590 pAccessUnit->m_dataAddress = M4OSA_NULL; 591 pAccessUnit->m_maxsize = pStreamHandler->m_maxAUSize; 592 pAccessUnit->m_streamID = pStreamHandler->m_streamId; 593 pAccessUnit->m_structSize = sizeof(M4_AccessUnit); 594 595 LOGV("VideoEditorMp3Reader_fillAuStruct end"); 596 return M4NO_ERROR; 597} 598 599/** 600 ******************************************************************************* 601 * @brief reset the stream, i.e seek it to the beginning 602 * @note 603 * @param context: (IN) Context of the reader 604 * @param pStreamHandler (IN) The stream handler of the stream to reset 605 * @return M4NO_ERROR there is no error 606 * @return M4ERR_PARAMETER at least one parameter is not properly set 607 ******************************************************************************* 608*/ 609M4OSA_ERR VideoEditorMp3Reader_reset(M4OSA_Context context, 610 M4_StreamHandler *pStreamHandler) { 611 VideoEditorMp3Reader_Context *pReaderContext = 612 (VideoEditorMp3Reader_Context*)context; 613 614 M4OSA_ERR err = M4NO_ERROR; 615 M4SYS_StreamID streamIdArray[2]; 616 M4SYS_AccessUnit* pAu; 617 M4OSA_Time time64; 618 619 LOGV("VideoEditorMp3Reader_reset start"); 620 M4OSA_DEBUG_IF1((pReaderContext == 0), M4ERR_PARAMETER, 621 "VideoEditorMp3Reader_reset: invalid context"); 622 M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, 623 "VideoEditorMp3Reader_reset: invalid pointer to M4_StreamHandler"); 624 625 M4OSA_INT64_FROM_INT32(time64, 0); 626 627 if (pStreamHandler == (M4_StreamHandler*)pReaderContext->\ 628 mAudioStreamHandler) { 629 pAu = &pReaderContext->mAudioAu; 630 } else { 631 LOGV("VideoEditorMp3Reader_reset StreamHandler is not known"); 632 return M4ERR_PARAMETER; 633 } 634 streamIdArray[0] = pStreamHandler->m_streamId; 635 streamIdArray[1] = 0; 636 pAu->CTS = time64; 637 pAu->DTS = time64; 638 639 pReaderContext->mSeeking = M4OSA_TRUE; 640 pReaderContext->mSeekTime = time64; 641 642 LOGV("VideoEditorMp3Reader_reset end"); 643 return err; 644} 645/** 646 ******************************************************************************* 647 * @brief Gets an access unit (AU) from the stream handler source. 648 * @note AU is the smallest possible amount of data to be decoded by decoder 649 * 650 * @param context: (IN) Context of the reader 651 * @param pStreamHandler (IN) The stream handler of the stream to make jump 652 * @param pAccessUnit (I/O)Pointer to an access unit to fill with read data 653 * @return M4NO_ERROR there is no error 654 * @return M4ERR_PARAMETER at least one parameter is not properly set 655 * @returns M4ERR_ALLOC memory allocation failed 656 * @returns M4WAR_NO_MORE_AU there are no more access unit in the stream 657 ******************************************************************************* 658*/ 659M4OSA_ERR VideoEditorMp3Reader_getNextAu(M4OSA_Context context, 660 M4_StreamHandler *pStreamHandler, M4_AccessUnit *pAccessUnit) { 661 VideoEditorMp3Reader_Context *pReaderContext = 662 (VideoEditorMp3Reader_Context*)context; 663 M4OSA_ERR err = M4NO_ERROR; 664 M4SYS_AccessUnit* pAu; 665 MediaBuffer *mAudioBuffer; 666 MediaSource::ReadOptions options; 667 668 LOGV("VideoEditorMp3Reader_getNextAu start"); 669 M4OSA_DEBUG_IF1((pReaderContext == 0), M4ERR_PARAMETER, 670 "VideoEditorMp3Reader_getNextAu: invalid context"); 671 M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, 672 "VideoEditorMp3Reader_getNextAu: invalid pointer to M4_StreamHandler"); 673 M4OSA_DEBUG_IF1((pAccessUnit == 0), M4ERR_PARAMETER, 674 "VideoEditorMp3Reader_getNextAu: invalid pointer to M4_AccessUnit"); 675 676 if (pStreamHandler == (M4_StreamHandler*)pReaderContext->\ 677 mAudioStreamHandler) { 678 pAu = &pReaderContext->mAudioAu; 679 } else { 680 LOGV("VideoEditorMp3Reader_getNextAu: StreamHandler is not known\n"); 681 return M4ERR_PARAMETER; 682 } 683 684 if (pReaderContext->mSeeking) { 685 options.setSeekTo(pReaderContext->mSeekTime); 686 } 687 688 pReaderContext->mMediaSource->read(&mAudioBuffer, &options); 689 690 if (mAudioBuffer != NULL) { 691 if ((pAu->dataAddress == NULL) || 692 (pAu->size < mAudioBuffer->range_length())) { 693 if (pAu->dataAddress != NULL) { 694 M4OSA_free((M4OSA_Int32*)pAu->dataAddress); 695 pAu->dataAddress = NULL; 696 } 697 pAu->dataAddress = (M4OSA_Int32*)M4OSA_malloc( 698 (mAudioBuffer->range_length() + 3) & ~0x3, 699 M4READER_MP3, (M4OSA_Char*)"pAccessUnit->m_dataAddress" ); 700 701 if (pAu->dataAddress == NULL) { 702 LOGV("VideoEditorMp3Reader_getNextAu malloc failed"); 703 pReaderContext->mMediaSource->stop(); 704 pReaderContext->mMediaSource.clear(); 705 pReaderContext->mDataSource.clear(); 706 707 return M4ERR_ALLOC; 708 } 709 } 710 pAu->size = mAudioBuffer->range_length(); 711 memcpy((M4OSA_MemAddr8)pAu->dataAddress, 712 (const char *)mAudioBuffer->data() + mAudioBuffer->range_offset(), 713 mAudioBuffer->range_length()); 714 715 mAudioBuffer->meta_data()->findInt64(kKeyTime, (int64_t*)&pAu->CTS); 716 717 718 pAu->CTS = pAu->CTS / 1000; /*converting the microsec to millisec */ 719 pAu->DTS = pAu->CTS; 720 pAu->attribute = M4SYS_kFragAttrOk; 721 mAudioBuffer->release(); 722 723 LOGV("VideoEditorMp3Reader_getNextAu AU CTS = %ld",pAu->CTS); 724 725 pAccessUnit->m_dataAddress = (M4OSA_Int8*) pAu->dataAddress; 726 pAccessUnit->m_size = pAu->size; 727 pAccessUnit->m_CTS = pAu->CTS; 728 pAccessUnit->m_DTS = pAu->DTS; 729 pAccessUnit->m_attribute = pAu->attribute; 730 } else { 731 LOGV("VideoEditorMp3Reader_getNextAu EOS reached."); 732 pAccessUnit->m_size=0; 733 err = M4WAR_NO_MORE_AU; 734 } 735 pAu->nbFrag = 0; 736 737 options.clearSeekTo(); 738 pReaderContext->mSeeking = M4OSA_FALSE; 739 mAudioBuffer = NULL; 740 LOGV("VideoEditorMp3Reader_getNextAu end"); 741 742 return err; 743} 744 745extern "C" { 746 747M4OSA_ERR VideoEditorMp3Reader_getInterface( 748 M4READER_MediaType *pMediaType, 749 M4READER_GlobalInterface **pRdrGlobalInterface, 750 M4READER_DataInterface **pRdrDataInterface) { 751 M4OSA_ERR err = M4NO_ERROR; 752 753 LOGV("VideoEditorMp3Reader_getInterface: begin"); 754 /* Input parameters check */ 755 VIDEOEDITOR_CHECK(M4OSA_NULL != pMediaType, M4ERR_PARAMETER); 756 VIDEOEDITOR_CHECK(M4OSA_NULL != pRdrGlobalInterface, M4ERR_PARAMETER); 757 VIDEOEDITOR_CHECK(M4OSA_NULL != pRdrDataInterface, M4ERR_PARAMETER); 758 759 SAFE_MALLOC(*pRdrGlobalInterface, M4READER_GlobalInterface, 1, 760 "VideoEditorMp3Reader_getInterface"); 761 SAFE_MALLOC(*pRdrDataInterface, M4READER_DataInterface, 1, 762 "VideoEditorMp3Reader_getInterface"); 763 764 *pMediaType = M4READER_kMediaTypeMP3; 765 766 (*pRdrGlobalInterface)->m_pFctCreate = VideoEditorMp3Reader_create; 767 (*pRdrGlobalInterface)->m_pFctDestroy = VideoEditorMp3Reader_destroy; 768 (*pRdrGlobalInterface)->m_pFctOpen = VideoEditorMp3Reader_open; 769 (*pRdrGlobalInterface)->m_pFctClose = VideoEditorMp3Reader_close; 770 (*pRdrGlobalInterface)->m_pFctGetOption = VideoEditorMp3Reader_getOption; 771 (*pRdrGlobalInterface)->m_pFctSetOption = VideoEditorMp3Reader_setOption; 772 (*pRdrGlobalInterface)->m_pFctGetNextStream = 773 VideoEditorMp3Reader_getNextStream; 774 (*pRdrGlobalInterface)->m_pFctFillAuStruct = 775 VideoEditorMp3Reader_fillAuStruct; 776 (*pRdrGlobalInterface)->m_pFctStart = M4OSA_NULL; 777 (*pRdrGlobalInterface)->m_pFctStop = M4OSA_NULL; 778 (*pRdrGlobalInterface)->m_pFctJump = VideoEditorMp3Reader_jump; 779 (*pRdrGlobalInterface)->m_pFctReset = VideoEditorMp3Reader_reset; 780 (*pRdrGlobalInterface)->m_pFctGetPrevRapTime = M4OSA_NULL; 781 782 (*pRdrDataInterface)->m_pFctGetNextAu = VideoEditorMp3Reader_getNextAu; 783 (*pRdrDataInterface)->m_readerContext = M4OSA_NULL; 784 785cleanUp: 786 if( M4NO_ERROR == err ) 787 { 788 LOGV("VideoEditorMp3Reader_getInterface no error"); 789 } 790 else 791 { 792 SAFE_FREE(*pRdrGlobalInterface); 793 SAFE_FREE(*pRdrDataInterface); 794 795 LOGV("VideoEditorMp3Reader_getInterface ERROR 0x%X", err); 796 } 797 LOGV("VideoEditorMp3Reader_getInterface: end"); 798 return err; 799} 800} /* extern "C" */ 801} /* namespace android */ 802