blob: e5039367b2d6054accf1acb280fba7292bfce732 [file] [log] [blame]
Dharmaray Kundargi643290d2011-01-16 16:02:42 -08001/*
Dharmaray Kundargi643290d2011-01-16 16:02:42 -08002 * 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>
James Dongc4689fa2012-02-08 13:51:46 -080024#include <media/stagefright/foundation/ADebug.h>
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080025#include <media/stagefright/MediaDefs.h>
26#include <media/stagefright/MediaErrors.h>
27#include <media/stagefright/MediaSource.h>
28#include <media/stagefright/MetaData.h>
29
Dima Zavin272eb552011-05-11 14:15:37 -070030#include <system/audio.h>
Dima Zavin68598372011-04-05 16:13:49 -070031
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080032#include "PreviewPlayer.h"
33namespace android {
34
35VideoEditorAudioPlayer::VideoEditorAudioPlayer(
36 const sp<MediaPlayerBase::AudioSink> &audioSink,
James Dong00f742c2012-01-13 17:34:42 -080037 PreviewPlayer *observer)
Glenn Kasten2799d742013-05-30 14:33:29 -070038 : mInputBuffer(NULL),
James Dong727f9e12012-01-20 13:09:13 -080039 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) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080054
James Dong727f9e12012-01-20 13:09:13 -080055 ALOGV("Constructor");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080056 mBGAudioPCMFileHandle = NULL;
Dheeraj Sharma5bc7fb42011-02-13 20:31:27 -080057 mAudioProcess = NULL;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080058 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;
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -080067 mSource = NULL;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080068}
69
70VideoEditorAudioPlayer::~VideoEditorAudioPlayer() {
71
James Dong727f9e12012-01-20 13:09:13 -080072 ALOGV("Destructor");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080073 if (mStarted) {
74 reset();
75 }
Santosh Madhava5df81852011-02-11 00:43:26 -080076 if (mAudioProcess != NULL) {
77 delete mAudioProcess;
78 mAudioProcess = NULL;
79 }
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080080}
James Dong727f9e12012-01-20 13:09:13 -080081
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
Glenn Kasten2799d742013-05-30 14:33:29 -0700113 mAudioTrack.clear();
James Dong727f9e12012-01-20 13:09:13 -0800114 }
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
Richard Fitzgerald94ea60f2013-05-14 15:52:03 +0100152status_t VideoEditorAudioPlayer::resume() {
James Dong727f9e12012-01-20 13:09:13 -0800153 ALOGV("resume");
154
James Dong3bd45592012-01-20 19:28:01 -0800155 AudioMixSettings audioMixSettings;
James Dong727f9e12012-01-20 13:09:13 -0800156
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
James Dong3bd45592012-01-20 19:28:01 -0800174 mAudioProcess->setMixParams(audioMixSettings);
James Dong727f9e12012-01-20 13:09:13 -0800175
176 CHECK(mStarted);
177
178 if (mAudioSink.get() != NULL) {
179 mAudioSink->start();
180 } else {
181 mAudioTrack->start();
182 }
Richard Fitzgerald94ea60f2013-05-14 15:52:03 +0100183 return OK;
James Dong727f9e12012-01-20 13:09:13 -0800184}
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
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800259void VideoEditorAudioPlayer::setSource(const sp<MediaSource> &source) {
260 Mutex::Autolock autoLock(mLock);
Rajneesh Chowduryb6e2b5c2011-02-25 22:59:46 -0800261
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) {
Steve Block2703f232011-10-20 11:56:09 +0100272 ALOGV("VideoEditorAudioPlayer releasing input buffer.");
Rajneesh Chowduryb6e2b5c2011-02-25 22:59:46 -0800273
274 mInputBuffer->release();
275 mInputBuffer = NULL;
276 }
277
278 if (mSource != NULL) {
279 mSource->stop();
280 mSource.clear();
281 }
282
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800283 mSource = source;
284 mReachedEOS = false;
285}
286
287sp<MediaSource> VideoEditorAudioPlayer::getSource() {
288 Mutex::Autolock autoLock(mLock);
289 return mSource;
290}
291
James Dong00f742c2012-01-13 17:34:42 -0800292void VideoEditorAudioPlayer::setObserver(PreviewPlayer *observer) {
Steve Block2703f232011-10-20 11:56:09 +0100293 ALOGV("setObserver");
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800294 //CHECK(!mStarted);
295 mObserver = observer;
296}
297
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800298bool VideoEditorAudioPlayer::isStarted() {
299 return mStarted;
300}
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800301
James Dong727f9e12012-01-20 13:09:13 -0800302// 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
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800319status_t VideoEditorAudioPlayer::start(bool sourceAlreadyStarted) {
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800320 Mutex::Autolock autoLock(mLock);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800321 CHECK(!mStarted);
322 CHECK(mSource != NULL);
Steve Block2703f232011-10-20 11:56:09 +0100323 ALOGV("Start");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800324 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();
James Dong3bd45592012-01-20 19:28:01 -0800339 AudioMixSettings audioMixSettings;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800340
341 // Pass on the audio ducking parameters
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800342 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;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800352 audioMixSettings.lvBTChannelCount = mAudioMixSettings->uiBTChannelCount;
353 audioMixSettings.lvPTChannelCount = mAudioMixSettings->uiNbChannels;
354
355 // Call to Audio mix param setting
James Dong3bd45592012-01-20 19:28:01 -0800356 mAudioProcess->setMixParams(audioMixSettings);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800357
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
Steve Block2703f232011-10-20 11:56:09 +0100370 ALOGV("VideoEditorAudioPlayer::start M4OSA_kFileReadGetFileSize = %lld",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800371 mBGAudioPCMFileLength);
372
373 // Get the duration in time of the audio BT
374 if ( result == M4NO_ERROR ) {
Steve Block2703f232011-10-20 11:56:09 +0100375 ALOGV("VEAP: channels = %d freq = %d",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800376 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
Steve Block2703f232011-10-20 11:56:09 +0100384 ALOGV("VideoEditorAudioPlayer:: beginCutMs %d , endCutMs %d",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800385 (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
Steve Block2703f232011-10-20 11:56:09 +0100425 ALOGV("VideoEditorAudioPlayer: file duration recorded : %lld",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800426 mBGAudioPCMFileDuration);
427 }
428
429 // Last played location to be seeked at for next media item
430 if ( result == M4NO_ERROR ) {
Steve Block2703f232011-10-20 11:56:09 +0100431 ALOGV("VideoEditorAudioPlayer::mBGAudioStoryBoardSkimTimeStamp %lld",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800432 mBGAudioStoryBoardSkimTimeStamp);
Steve Block2703f232011-10-20 11:56:09 +0100433 ALOGV("VideoEditorAudioPlayer::uiAddCts %d",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800434 mAudioMixSettings->uiAddCts);
435 if (mBGAudioStoryBoardSkimTimeStamp >= mAudioMixSettings->uiAddCts) {
436 startTime = (mBGAudioStoryBoardSkimTimeStamp -
437 mAudioMixSettings->uiAddCts);
438 }
439 else {
440 // do nothing
441 }
442
Steve Block2703f232011-10-20 11:56:09 +0100443 ALOGV("VideoEditorAudioPlayer::startTime %d", startTime);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800444 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) {
Steve Block2703f232011-10-20 11:56:09 +0100489 ALOGV("INFO_FORMAT_CHANGED!!!");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800490
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(
Jean-Michel Trivi8162c1a2012-03-02 14:34:10 -0800513 mSampleRate, numChannels, CHANNEL_MASK_USE_CHANNEL_ORDER, AUDIO_FORMAT_PCM_16_BIT,
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800514 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(
Dima Zavin68598372011-04-05 16:13:49 -0700535 AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT,
Glenn Kasten28b76b32012-07-03 17:24:41 -0700536 audio_channel_out_mask_from_count(numChannels),
Eric Laurent0ca3cf92012-04-18 09:24:29 -0700537 0, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this, 0);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800538
539 if ((err = mAudioTrack->initCheck()) != OK) {
Glenn Kasten2799d742013-05-30 14:33:29 -0700540 mAudioTrack.clear();
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800541
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
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800565
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800566void VideoEditorAudioPlayer::reset() {
567
Steve Block2703f232011-10-20 11:56:09 +0100568 ALOGV("reset");
James Dong727f9e12012-01-20 13:09:13 -0800569 clear();
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800570
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,
Richard Fitzgeraldad3af332013-03-25 16:54:37 +0000579 void *buffer, size_t size, void *cookie,
580 MediaPlayerBase::AudioSink::cb_event_t event) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800581 VideoEditorAudioPlayer *me = (VideoEditorAudioPlayer *)cookie;
582
Richard Fitzgeraldad3af332013-03-25 16:54:37 +0000583 if (event == MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER ) {
584 return me->fillBuffer(buffer, size);
585 } else {
586 return 0;
587 }
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800588}
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;
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800601 M4AM_Buffer16 bgFrame = {NULL, 0};
602 M4AM_Buffer16 mixFrame = {NULL, 0};
603 M4AM_Buffer16 ptFrame = {NULL, 0};
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800604 int64_t currentSteamTS = 0;
605 int64_t startTimeForBT = 0;
606 M4OSA_Float fPTVolLevel =
607 ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal)/100;
Basavapatna Dattaguru100d0182011-03-04 09:48:24 -0800608 M4OSA_Int16 *pPTMdata=NULL;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800609 M4OSA_UInt32 uiPCMsize = 0;
610
Andreas Huber838daaf2011-04-04 11:38:25 -0700611 bool postSeekComplete = false;
612 bool postEOS = false;
613
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800614 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;
Andreas Huber838daaf2011-04-04 11:38:25 -0700636
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800637 if (mObserver) {
Andreas Huber838daaf2011-04-04 11:38:25 -0700638 postSeekComplete = true;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800639 }
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 {
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800653
654 {
655 Mutex::Autolock autoLock(mLock);
656 status = mSource->read(&mInputBuffer, &options);
657 }
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800658 // 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
Steve Block2703f232011-10-20 11:56:09 +0100667 ALOGV("VideoEditorAudioPlayer::INSIDE MIXING");
668 ALOGV("Checking %lld <= %lld",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800669 mBGAudioPCMFileSeekPoint-mBGAudioPCMFileOriginalSeekPoint,
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800670 mBGAudioPCMFileTrimmedLength);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800671
672
673 M4OSA_Void* ptr;
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000674 ptr = reinterpret_cast<M4OSA_Void*>(
675 reinterpret_cast<uintptr_t>(mInputBuffer->data()) +
676 mInputBuffer->range_offset());
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800677
678 M4OSA_UInt32 len = mInputBuffer->range_length();
679 M4OSA_Context fp = M4OSA_NULL;
680
681 uiPCMsize = (mInputBuffer->range_length())/2;
Kenny Rooteb5b2652011-02-08 11:13:19 -0800682 pPTMdata = (M4OSA_Int16*) ((uint8_t*) mInputBuffer->data()
683 + mInputBuffer->range_offset());
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800684
Steve Block2703f232011-10-20 11:56:09 +0100685 ALOGV("mix with background malloc to do len %d", len);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800686
Shyam Pallapothu694816d2011-04-21 09:48:41 -0700687 bgFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_32bitAlignedMalloc( len, 1,
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800688 (M4OSA_Char*)"bgFrame");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800689 bgFrame.m_bufferSize = len;
690
Shyam Pallapothu694816d2011-04-21 09:48:41 -0700691 mixFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_32bitAlignedMalloc(len, 1,
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800692 (M4OSA_Char*)"mixFrame");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800693 mixFrame.m_bufferSize = len;
694
Steve Block2703f232011-10-20 11:56:09 +0100695 ALOGV("mix with bgm with size %lld", mBGAudioPCMFileLength);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800696
697 CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime,
698 &mPositionTimeMediaUs));
699
700 if (mBGAudioPCMFileSeekPoint -
701 mBGAudioPCMFileOriginalSeekPoint <=
702 (mBGAudioPCMFileTrimmedLength - len)) {
703
Steve Block2703f232011-10-20 11:56:09 +0100704 ALOGV("Checking mBGAudioPCMFileHandle %d",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800705 (unsigned int)mBGAudioPCMFileHandle);
706
707 if (mBGAudioPCMFileHandle != M4OSA_NULL) {
Steve Block2703f232011-10-20 11:56:09 +0100708 ALOGV("fillBuffer seeking file to %lld",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800709 mBGAudioPCMFileSeekPoint);
710
711 // TODO : 32bits required for OSAL
712 M4OSA_UInt32 tmp32 =
713 (M4OSA_UInt32)mBGAudioPCMFileSeekPoint;
714 err = M4OSA_fileReadSeek(mBGAudioPCMFileHandle,
715 M4OSA_kFileSeekBeginning,
716 (M4OSA_FilePosition*)&tmp32);
717
718 mBGAudioPCMFileSeekPoint = tmp32;
719
720 if (err != M4NO_ERROR){
Steve Blockf8bd29c2012-01-08 10:14:44 +0000721 ALOGE("M4OSA_fileReadSeek err %d",(int)err);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800722 }
723
724 err = M4OSA_fileReadData(mBGAudioPCMFileHandle,
725 (M4OSA_Int8*)bgFrame.m_dataAddress,
726 (M4OSA_UInt32*)&len);
727 if (err == M4WAR_NO_DATA_YET ) {
728
Steve Block2703f232011-10-20 11:56:09 +0100729 ALOGV("fillBuffer End of file reached");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800730 err = M4NO_ERROR;
731
732 // We reached the end of file
733 // move to begin cut time equal value
734 if (mAudioMixSettings->bLoop) {
735 mBGAudioPCMFileSeekPoint =
736 (((int64_t)(mAudioMixSettings->beginCutMs) *
737 mAudioMixSettings->uiSamplingFrequency) *
738 mAudioMixSettings->uiNbChannels *
739 sizeof(M4OSA_UInt16)) / 1000;
Steve Block2703f232011-10-20 11:56:09 +0100740 ALOGV("fillBuffer Looping \
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800741 to mBGAudioPCMFileSeekPoint %lld",
742 mBGAudioPCMFileSeekPoint);
743 }
744 else {
745 // No mixing;
746 // take care of volume of primary track
747 if (fPTVolLevel < 1.0) {
748 setPrimaryTrackVolume(pPTMdata,
749 uiPCMsize, fPTVolLevel);
750 }
751 }
752 } else if (err != M4NO_ERROR ) {
Steve Block2703f232011-10-20 11:56:09 +0100753 ALOGV("fileReadData for audio err %d", err);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800754 } else {
755 mBGAudioPCMFileSeekPoint += len;
Steve Block2703f232011-10-20 11:56:09 +0100756 ALOGV("fillBuffer mBGAudioPCMFileSeekPoint \
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800757 %lld", mBGAudioPCMFileSeekPoint);
758
759 // Assign the ptr data to primary track
760 ptFrame.m_dataAddress = (M4OSA_UInt16*)ptr;
761 ptFrame.m_bufferSize = len;
762
763 // Call to mix and duck
James Dong3bd45592012-01-20 19:28:01 -0800764 mAudioProcess->mixAndDuck(
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800765 &ptFrame, &bgFrame, &mixFrame);
766
767 // Overwrite the decoded buffer
Shyam Pallapothu32ed3f42011-04-20 21:00:48 -0700768 memcpy((void *)ptr,
769 (void *)mixFrame.m_dataAddress, len);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800770 }
771 }
772 } else if (mAudioMixSettings->bLoop){
773 // Move to begin cut time equal value
774 mBGAudioPCMFileSeekPoint =
775 mBGAudioPCMFileOriginalSeekPoint;
776 } else {
777 // No mixing;
778 // take care of volume level of primary track
779 if(fPTVolLevel < 1.0) {
780 setPrimaryTrackVolume(
781 pPTMdata, uiPCMsize, fPTVolLevel);
782 }
783 }
784 if (bgFrame.m_dataAddress) {
Shyam Pallapothu694816d2011-04-21 09:48:41 -0700785 free(bgFrame.m_dataAddress);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800786 }
787 if (mixFrame.m_dataAddress) {
Shyam Pallapothu694816d2011-04-21 09:48:41 -0700788 free(mixFrame.m_dataAddress);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800789 }
790 } else {
791 // No mixing;
792 // take care of volume level of primary track
793 if(fPTVolLevel < 1.0) {
794 setPrimaryTrackVolume(pPTMdata, uiPCMsize,
795 fPTVolLevel);
796 }
797 }
798 }
799 }
800
801 CHECK((status == OK && mInputBuffer != NULL)
802 || (status != OK && mInputBuffer == NULL));
803
804 Mutex::Autolock autoLock(mLock);
805
806 if (status != OK) {
Steve Block2703f232011-10-20 11:56:09 +0100807 ALOGV("fillBuffer: mSource->read returned err %d", status);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800808 if (mObserver && !mReachedEOS) {
Andreas Huber838daaf2011-04-04 11:38:25 -0700809 postEOS = true;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800810 }
811
812 mReachedEOS = true;
813 mFinalStatus = status;
814 break;
815 }
816
817 CHECK(mInputBuffer->meta_data()->findInt64(
818 kKeyTime, &mPositionTimeMediaUs));
819
820 mPositionTimeRealUs =
821 ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
822 / mSampleRate;
823
Steve Block2703f232011-10-20 11:56:09 +0100824 ALOGV("buffer->size() = %d, "
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800825 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
826 mInputBuffer->range_length(),
827 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
828 }
829
830 if (mInputBuffer->range_length() == 0) {
831 mInputBuffer->release();
832 mInputBuffer = NULL;
833
834 continue;
835 }
836
837 size_t copy = size_remaining;
838 if (copy > mInputBuffer->range_length()) {
839 copy = mInputBuffer->range_length();
840 }
841
842 memcpy((char *)data + size_done,
843 (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),
844 copy);
845
846 mInputBuffer->set_range(mInputBuffer->range_offset() + copy,
847 mInputBuffer->range_length() - copy);
848
849 size_done += copy;
850 size_remaining -= copy;
851 }
852
Andreas Huber838daaf2011-04-04 11:38:25 -0700853 {
854 Mutex::Autolock autoLock(mLock);
855 mNumFramesPlayed += size_done / mFrameSize;
856 }
857
858 if (postEOS) {
859 mObserver->postAudioEOS();
860 }
861
862 if (postSeekComplete) {
863 mObserver->postAudioSeekComplete();
864 }
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800865
866 return size_done;
867}
868
869void VideoEditorAudioPlayer::setAudioMixSettings(
870 M4xVSS_AudioMixingSettings* pAudioMixSettings) {
871 mAudioMixSettings = pAudioMixSettings;
872}
873
874void VideoEditorAudioPlayer::setAudioMixPCMFileHandle(
875 M4OSA_Context pBGAudioPCMFileHandle){
876 mBGAudioPCMFileHandle = pBGAudioPCMFileHandle;
877}
878
879void VideoEditorAudioPlayer::setAudioMixStoryBoardSkimTimeStamp(
880 M4OSA_UInt32 pBGAudioStoryBoardSkimTimeStamp,
881 M4OSA_UInt32 pBGAudioCurrentMediaBeginCutTS,
882 M4OSA_UInt32 pBGAudioCurrentMediaVolumeVal) {
883
884 mBGAudioStoryBoardSkimTimeStamp = pBGAudioStoryBoardSkimTimeStamp;
885 mBGAudioStoryBoardCurrentMediaBeginCutTS = pBGAudioCurrentMediaBeginCutTS;
886 mBGAudioStoryBoardCurrentMediaVolumeVal = pBGAudioCurrentMediaVolumeVal;
887}
888
889void VideoEditorAudioPlayer::setPrimaryTrackVolume(
890 M4OSA_Int16 *data, M4OSA_UInt32 size, M4OSA_Float volLevel) {
891
892 while(size-- > 0) {
893 *data = (M4OSA_Int16)((*data)*volLevel);
894 data++;
895 }
896}
897
898}