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