VideoEditorAudioPlayer.cpp revision 5df818550a13d5bd21798badcb413e7a945e15e8
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#define LOG_NDEBUG 1 19#define LOG_TAG "VideoEditorAudioPlayer" 20#include <utils/Log.h> 21 22#include <binder/IPCThreadState.h> 23#include <media/AudioTrack.h> 24#include <VideoEditorAudioPlayer.h> 25#include <media/stagefright/MediaDebug.h> 26#include <media/stagefright/MediaDefs.h> 27#include <media/stagefright/MediaErrors.h> 28#include <media/stagefright/MediaSource.h> 29#include <media/stagefright/MetaData.h> 30 31#include "PreviewPlayer.h" 32namespace android { 33 34VideoEditorAudioPlayer::VideoEditorAudioPlayer( 35 const sp<MediaPlayerBase::AudioSink> &audioSink, 36 AwesomePlayer *observer) 37 : AudioPlayer(audioSink, observer) { 38 39 LOGV("VideoEditorAudioPlayer"); 40 mBGAudioPCMFileHandle = NULL; 41 mBGAudioPCMFileLength = 0; 42 mBGAudioPCMFileTrimmedLength = 0; 43 mBGAudioPCMFileDuration = 0; 44 mBGAudioPCMFileSeekPoint = 0; 45 mBGAudioPCMFileOriginalSeekPoint = 0; 46 mBGAudioStoryBoardSkimTimeStamp = 0; 47 mBGAudioStoryBoardCurrentMediaBeginCutTS = 0; 48 mBGAudioStoryBoardCurrentMediaVolumeVal = 0; 49 mSeekTimeUs = 0; 50} 51 52VideoEditorAudioPlayer::~VideoEditorAudioPlayer() { 53 54 LOGV("~VideoEditorAudioPlayer"); 55 if (mStarted) { 56 reset(); 57 } 58 if (mAudioProcess != NULL) { 59 delete mAudioProcess; 60 mAudioProcess = NULL; 61 } 62} 63 64status_t VideoEditorAudioPlayer::start(bool sourceAlreadyStarted) { 65 66 CHECK(!mStarted); 67 CHECK(mSource != NULL); 68 LOGV("Start"); 69 status_t err; 70 M4OSA_ERR result = M4NO_ERROR; 71 M4OSA_UInt32 startTime = 0; 72 M4OSA_UInt32 seekTimeStamp = 0; 73 M4OSA_Bool bStoryBoardTSBeyondBTEndCutTime = M4OSA_FALSE; 74 75 if (!sourceAlreadyStarted) { 76 err = mSource->start(); 77 if (err != OK) { 78 return err; 79 } 80 } 81 82 // Create the BG Audio handler 83 mAudioProcess = new VideoEditorBGAudioProcessing(); 84 veAudMixSettings audioMixSettings; 85 86 // Pass on the audio ducking parameters 87 audioMixSettings.lvInDucking_threshold = mAudioMixSettings->uiInDucking_threshold; 88 audioMixSettings.lvInDucking_lowVolume = ((M4OSA_Float)mAudioMixSettings->uiInDucking_lowVolume) / 100.0; 89 audioMixSettings.lvInDucking_enable = mAudioMixSettings->bInDucking_enable; 90 audioMixSettings.lvPTVolLevel = ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal) / 100.0; 91 audioMixSettings.lvBTVolLevel = ((M4OSA_Float)mAudioMixSettings->uiAddVolume) /100.0; 92 audioMixSettings.lvBTChannelCount = mAudioMixSettings->uiBTChannelCount; 93 audioMixSettings.lvPTChannelCount = mAudioMixSettings->uiNbChannels; 94 95 // Call to Audio mix param setting 96 mAudioProcess->veSetAudioProcessingParams(audioMixSettings); 97 98 // Get the BG Audio PCM file details 99 if ( mBGAudioPCMFileHandle ) { 100 101 // TODO : 32bits required for OSAL, to be updated once OSAL is updated 102 M4OSA_UInt32 tmp32 = 0; 103 result = M4OSA_fileReadGetOption(mBGAudioPCMFileHandle, 104 M4OSA_kFileReadGetFileSize, 105 (M4OSA_Void**)&tmp32); 106 mBGAudioPCMFileLength = tmp32; 107 mBGAudioPCMFileTrimmedLength = mBGAudioPCMFileLength; 108 109 110 LOGV("VideoEditorAudioPlayer::start M4OSA_kFileReadGetFileSize = %lld", 111 mBGAudioPCMFileLength); 112 113 // Get the duration in time of the audio BT 114 if ( result == M4NO_ERROR ) { 115 LOGV("VEAP: channels = %d freq = %d", 116 mAudioMixSettings->uiNbChannels, mAudioMixSettings->uiSamplingFrequency); 117 118 // No trim 119 mBGAudioPCMFileDuration = (( 120 (int64_t)(mBGAudioPCMFileLength/sizeof(M4OSA_UInt16)/ 121 mAudioMixSettings->uiNbChannels))*1000 ) / 122 mAudioMixSettings->uiSamplingFrequency; 123 124 LOGV("VideoEditorAudioPlayer:: beginCutMs %d , endCutMs %d", 125 (unsigned int) mAudioMixSettings->beginCutMs, 126 (unsigned int) mAudioMixSettings->endCutMs); 127 128 // Remove the trim part 129 if ((mAudioMixSettings->beginCutMs == 0) && 130 (mAudioMixSettings->endCutMs != 0)) { 131 // End time itself the file duration 132 mBGAudioPCMFileDuration = mAudioMixSettings->endCutMs; 133 // Limit the file length also 134 mBGAudioPCMFileTrimmedLength = (( 135 (int64_t)(mBGAudioPCMFileDuration * 136 mAudioMixSettings->uiSamplingFrequency) * 137 mAudioMixSettings->uiNbChannels) * 138 sizeof(M4OSA_UInt16)) / 1000; 139 } 140 else if ((mAudioMixSettings->beginCutMs != 0) && 141 (mAudioMixSettings->endCutMs == mBGAudioPCMFileDuration)) { 142 // End time itself the file duration 143 mBGAudioPCMFileDuration = mBGAudioPCMFileDuration - 144 mAudioMixSettings->beginCutMs; 145 // Limit the file length also 146 mBGAudioPCMFileTrimmedLength = (( 147 (int64_t)(mBGAudioPCMFileDuration * 148 mAudioMixSettings->uiSamplingFrequency) * 149 mAudioMixSettings->uiNbChannels) * 150 sizeof(M4OSA_UInt16)) / 1000; 151 } 152 else if ((mAudioMixSettings->beginCutMs != 0) && 153 (mAudioMixSettings->endCutMs != 0)) { 154 // End time itself the file duration 155 mBGAudioPCMFileDuration = mAudioMixSettings->endCutMs - 156 mAudioMixSettings->beginCutMs; 157 // Limit the file length also 158 mBGAudioPCMFileTrimmedLength = (( 159 (int64_t)(mBGAudioPCMFileDuration * 160 mAudioMixSettings->uiSamplingFrequency) * 161 mAudioMixSettings->uiNbChannels) * 162 sizeof(M4OSA_UInt16)) / 1000; /*make to sec from ms*/ 163 } 164 165 LOGV("VideoEditorAudioPlayer: file duration recorded : %lld", 166 mBGAudioPCMFileDuration); 167 } 168 169 // Last played location to be seeked at for next media item 170 if ( result == M4NO_ERROR ) { 171 LOGV("VideoEditorAudioPlayer::mBGAudioStoryBoardSkimTimeStamp %lld", 172 mBGAudioStoryBoardSkimTimeStamp); 173 LOGV("VideoEditorAudioPlayer::uiAddCts %d", 174 mAudioMixSettings->uiAddCts); 175 if (mBGAudioStoryBoardSkimTimeStamp >= mAudioMixSettings->uiAddCts) { 176 startTime = (mBGAudioStoryBoardSkimTimeStamp - 177 mAudioMixSettings->uiAddCts); 178 } 179 else { 180 // do nothing 181 } 182 183 LOGV("VideoEditorAudioPlayer::startTime %d", startTime); 184 seekTimeStamp = 0; 185 if (startTime) { 186 if (startTime >= mBGAudioPCMFileDuration) { 187 // The BG track should be looped and started again 188 if (mAudioMixSettings->bLoop) { 189 // Add begin cut time to the mod value 190 seekTimeStamp = ((startTime%mBGAudioPCMFileDuration) + 191 mAudioMixSettings->beginCutMs); 192 }else { 193 // Looping disabled, donot do BT Mix , set to file end 194 seekTimeStamp = (mBGAudioPCMFileDuration + 195 mAudioMixSettings->beginCutMs); 196 } 197 }else { 198 // BT still present , just seek to story board time 199 seekTimeStamp = startTime + mAudioMixSettings->beginCutMs; 200 } 201 } 202 else { 203 seekTimeStamp = mAudioMixSettings->beginCutMs; 204 } 205 206 // Convert the seekTimeStamp to file location 207 mBGAudioPCMFileOriginalSeekPoint = ( 208 (int64_t)(mAudioMixSettings->beginCutMs) 209 * mAudioMixSettings->uiSamplingFrequency 210 * mAudioMixSettings->uiNbChannels 211 * sizeof(M4OSA_UInt16))/ 1000 ; /*make to sec from ms*/ 212 213 mBGAudioPCMFileSeekPoint = ((int64_t)(seekTimeStamp) 214 * mAudioMixSettings->uiSamplingFrequency 215 * mAudioMixSettings->uiNbChannels 216 * sizeof(M4OSA_UInt16))/ 1000 ; 217 } 218 } 219 220 // We allow an optional INFO_FORMAT_CHANGED at the very beginning 221 // of playback, if there is one, getFormat below will retrieve the 222 // updated format, if there isn't, we'll stash away the valid buffer 223 // of data to be used on the first audio callback. 224 225 CHECK(mFirstBuffer == NULL); 226 227 mFirstBufferResult = mSource->read(&mFirstBuffer); 228 if (mFirstBufferResult == INFO_FORMAT_CHANGED) { 229 LOGV("INFO_FORMAT_CHANGED!!!"); 230 231 CHECK(mFirstBuffer == NULL); 232 mFirstBufferResult = OK; 233 mIsFirstBuffer = false; 234 } else { 235 mIsFirstBuffer = true; 236 } 237 238 sp<MetaData> format = mSource->getFormat(); 239 const char *mime; 240 bool success = format->findCString(kKeyMIMEType, &mime); 241 CHECK(success); 242 CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); 243 244 success = format->findInt32(kKeySampleRate, &mSampleRate); 245 CHECK(success); 246 247 int32_t numChannels; 248 success = format->findInt32(kKeyChannelCount, &numChannels); 249 CHECK(success); 250 251 if (mAudioSink.get() != NULL) { 252 status_t err = mAudioSink->open( 253 mSampleRate, numChannels, AudioSystem::PCM_16_BIT, 254 DEFAULT_AUDIOSINK_BUFFERCOUNT, 255 &VideoEditorAudioPlayer::AudioSinkCallback, this); 256 if (err != OK) { 257 if (mFirstBuffer != NULL) { 258 mFirstBuffer->release(); 259 mFirstBuffer = NULL; 260 } 261 262 if (!sourceAlreadyStarted) { 263 mSource->stop(); 264 } 265 266 return err; 267 } 268 269 mLatencyUs = (int64_t)mAudioSink->latency() * 1000; 270 mFrameSize = mAudioSink->frameSize(); 271 272 mAudioSink->start(); 273 } else { 274 mAudioTrack = new AudioTrack( 275 AudioSystem::MUSIC, mSampleRate, AudioSystem::PCM_16_BIT, 276 (numChannels == 2) 277 ? AudioSystem::CHANNEL_OUT_STEREO 278 : AudioSystem::CHANNEL_OUT_MONO, 279 0, 0, &AudioCallback, this, 0); 280 281 if ((err = mAudioTrack->initCheck()) != OK) { 282 delete mAudioTrack; 283 mAudioTrack = NULL; 284 285 if (mFirstBuffer != NULL) { 286 mFirstBuffer->release(); 287 mFirstBuffer = NULL; 288 } 289 290 if (!sourceAlreadyStarted) { 291 mSource->stop(); 292 } 293 294 return err; 295 } 296 297 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 298 mFrameSize = mAudioTrack->frameSize(); 299 300 mAudioTrack->start(); 301 } 302 303 mStarted = true; 304 305 return OK; 306} 307 308void VideoEditorAudioPlayer::reset() { 309 310 LOGV("reset"); 311 AudioPlayer::reset(); 312 313 // Capture the current seek point 314 mBGAudioPCMFileSeekPoint = 0; 315 mBGAudioStoryBoardSkimTimeStamp =0; 316 mBGAudioStoryBoardCurrentMediaBeginCutTS=0; 317} 318 319size_t VideoEditorAudioPlayer::AudioSinkCallback( 320 MediaPlayerBase::AudioSink *audioSink, 321 void *buffer, size_t size, void *cookie) { 322 VideoEditorAudioPlayer *me = (VideoEditorAudioPlayer *)cookie; 323 324 return me->fillBuffer(buffer, size); 325} 326 327 328size_t VideoEditorAudioPlayer::fillBuffer(void *data, size_t size) { 329 330 if (mReachedEOS) { 331 return 0; 332 } 333 334 size_t size_done = 0; 335 size_t size_remaining = size; 336 337 M4OSA_ERR err = M4NO_ERROR; 338 M4AM_Buffer bgFrame = {NULL, 0}; 339 M4AM_Buffer mixFrame = {NULL, 0}; 340 M4AM_Buffer ptFrame = {NULL, 0}; 341 int64_t currentSteamTS = 0; 342 int64_t startTimeForBT = 0; 343 M4OSA_Float fPTVolLevel = 344 ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal)/100; 345 M4OSA_Int16 *pPTMdata; 346 M4OSA_UInt32 uiPCMsize = 0; 347 348 while ((size_remaining > 0)&&(err==M4NO_ERROR)) { 349 MediaSource::ReadOptions options; 350 351 { 352 Mutex::Autolock autoLock(mLock); 353 if (mSeeking) { 354 if (mIsFirstBuffer) { 355 if (mFirstBuffer != NULL) { 356 mFirstBuffer->release(); 357 mFirstBuffer = NULL; 358 } 359 mIsFirstBuffer = false; 360 } 361 362 options.setSeekTo(mSeekTimeUs); 363 364 if (mInputBuffer != NULL) { 365 mInputBuffer->release(); 366 mInputBuffer = NULL; 367 } 368 369 mSeeking = false; 370 if (mObserver) { 371 mObserver->postAudioSeekComplete(); 372 } 373 } 374 } 375 376 if (mInputBuffer == NULL) { 377 status_t status = OK; 378 379 if (mIsFirstBuffer) { 380 mInputBuffer = mFirstBuffer; 381 mFirstBuffer = NULL; 382 status = mFirstBufferResult; 383 384 mIsFirstBuffer = false; 385 } else { 386 status = mSource->read(&mInputBuffer, &options); 387 // Data is Primary Track, mix with background track 388 // after reading same size from Background track PCM file 389 if (status == OK) 390 { 391 // Mix only when skim point is after startTime of BT 392 if (((mBGAudioStoryBoardSkimTimeStamp* 1000) + 393 (mPositionTimeMediaUs - mSeekTimeUs)) >= 394 (int64_t)(mAudioMixSettings->uiAddCts * 1000)) { 395 396 LOGV("VideoEditorAudioPlayer::INSIDE MIXING"); 397 LOGV("Checking %lld <= %lld - %d", 398 mBGAudioPCMFileSeekPoint-mBGAudioPCMFileOriginalSeekPoint, 399 mBGAudioPCMFileTrimmedLength, len); 400 401 402 M4OSA_Void* ptr; 403 ptr = (M4OSA_Void*)((unsigned int)mInputBuffer->data() + 404 mInputBuffer->range_offset()); 405 406 M4OSA_UInt32 len = mInputBuffer->range_length(); 407 M4OSA_Context fp = M4OSA_NULL; 408 409 uiPCMsize = (mInputBuffer->range_length())/2; 410 pPTMdata = (M4OSA_Int16*) ((uint8_t*) mInputBuffer->data() 411 + mInputBuffer->range_offset()); 412 413 LOGV("mix with background malloc to do len %d", len); 414 415 bgFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_malloc( len, 1, 416 (M4OSA_Char*)"bgFrame"); 417 if (NULL == bgFrame.m_dataAddress) { 418 LOGE("mBackgroundAudioSetting Malloc failed"); 419 } 420 421 bgFrame.m_bufferSize = len; 422 423 mixFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_malloc(len, 1, 424 (M4OSA_Char*)"mixFrame"); 425 if (NULL == mixFrame.m_dataAddress) { 426 LOGE("mBackgroundAudioSetting Malloc failed"); 427 } 428 429 mixFrame.m_bufferSize = len; 430 431 LOGV("mix with bgm with size %lld", mBGAudioPCMFileLength); 432 433 CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime, 434 &mPositionTimeMediaUs)); 435 436 if (mBGAudioPCMFileSeekPoint - 437 mBGAudioPCMFileOriginalSeekPoint <= 438 (mBGAudioPCMFileTrimmedLength - len)) { 439 440 LOGV("Checking mBGAudioPCMFileHandle %d", 441 (unsigned int)mBGAudioPCMFileHandle); 442 443 if (mBGAudioPCMFileHandle != M4OSA_NULL) { 444 LOGV("fillBuffer seeking file to %lld", 445 mBGAudioPCMFileSeekPoint); 446 447 // TODO : 32bits required for OSAL 448 M4OSA_UInt32 tmp32 = 449 (M4OSA_UInt32)mBGAudioPCMFileSeekPoint; 450 err = M4OSA_fileReadSeek(mBGAudioPCMFileHandle, 451 M4OSA_kFileSeekBeginning, 452 (M4OSA_FilePosition*)&tmp32); 453 454 mBGAudioPCMFileSeekPoint = tmp32; 455 456 if (err != M4NO_ERROR){ 457 LOGE("M4OSA_fileReadSeek err %d", err); 458 } 459 460 err = M4OSA_fileReadData(mBGAudioPCMFileHandle, 461 (M4OSA_Int8*)bgFrame.m_dataAddress, 462 (M4OSA_UInt32*)&len); 463 if (err == M4WAR_NO_DATA_YET ) { 464 465 LOGV("fillBuffer End of file reached"); 466 err = M4NO_ERROR; 467 468 // We reached the end of file 469 // move to begin cut time equal value 470 if (mAudioMixSettings->bLoop) { 471 mBGAudioPCMFileSeekPoint = 472 (((int64_t)(mAudioMixSettings->beginCutMs) * 473 mAudioMixSettings->uiSamplingFrequency) * 474 mAudioMixSettings->uiNbChannels * 475 sizeof(M4OSA_UInt16)) / 1000; 476 LOGV("fillBuffer Looping \ 477 to mBGAudioPCMFileSeekPoint %lld", 478 mBGAudioPCMFileSeekPoint); 479 } 480 else { 481 // No mixing; 482 // take care of volume of primary track 483 if (fPTVolLevel < 1.0) { 484 setPrimaryTrackVolume(pPTMdata, 485 uiPCMsize, fPTVolLevel); 486 } 487 } 488 } else if (err != M4NO_ERROR ) { 489 LOGV("fileReadData for audio err %d", err); 490 } else { 491 mBGAudioPCMFileSeekPoint += len; 492 LOGV("fillBuffer mBGAudioPCMFileSeekPoint \ 493 %lld", mBGAudioPCMFileSeekPoint); 494 495 // Assign the ptr data to primary track 496 ptFrame.m_dataAddress = (M4OSA_UInt16*)ptr; 497 ptFrame.m_bufferSize = len; 498 499 // Call to mix and duck 500 mAudioProcess->veProcessAudioMixNDuck( 501 &ptFrame, &bgFrame, &mixFrame); 502 503 // Overwrite the decoded buffer 504 M4OSA_memcpy((M4OSA_MemAddr8)ptr, 505 (M4OSA_MemAddr8)mixFrame.m_dataAddress, len); 506 } 507 } 508 } else if (mAudioMixSettings->bLoop){ 509 // Move to begin cut time equal value 510 mBGAudioPCMFileSeekPoint = 511 mBGAudioPCMFileOriginalSeekPoint; 512 } else { 513 // No mixing; 514 // take care of volume level of primary track 515 if(fPTVolLevel < 1.0) { 516 setPrimaryTrackVolume( 517 pPTMdata, uiPCMsize, fPTVolLevel); 518 } 519 } 520 if (bgFrame.m_dataAddress) { 521 M4OSA_free((M4OSA_MemAddr32)bgFrame.m_dataAddress); 522 } 523 if (mixFrame.m_dataAddress) { 524 M4OSA_free((M4OSA_MemAddr32)mixFrame.m_dataAddress); 525 } 526 } else { 527 // No mixing; 528 // take care of volume level of primary track 529 if(fPTVolLevel < 1.0) { 530 setPrimaryTrackVolume(pPTMdata, uiPCMsize, 531 fPTVolLevel); 532 } 533 } 534 } 535 } 536 537 CHECK((status == OK && mInputBuffer != NULL) 538 || (status != OK && mInputBuffer == NULL)); 539 540 Mutex::Autolock autoLock(mLock); 541 542 if (status != OK) { 543 LOGV("fillBuffer: mSource->read returned err %d", status); 544 if (mObserver && !mReachedEOS) { 545 mObserver->postAudioEOS(); 546 } 547 548 mReachedEOS = true; 549 mFinalStatus = status; 550 break; 551 } 552 553 CHECK(mInputBuffer->meta_data()->findInt64( 554 kKeyTime, &mPositionTimeMediaUs)); 555 556 mPositionTimeRealUs = 557 ((mNumFramesPlayed + size_done / mFrameSize) * 1000000) 558 / mSampleRate; 559 560 LOGV("buffer->size() = %d, " 561 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", 562 mInputBuffer->range_length(), 563 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); 564 } 565 566 if (mInputBuffer->range_length() == 0) { 567 mInputBuffer->release(); 568 mInputBuffer = NULL; 569 570 continue; 571 } 572 573 size_t copy = size_remaining; 574 if (copy > mInputBuffer->range_length()) { 575 copy = mInputBuffer->range_length(); 576 } 577 578 memcpy((char *)data + size_done, 579 (const char *)mInputBuffer->data() + mInputBuffer->range_offset(), 580 copy); 581 582 mInputBuffer->set_range(mInputBuffer->range_offset() + copy, 583 mInputBuffer->range_length() - copy); 584 585 size_done += copy; 586 size_remaining -= copy; 587 } 588 589 Mutex::Autolock autoLock(mLock); 590 mNumFramesPlayed += size_done / mFrameSize; 591 592 return size_done; 593} 594 595void VideoEditorAudioPlayer::setAudioMixSettings( 596 M4xVSS_AudioMixingSettings* pAudioMixSettings) { 597 mAudioMixSettings = pAudioMixSettings; 598} 599 600void VideoEditorAudioPlayer::setAudioMixPCMFileHandle( 601 M4OSA_Context pBGAudioPCMFileHandle){ 602 mBGAudioPCMFileHandle = pBGAudioPCMFileHandle; 603} 604 605void VideoEditorAudioPlayer::setAudioMixStoryBoardSkimTimeStamp( 606 M4OSA_UInt32 pBGAudioStoryBoardSkimTimeStamp, 607 M4OSA_UInt32 pBGAudioCurrentMediaBeginCutTS, 608 M4OSA_UInt32 pBGAudioCurrentMediaVolumeVal) { 609 610 mBGAudioStoryBoardSkimTimeStamp = pBGAudioStoryBoardSkimTimeStamp; 611 mBGAudioStoryBoardCurrentMediaBeginCutTS = pBGAudioCurrentMediaBeginCutTS; 612 mBGAudioStoryBoardCurrentMediaVolumeVal = pBGAudioCurrentMediaVolumeVal; 613} 614 615void VideoEditorAudioPlayer::setPrimaryTrackVolume( 616 M4OSA_Int16 *data, M4OSA_UInt32 size, M4OSA_Float volLevel) { 617 618 while(size-- > 0) { 619 *data = (M4OSA_Int16)((*data)*volLevel); 620 data++; 621 } 622} 623 624} 625