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