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