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