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 #define LOG_NDEBUG 1 18 #define LOG_TAG "VideoEditorAudioPlayer" 19 #include <utils/Log.h> 20 21 #include <binder/IPCThreadState.h> 22 #include <media/AudioTrack.h> 23 #include <VideoEditorAudioPlayer.h> 24 #include <media/stagefright/foundation/ADebug.h> 25 #include <media/stagefright/MediaDefs.h> 26 #include <media/stagefright/MediaErrors.h> 27 #include <media/stagefright/MediaSource.h> 28 #include <media/stagefright/MetaData.h> 29 30 #include <system/audio.h> 31 32 #include "PreviewPlayer.h" 33 namespace android { 34 35 VideoEditorAudioPlayer::VideoEditorAudioPlayer( 36 const sp<MediaPlayerBase::AudioSink> &audioSink, 37 PreviewPlayer *observer) 38 : mAudioTrack(NULL), 39 mInputBuffer(NULL), 40 mSampleRate(0), 41 mLatencyUs(0), 42 mFrameSize(0), 43 mNumFramesPlayed(0), 44 mPositionTimeMediaUs(-1), 45 mPositionTimeRealUs(-1), 46 mSeeking(false), 47 mReachedEOS(false), 48 mFinalStatus(OK), 49 mStarted(false), 50 mIsFirstBuffer(false), 51 mFirstBufferResult(OK), 52 mFirstBuffer(NULL), 53 mAudioSink(audioSink), 54 mObserver(observer) { 55 56 ALOGV("Constructor"); 57 mBGAudioPCMFileHandle = NULL; 58 mAudioProcess = NULL; 59 mBGAudioPCMFileLength = 0; 60 mBGAudioPCMFileTrimmedLength = 0; 61 mBGAudioPCMFileDuration = 0; 62 mBGAudioPCMFileSeekPoint = 0; 63 mBGAudioPCMFileOriginalSeekPoint = 0; 64 mBGAudioStoryBoardSkimTimeStamp = 0; 65 mBGAudioStoryBoardCurrentMediaBeginCutTS = 0; 66 mBGAudioStoryBoardCurrentMediaVolumeVal = 0; 67 mSeekTimeUs = 0; 68 mSource = NULL; 69 } 70 71 VideoEditorAudioPlayer::~VideoEditorAudioPlayer() { 72 73 ALOGV("Destructor"); 74 if (mStarted) { 75 reset(); 76 } 77 if (mAudioProcess != NULL) { 78 delete mAudioProcess; 79 mAudioProcess = NULL; 80 } 81 } 82 83 void VideoEditorAudioPlayer::pause(bool playPendingSamples) { 84 ALOGV("pause: playPendingSamples=%d", playPendingSamples); 85 CHECK(mStarted); 86 87 if (playPendingSamples) { 88 if (mAudioSink.get() != NULL) { 89 mAudioSink->stop(); 90 } else { 91 mAudioTrack->stop(); 92 } 93 } else { 94 if (mAudioSink.get() != NULL) { 95 mAudioSink->pause(); 96 } else { 97 mAudioTrack->pause(); 98 } 99 } 100 } 101 102 void VideoEditorAudioPlayer::clear() { 103 ALOGV("clear"); 104 if (!mStarted) { 105 return; 106 } 107 108 if (mAudioSink.get() != NULL) { 109 mAudioSink->stop(); 110 mAudioSink->close(); 111 } else { 112 mAudioTrack->stop(); 113 114 delete mAudioTrack; 115 mAudioTrack = NULL; 116 } 117 118 // Make sure to release any buffer we hold onto so that the 119 // source is able to stop(). 120 121 if (mFirstBuffer != NULL) { 122 mFirstBuffer->release(); 123 mFirstBuffer = NULL; 124 } 125 126 if (mInputBuffer != NULL) { 127 ALOGV("AudioPlayerBase releasing input buffer."); 128 129 mInputBuffer->release(); 130 mInputBuffer = NULL; 131 } 132 133 mSource->stop(); 134 135 // The following hack is necessary to ensure that the OMX 136 // component is completely released by the time we may try 137 // to instantiate it again. 138 wp<MediaSource> tmp = mSource; 139 mSource.clear(); 140 while (tmp.promote() != NULL) { 141 usleep(1000); 142 } 143 IPCThreadState::self()->flushCommands(); 144 145 mNumFramesPlayed = 0; 146 mPositionTimeMediaUs = -1; 147 mPositionTimeRealUs = -1; 148 mSeeking = false; 149 mReachedEOS = false; 150 mFinalStatus = OK; 151 mStarted = false; 152 } 153 154 void VideoEditorAudioPlayer::resume() { 155 ALOGV("resume"); 156 157 AudioMixSettings audioMixSettings; 158 159 // Single audio player is used; 160 // Pass on the audio ducking parameters 161 // which might have changed with new audio source 162 audioMixSettings.lvInDucking_threshold = 163 mAudioMixSettings->uiInDucking_threshold; 164 audioMixSettings.lvInDucking_lowVolume = 165 ((M4OSA_Float)mAudioMixSettings->uiInDucking_lowVolume) / 100.0; 166 audioMixSettings.lvInDucking_enable = 167 mAudioMixSettings->bInDucking_enable; 168 audioMixSettings.lvPTVolLevel = 169 ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal) / 100.0; 170 audioMixSettings.lvBTVolLevel = 171 ((M4OSA_Float)mAudioMixSettings->uiAddVolume) / 100.0; 172 audioMixSettings.lvBTChannelCount = mAudioMixSettings->uiBTChannelCount; 173 audioMixSettings.lvPTChannelCount = mAudioMixSettings->uiNbChannels; 174 175 // Call to Audio mix param setting 176 mAudioProcess->setMixParams(audioMixSettings); 177 178 CHECK(mStarted); 179 180 if (mAudioSink.get() != NULL) { 181 mAudioSink->start(); 182 } else { 183 mAudioTrack->start(); 184 } 185 } 186 187 status_t VideoEditorAudioPlayer::seekTo(int64_t time_us) { 188 ALOGV("seekTo: %lld", time_us); 189 Mutex::Autolock autoLock(mLock); 190 191 mSeeking = true; 192 mPositionTimeRealUs = mPositionTimeMediaUs = -1; 193 mReachedEOS = false; 194 mSeekTimeUs = time_us; 195 196 if (mAudioSink != NULL) { 197 mAudioSink->flush(); 198 } else { 199 mAudioTrack->flush(); 200 } 201 202 return OK; 203 } 204 205 bool VideoEditorAudioPlayer::isSeeking() { 206 Mutex::Autolock lock(mLock); 207 ALOGV("isSeeking: mSeeking=%d", mSeeking); 208 return mSeeking; 209 } 210 211 bool VideoEditorAudioPlayer::reachedEOS(status_t *finalStatus) { 212 ALOGV("reachedEOS: status=%d", mFinalStatus); 213 *finalStatus = OK; 214 215 Mutex::Autolock autoLock(mLock); 216 *finalStatus = mFinalStatus; 217 return mReachedEOS; 218 } 219 220 int64_t VideoEditorAudioPlayer::getRealTimeUs() { 221 Mutex::Autolock autoLock(mLock); 222 return getRealTimeUs_l(); 223 } 224 225 int64_t VideoEditorAudioPlayer::getRealTimeUs_l() { 226 return -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate; 227 } 228 229 int64_t VideoEditorAudioPlayer::getMediaTimeUs() { 230 ALOGV("getMediaTimeUs"); 231 Mutex::Autolock autoLock(mLock); 232 233 if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) { 234 if (mSeeking) { 235 return mSeekTimeUs; 236 } 237 238 return 0; 239 } 240 241 int64_t realTimeOffset = getRealTimeUs_l() - mPositionTimeRealUs; 242 if (realTimeOffset < 0) { 243 realTimeOffset = 0; 244 } 245 246 return mPositionTimeMediaUs + realTimeOffset; 247 } 248 249 bool VideoEditorAudioPlayer::getMediaTimeMapping( 250 int64_t *realtime_us, int64_t *mediatime_us) { 251 ALOGV("getMediaTimeMapping"); 252 Mutex::Autolock autoLock(mLock); 253 254 *realtime_us = mPositionTimeRealUs; 255 *mediatime_us = mPositionTimeMediaUs; 256 257 return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1; 258 } 259 260 void VideoEditorAudioPlayer::setSource(const sp<MediaSource> &source) { 261 Mutex::Autolock autoLock(mLock); 262 263 // Before setting source, stop any existing source. 264 // Make sure to release any buffer we hold onto so that the 265 // source is able to stop(). 266 267 if (mFirstBuffer != NULL) { 268 mFirstBuffer->release(); 269 mFirstBuffer = NULL; 270 } 271 272 if (mInputBuffer != NULL) { 273 ALOGV("VideoEditorAudioPlayer releasing input buffer."); 274 275 mInputBuffer->release(); 276 mInputBuffer = NULL; 277 } 278 279 if (mSource != NULL) { 280 mSource->stop(); 281 mSource.clear(); 282 } 283 284 mSource = source; 285 mReachedEOS = false; 286 } 287 288 sp<MediaSource> VideoEditorAudioPlayer::getSource() { 289 Mutex::Autolock autoLock(mLock); 290 return mSource; 291 } 292 293 void VideoEditorAudioPlayer::setObserver(PreviewPlayer *observer) { 294 ALOGV("setObserver"); 295 //CHECK(!mStarted); 296 mObserver = observer; 297 } 298 299 bool VideoEditorAudioPlayer::isStarted() { 300 return mStarted; 301 } 302 303 // static 304 void VideoEditorAudioPlayer::AudioCallback(int event, void *user, void *info) { 305 static_cast<VideoEditorAudioPlayer *>(user)->AudioCallback(event, info); 306 } 307 308 309 void VideoEditorAudioPlayer::AudioCallback(int event, void *info) { 310 if (event != AudioTrack::EVENT_MORE_DATA) { 311 return; 312 } 313 314 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; 315 size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size); 316 317 buffer->size = numBytesWritten; 318 } 319 320 status_t VideoEditorAudioPlayer::start(bool sourceAlreadyStarted) { 321 Mutex::Autolock autoLock(mLock); 322 CHECK(!mStarted); 323 CHECK(mSource != NULL); 324 ALOGV("Start"); 325 status_t err; 326 M4OSA_ERR result = M4NO_ERROR; 327 M4OSA_UInt32 startTime = 0; 328 M4OSA_UInt32 seekTimeStamp = 0; 329 M4OSA_Bool bStoryBoardTSBeyondBTEndCutTime = M4OSA_FALSE; 330 331 if (!sourceAlreadyStarted) { 332 err = mSource->start(); 333 if (err != OK) { 334 return err; 335 } 336 } 337 338 // Create the BG Audio handler 339 mAudioProcess = new VideoEditorBGAudioProcessing(); 340 AudioMixSettings audioMixSettings; 341 342 // Pass on the audio ducking parameters 343 audioMixSettings.lvInDucking_threshold = 344 mAudioMixSettings->uiInDucking_threshold; 345 audioMixSettings.lvInDucking_lowVolume = 346 ((M4OSA_Float)mAudioMixSettings->uiInDucking_lowVolume) / 100.0; 347 audioMixSettings.lvInDucking_enable = 348 mAudioMixSettings->bInDucking_enable; 349 audioMixSettings.lvPTVolLevel = 350 ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal) / 100.0; 351 audioMixSettings.lvBTVolLevel = 352 ((M4OSA_Float)mAudioMixSettings->uiAddVolume) / 100.0; 353 audioMixSettings.lvBTChannelCount = mAudioMixSettings->uiBTChannelCount; 354 audioMixSettings.lvPTChannelCount = mAudioMixSettings->uiNbChannels; 355 356 // Call to Audio mix param setting 357 mAudioProcess->setMixParams(audioMixSettings); 358 359 // Get the BG Audio PCM file details 360 if ( mBGAudioPCMFileHandle ) { 361 362 // TODO : 32bits required for OSAL, to be updated once OSAL is updated 363 M4OSA_UInt32 tmp32 = 0; 364 result = M4OSA_fileReadGetOption(mBGAudioPCMFileHandle, 365 M4OSA_kFileReadGetFileSize, 366 (M4OSA_Void**)&tmp32); 367 mBGAudioPCMFileLength = tmp32; 368 mBGAudioPCMFileTrimmedLength = mBGAudioPCMFileLength; 369 370 371 ALOGV("VideoEditorAudioPlayer::start M4OSA_kFileReadGetFileSize = %lld", 372 mBGAudioPCMFileLength); 373 374 // Get the duration in time of the audio BT 375 if ( result == M4NO_ERROR ) { 376 ALOGV("VEAP: channels = %d freq = %d", 377 mAudioMixSettings->uiNbChannels, mAudioMixSettings->uiSamplingFrequency); 378 379 // No trim 380 mBGAudioPCMFileDuration = (( 381 (int64_t)(mBGAudioPCMFileLength/sizeof(M4OSA_UInt16)/ 382 mAudioMixSettings->uiNbChannels))*1000 ) / 383 mAudioMixSettings->uiSamplingFrequency; 384 385 ALOGV("VideoEditorAudioPlayer:: beginCutMs %d , endCutMs %d", 386 (unsigned int) mAudioMixSettings->beginCutMs, 387 (unsigned int) mAudioMixSettings->endCutMs); 388 389 // Remove the trim part 390 if ((mAudioMixSettings->beginCutMs == 0) && 391 (mAudioMixSettings->endCutMs != 0)) { 392 // End time itself the file duration 393 mBGAudioPCMFileDuration = mAudioMixSettings->endCutMs; 394 // Limit the file length also 395 mBGAudioPCMFileTrimmedLength = (( 396 (int64_t)(mBGAudioPCMFileDuration * 397 mAudioMixSettings->uiSamplingFrequency) * 398 mAudioMixSettings->uiNbChannels) * 399 sizeof(M4OSA_UInt16)) / 1000; 400 } 401 else if ((mAudioMixSettings->beginCutMs != 0) && 402 (mAudioMixSettings->endCutMs == mBGAudioPCMFileDuration)) { 403 // End time itself the file duration 404 mBGAudioPCMFileDuration = mBGAudioPCMFileDuration - 405 mAudioMixSettings->beginCutMs; 406 // Limit the file length also 407 mBGAudioPCMFileTrimmedLength = (( 408 (int64_t)(mBGAudioPCMFileDuration * 409 mAudioMixSettings->uiSamplingFrequency) * 410 mAudioMixSettings->uiNbChannels) * 411 sizeof(M4OSA_UInt16)) / 1000; 412 } 413 else if ((mAudioMixSettings->beginCutMs != 0) && 414 (mAudioMixSettings->endCutMs != 0)) { 415 // End time itself the file duration 416 mBGAudioPCMFileDuration = mAudioMixSettings->endCutMs - 417 mAudioMixSettings->beginCutMs; 418 // Limit the file length also 419 mBGAudioPCMFileTrimmedLength = (( 420 (int64_t)(mBGAudioPCMFileDuration * 421 mAudioMixSettings->uiSamplingFrequency) * 422 mAudioMixSettings->uiNbChannels) * 423 sizeof(M4OSA_UInt16)) / 1000; /*make to sec from ms*/ 424 } 425 426 ALOGV("VideoEditorAudioPlayer: file duration recorded : %lld", 427 mBGAudioPCMFileDuration); 428 } 429 430 // Last played location to be seeked at for next media item 431 if ( result == M4NO_ERROR ) { 432 ALOGV("VideoEditorAudioPlayer::mBGAudioStoryBoardSkimTimeStamp %lld", 433 mBGAudioStoryBoardSkimTimeStamp); 434 ALOGV("VideoEditorAudioPlayer::uiAddCts %d", 435 mAudioMixSettings->uiAddCts); 436 if (mBGAudioStoryBoardSkimTimeStamp >= mAudioMixSettings->uiAddCts) { 437 startTime = (mBGAudioStoryBoardSkimTimeStamp - 438 mAudioMixSettings->uiAddCts); 439 } 440 else { 441 // do nothing 442 } 443 444 ALOGV("VideoEditorAudioPlayer::startTime %d", startTime); 445 seekTimeStamp = 0; 446 if (startTime) { 447 if (startTime >= mBGAudioPCMFileDuration) { 448 // The BG track should be looped and started again 449 if (mAudioMixSettings->bLoop) { 450 // Add begin cut time to the mod value 451 seekTimeStamp = ((startTime%mBGAudioPCMFileDuration) + 452 mAudioMixSettings->beginCutMs); 453 }else { 454 // Looping disabled, donot do BT Mix , set to file end 455 seekTimeStamp = (mBGAudioPCMFileDuration + 456 mAudioMixSettings->beginCutMs); 457 } 458 }else { 459 // BT still present , just seek to story board time 460 seekTimeStamp = startTime + mAudioMixSettings->beginCutMs; 461 } 462 } 463 else { 464 seekTimeStamp = mAudioMixSettings->beginCutMs; 465 } 466 467 // Convert the seekTimeStamp to file location 468 mBGAudioPCMFileOriginalSeekPoint = ( 469 (int64_t)(mAudioMixSettings->beginCutMs) 470 * mAudioMixSettings->uiSamplingFrequency 471 * mAudioMixSettings->uiNbChannels 472 * sizeof(M4OSA_UInt16))/ 1000 ; /*make to sec from ms*/ 473 474 mBGAudioPCMFileSeekPoint = ((int64_t)(seekTimeStamp) 475 * mAudioMixSettings->uiSamplingFrequency 476 * mAudioMixSettings->uiNbChannels 477 * sizeof(M4OSA_UInt16))/ 1000 ; 478 } 479 } 480 481 // We allow an optional INFO_FORMAT_CHANGED at the very beginning 482 // of playback, if there is one, getFormat below will retrieve the 483 // updated format, if there isn't, we'll stash away the valid buffer 484 // of data to be used on the first audio callback. 485 486 CHECK(mFirstBuffer == NULL); 487 488 mFirstBufferResult = mSource->read(&mFirstBuffer); 489 if (mFirstBufferResult == INFO_FORMAT_CHANGED) { 490 ALOGV("INFO_FORMAT_CHANGED!!!"); 491 492 CHECK(mFirstBuffer == NULL); 493 mFirstBufferResult = OK; 494 mIsFirstBuffer = false; 495 } else { 496 mIsFirstBuffer = true; 497 } 498 499 sp<MetaData> format = mSource->getFormat(); 500 const char *mime; 501 bool success = format->findCString(kKeyMIMEType, &mime); 502 CHECK(success); 503 CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); 504 505 success = format->findInt32(kKeySampleRate, &mSampleRate); 506 CHECK(success); 507 508 int32_t numChannels; 509 success = format->findInt32(kKeyChannelCount, &numChannels); 510 CHECK(success); 511 512 if (mAudioSink.get() != NULL) { 513 status_t err = mAudioSink->open( 514 mSampleRate, numChannels, CHANNEL_MASK_USE_CHANNEL_ORDER, AUDIO_FORMAT_PCM_16_BIT, 515 DEFAULT_AUDIOSINK_BUFFERCOUNT, 516 &VideoEditorAudioPlayer::AudioSinkCallback, this); 517 if (err != OK) { 518 if (mFirstBuffer != NULL) { 519 mFirstBuffer->release(); 520 mFirstBuffer = NULL; 521 } 522 523 if (!sourceAlreadyStarted) { 524 mSource->stop(); 525 } 526 527 return err; 528 } 529 530 mLatencyUs = (int64_t)mAudioSink->latency() * 1000; 531 mFrameSize = mAudioSink->frameSize(); 532 533 mAudioSink->start(); 534 } else { 535 mAudioTrack = new AudioTrack( 536 AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, 537 audio_channel_out_mask_from_count(numChannels), 538 0, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this, 0); 539 540 if ((err = mAudioTrack->initCheck()) != OK) { 541 delete mAudioTrack; 542 mAudioTrack = NULL; 543 544 if (mFirstBuffer != NULL) { 545 mFirstBuffer->release(); 546 mFirstBuffer = NULL; 547 } 548 549 if (!sourceAlreadyStarted) { 550 mSource->stop(); 551 } 552 553 return err; 554 } 555 556 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 557 mFrameSize = mAudioTrack->frameSize(); 558 559 mAudioTrack->start(); 560 } 561 562 mStarted = true; 563 564 return OK; 565 } 566 567 568 void VideoEditorAudioPlayer::reset() { 569 570 ALOGV("reset"); 571 clear(); 572 573 // Capture the current seek point 574 mBGAudioPCMFileSeekPoint = 0; 575 mBGAudioStoryBoardSkimTimeStamp =0; 576 mBGAudioStoryBoardCurrentMediaBeginCutTS=0; 577 } 578 579 size_t VideoEditorAudioPlayer::AudioSinkCallback( 580 MediaPlayerBase::AudioSink *audioSink, 581 void *buffer, size_t size, void *cookie) { 582 VideoEditorAudioPlayer *me = (VideoEditorAudioPlayer *)cookie; 583 584 return me->fillBuffer(buffer, size); 585 } 586 587 588 size_t VideoEditorAudioPlayer::fillBuffer(void *data, size_t size) { 589 590 if (mReachedEOS) { 591 return 0; 592 } 593 594 size_t size_done = 0; 595 size_t size_remaining = size; 596 597 M4OSA_ERR err = M4NO_ERROR; 598 M4AM_Buffer16 bgFrame = {NULL, 0}; 599 M4AM_Buffer16 mixFrame = {NULL, 0}; 600 M4AM_Buffer16 ptFrame = {NULL, 0}; 601 int64_t currentSteamTS = 0; 602 int64_t startTimeForBT = 0; 603 M4OSA_Float fPTVolLevel = 604 ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal)/100; 605 M4OSA_Int16 *pPTMdata=NULL; 606 M4OSA_UInt32 uiPCMsize = 0; 607 608 bool postSeekComplete = false; 609 bool postEOS = false; 610 611 while ((size_remaining > 0)&&(err==M4NO_ERROR)) { 612 MediaSource::ReadOptions options; 613 614 { 615 Mutex::Autolock autoLock(mLock); 616 if (mSeeking) { 617 if (mIsFirstBuffer) { 618 if (mFirstBuffer != NULL) { 619 mFirstBuffer->release(); 620 mFirstBuffer = NULL; 621 } 622 mIsFirstBuffer = false; 623 } 624 625 options.setSeekTo(mSeekTimeUs); 626 627 if (mInputBuffer != NULL) { 628 mInputBuffer->release(); 629 mInputBuffer = NULL; 630 } 631 632 mSeeking = false; 633 634 if (mObserver) { 635 postSeekComplete = true; 636 } 637 } 638 } 639 640 if (mInputBuffer == NULL) { 641 status_t status = OK; 642 643 if (mIsFirstBuffer) { 644 mInputBuffer = mFirstBuffer; 645 mFirstBuffer = NULL; 646 status = mFirstBufferResult; 647 648 mIsFirstBuffer = false; 649 } else { 650 651 { 652 Mutex::Autolock autoLock(mLock); 653 status = mSource->read(&mInputBuffer, &options); 654 } 655 // Data is Primary Track, mix with background track 656 // after reading same size from Background track PCM file 657 if (status == OK) 658 { 659 // Mix only when skim point is after startTime of BT 660 if (((mBGAudioStoryBoardSkimTimeStamp* 1000) + 661 (mPositionTimeMediaUs - mSeekTimeUs)) >= 662 (int64_t)(mAudioMixSettings->uiAddCts * 1000)) { 663 664 ALOGV("VideoEditorAudioPlayer::INSIDE MIXING"); 665 ALOGV("Checking %lld <= %lld", 666 mBGAudioPCMFileSeekPoint-mBGAudioPCMFileOriginalSeekPoint, 667 mBGAudioPCMFileTrimmedLength); 668 669 670 M4OSA_Void* ptr; 671 ptr = (M4OSA_Void*)((unsigned int)mInputBuffer->data() + 672 mInputBuffer->range_offset()); 673 674 M4OSA_UInt32 len = mInputBuffer->range_length(); 675 M4OSA_Context fp = M4OSA_NULL; 676 677 uiPCMsize = (mInputBuffer->range_length())/2; 678 pPTMdata = (M4OSA_Int16*) ((uint8_t*) mInputBuffer->data() 679 + mInputBuffer->range_offset()); 680 681 ALOGV("mix with background malloc to do len %d", len); 682 683 bgFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_32bitAlignedMalloc( len, 1, 684 (M4OSA_Char*)"bgFrame"); 685 bgFrame.m_bufferSize = len; 686 687 mixFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_32bitAlignedMalloc(len, 1, 688 (M4OSA_Char*)"mixFrame"); 689 mixFrame.m_bufferSize = len; 690 691 ALOGV("mix with bgm with size %lld", mBGAudioPCMFileLength); 692 693 CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime, 694 &mPositionTimeMediaUs)); 695 696 if (mBGAudioPCMFileSeekPoint - 697 mBGAudioPCMFileOriginalSeekPoint <= 698 (mBGAudioPCMFileTrimmedLength - len)) { 699 700 ALOGV("Checking mBGAudioPCMFileHandle %d", 701 (unsigned int)mBGAudioPCMFileHandle); 702 703 if (mBGAudioPCMFileHandle != M4OSA_NULL) { 704 ALOGV("fillBuffer seeking file to %lld", 705 mBGAudioPCMFileSeekPoint); 706 707 // TODO : 32bits required for OSAL 708 M4OSA_UInt32 tmp32 = 709 (M4OSA_UInt32)mBGAudioPCMFileSeekPoint; 710 err = M4OSA_fileReadSeek(mBGAudioPCMFileHandle, 711 M4OSA_kFileSeekBeginning, 712 (M4OSA_FilePosition*)&tmp32); 713 714 mBGAudioPCMFileSeekPoint = tmp32; 715 716 if (err != M4NO_ERROR){ 717 ALOGE("M4OSA_fileReadSeek err %d",(int)err); 718 } 719 720 err = M4OSA_fileReadData(mBGAudioPCMFileHandle, 721 (M4OSA_Int8*)bgFrame.m_dataAddress, 722 (M4OSA_UInt32*)&len); 723 if (err == M4WAR_NO_DATA_YET ) { 724 725 ALOGV("fillBuffer End of file reached"); 726 err = M4NO_ERROR; 727 728 // We reached the end of file 729 // move to begin cut time equal value 730 if (mAudioMixSettings->bLoop) { 731 mBGAudioPCMFileSeekPoint = 732 (((int64_t)(mAudioMixSettings->beginCutMs) * 733 mAudioMixSettings->uiSamplingFrequency) * 734 mAudioMixSettings->uiNbChannels * 735 sizeof(M4OSA_UInt16)) / 1000; 736 ALOGV("fillBuffer Looping \ 737 to mBGAudioPCMFileSeekPoint %lld", 738 mBGAudioPCMFileSeekPoint); 739 } 740 else { 741 // No mixing; 742 // take care of volume of primary track 743 if (fPTVolLevel < 1.0) { 744 setPrimaryTrackVolume(pPTMdata, 745 uiPCMsize, fPTVolLevel); 746 } 747 } 748 } else if (err != M4NO_ERROR ) { 749 ALOGV("fileReadData for audio err %d", err); 750 } else { 751 mBGAudioPCMFileSeekPoint += len; 752 ALOGV("fillBuffer mBGAudioPCMFileSeekPoint \ 753 %lld", mBGAudioPCMFileSeekPoint); 754 755 // Assign the ptr data to primary track 756 ptFrame.m_dataAddress = (M4OSA_UInt16*)ptr; 757 ptFrame.m_bufferSize = len; 758 759 // Call to mix and duck 760 mAudioProcess->mixAndDuck( 761 &ptFrame, &bgFrame, &mixFrame); 762 763 // Overwrite the decoded buffer 764 memcpy((void *)ptr, 765 (void *)mixFrame.m_dataAddress, len); 766 } 767 } 768 } else if (mAudioMixSettings->bLoop){ 769 // Move to begin cut time equal value 770 mBGAudioPCMFileSeekPoint = 771 mBGAudioPCMFileOriginalSeekPoint; 772 } else { 773 // No mixing; 774 // take care of volume level of primary track 775 if(fPTVolLevel < 1.0) { 776 setPrimaryTrackVolume( 777 pPTMdata, uiPCMsize, fPTVolLevel); 778 } 779 } 780 if (bgFrame.m_dataAddress) { 781 free(bgFrame.m_dataAddress); 782 } 783 if (mixFrame.m_dataAddress) { 784 free(mixFrame.m_dataAddress); 785 } 786 } else { 787 // No mixing; 788 // take care of volume level of primary track 789 if(fPTVolLevel < 1.0) { 790 setPrimaryTrackVolume(pPTMdata, uiPCMsize, 791 fPTVolLevel); 792 } 793 } 794 } 795 } 796 797 CHECK((status == OK && mInputBuffer != NULL) 798 || (status != OK && mInputBuffer == NULL)); 799 800 Mutex::Autolock autoLock(mLock); 801 802 if (status != OK) { 803 ALOGV("fillBuffer: mSource->read returned err %d", status); 804 if (mObserver && !mReachedEOS) { 805 postEOS = true; 806 } 807 808 mReachedEOS = true; 809 mFinalStatus = status; 810 break; 811 } 812 813 CHECK(mInputBuffer->meta_data()->findInt64( 814 kKeyTime, &mPositionTimeMediaUs)); 815 816 mPositionTimeRealUs = 817 ((mNumFramesPlayed + size_done / mFrameSize) * 1000000) 818 / mSampleRate; 819 820 ALOGV("buffer->size() = %d, " 821 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", 822 mInputBuffer->range_length(), 823 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); 824 } 825 826 if (mInputBuffer->range_length() == 0) { 827 mInputBuffer->release(); 828 mInputBuffer = NULL; 829 830 continue; 831 } 832 833 size_t copy = size_remaining; 834 if (copy > mInputBuffer->range_length()) { 835 copy = mInputBuffer->range_length(); 836 } 837 838 memcpy((char *)data + size_done, 839 (const char *)mInputBuffer->data() + mInputBuffer->range_offset(), 840 copy); 841 842 mInputBuffer->set_range(mInputBuffer->range_offset() + copy, 843 mInputBuffer->range_length() - copy); 844 845 size_done += copy; 846 size_remaining -= copy; 847 } 848 849 { 850 Mutex::Autolock autoLock(mLock); 851 mNumFramesPlayed += size_done / mFrameSize; 852 } 853 854 if (postEOS) { 855 mObserver->postAudioEOS(); 856 } 857 858 if (postSeekComplete) { 859 mObserver->postAudioSeekComplete(); 860 } 861 862 return size_done; 863 } 864 865 void VideoEditorAudioPlayer::setAudioMixSettings( 866 M4xVSS_AudioMixingSettings* pAudioMixSettings) { 867 mAudioMixSettings = pAudioMixSettings; 868 } 869 870 void VideoEditorAudioPlayer::setAudioMixPCMFileHandle( 871 M4OSA_Context pBGAudioPCMFileHandle){ 872 mBGAudioPCMFileHandle = pBGAudioPCMFileHandle; 873 } 874 875 void VideoEditorAudioPlayer::setAudioMixStoryBoardSkimTimeStamp( 876 M4OSA_UInt32 pBGAudioStoryBoardSkimTimeStamp, 877 M4OSA_UInt32 pBGAudioCurrentMediaBeginCutTS, 878 M4OSA_UInt32 pBGAudioCurrentMediaVolumeVal) { 879 880 mBGAudioStoryBoardSkimTimeStamp = pBGAudioStoryBoardSkimTimeStamp; 881 mBGAudioStoryBoardCurrentMediaBeginCutTS = pBGAudioCurrentMediaBeginCutTS; 882 mBGAudioStoryBoardCurrentMediaVolumeVal = pBGAudioCurrentMediaVolumeVal; 883 } 884 885 void VideoEditorAudioPlayer::setPrimaryTrackVolume( 886 M4OSA_Int16 *data, M4OSA_UInt32 size, M4OSA_Float volLevel) { 887 888 while(size-- > 0) { 889 *data = (M4OSA_Int16)((*data)*volLevel); 890 data++; 891 } 892 } 893 894 } 895