blob: 91dc590eba48965e65223637e3dd65316fef615c [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
Mark Salyzyndb43b342014-04-04 14:47:28 -070017#include <inttypes.h>
18
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080019#define LOG_NDEBUG 1
20#define LOG_TAG "VideoEditorAudioPlayer"
21#include <utils/Log.h>
22
23#include <binder/IPCThreadState.h>
24#include <media/AudioTrack.h>
25#include <VideoEditorAudioPlayer.h>
James Dongc4689fa2012-02-08 13:51:46 -080026#include <media/stagefright/foundation/ADebug.h>
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080027#include <media/stagefright/MediaDefs.h>
28#include <media/stagefright/MediaErrors.h>
29#include <media/stagefright/MediaSource.h>
30#include <media/stagefright/MetaData.h>
31
Dima Zavin272eb552011-05-11 14:15:37 -070032#include <system/audio.h>
Dima Zavin68598372011-04-05 16:13:49 -070033
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080034#include "PreviewPlayer.h"
35namespace android {
36
37VideoEditorAudioPlayer::VideoEditorAudioPlayer(
38 const sp<MediaPlayerBase::AudioSink> &audioSink,
James Dong00f742c2012-01-13 17:34:42 -080039 PreviewPlayer *observer)
Glenn Kasten2799d742013-05-30 14:33:29 -070040 : mInputBuffer(NULL),
James Dong727f9e12012-01-20 13:09:13 -080041 mSampleRate(0),
42 mLatencyUs(0),
43 mFrameSize(0),
44 mNumFramesPlayed(0),
45 mPositionTimeMediaUs(-1),
46 mPositionTimeRealUs(-1),
47 mSeeking(false),
48 mReachedEOS(false),
49 mFinalStatus(OK),
50 mStarted(false),
51 mIsFirstBuffer(false),
52 mFirstBufferResult(OK),
53 mFirstBuffer(NULL),
54 mAudioSink(audioSink),
55 mObserver(observer) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080056
James Dong727f9e12012-01-20 13:09:13 -080057 ALOGV("Constructor");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080058 mBGAudioPCMFileHandle = NULL;
Dheeraj Sharma5bc7fb42011-02-13 20:31:27 -080059 mAudioProcess = NULL;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080060 mBGAudioPCMFileLength = 0;
61 mBGAudioPCMFileTrimmedLength = 0;
62 mBGAudioPCMFileDuration = 0;
63 mBGAudioPCMFileSeekPoint = 0;
64 mBGAudioPCMFileOriginalSeekPoint = 0;
65 mBGAudioStoryBoardSkimTimeStamp = 0;
66 mBGAudioStoryBoardCurrentMediaBeginCutTS = 0;
67 mBGAudioStoryBoardCurrentMediaVolumeVal = 0;
68 mSeekTimeUs = 0;
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -080069 mSource = NULL;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080070}
71
72VideoEditorAudioPlayer::~VideoEditorAudioPlayer() {
73
James Dong727f9e12012-01-20 13:09:13 -080074 ALOGV("Destructor");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080075 if (mStarted) {
76 reset();
77 }
Santosh Madhava5df81852011-02-11 00:43:26 -080078 if (mAudioProcess != NULL) {
79 delete mAudioProcess;
80 mAudioProcess = NULL;
81 }
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080082}
James Dong727f9e12012-01-20 13:09:13 -080083
84void VideoEditorAudioPlayer::pause(bool playPendingSamples) {
85 ALOGV("pause: playPendingSamples=%d", playPendingSamples);
86 CHECK(mStarted);
87
88 if (playPendingSamples) {
89 if (mAudioSink.get() != NULL) {
90 mAudioSink->stop();
91 } else {
92 mAudioTrack->stop();
93 }
94 } else {
95 if (mAudioSink.get() != NULL) {
96 mAudioSink->pause();
97 } else {
98 mAudioTrack->pause();
99 }
100 }
101}
102
103void VideoEditorAudioPlayer::clear() {
104 ALOGV("clear");
105 if (!mStarted) {
106 return;
107 }
108
109 if (mAudioSink.get() != NULL) {
110 mAudioSink->stop();
111 mAudioSink->close();
112 } else {
113 mAudioTrack->stop();
114
Glenn Kasten2799d742013-05-30 14:33:29 -0700115 mAudioTrack.clear();
James Dong727f9e12012-01-20 13:09:13 -0800116 }
117
118 // Make sure to release any buffer we hold onto so that the
119 // source is able to stop().
120
121 if (mFirstBuffer != NULL) {
122 mFirstBuffer->release();
123 mFirstBuffer = NULL;
124 }
125
126 if (mInputBuffer != NULL) {
127 ALOGV("AudioPlayerBase releasing input buffer.");
128
129 mInputBuffer->release();
130 mInputBuffer = NULL;
131 }
132
133 mSource->stop();
134
135 // The following hack is necessary to ensure that the OMX
136 // component is completely released by the time we may try
137 // to instantiate it again.
138 wp<MediaSource> tmp = mSource;
139 mSource.clear();
140 while (tmp.promote() != NULL) {
141 usleep(1000);
142 }
143 IPCThreadState::self()->flushCommands();
144
145 mNumFramesPlayed = 0;
146 mPositionTimeMediaUs = -1;
147 mPositionTimeRealUs = -1;
148 mSeeking = false;
149 mReachedEOS = false;
150 mFinalStatus = OK;
151 mStarted = false;
152}
153
Richard Fitzgerald94ea60f2013-05-14 15:52:03 +0100154status_t VideoEditorAudioPlayer::resume() {
James Dong727f9e12012-01-20 13:09:13 -0800155 ALOGV("resume");
156
James Dong3bd45592012-01-20 19:28:01 -0800157 AudioMixSettings audioMixSettings;
James Dong727f9e12012-01-20 13:09:13 -0800158
159 // Single audio player is used;
160 // Pass on the audio ducking parameters
161 // which might have changed with new audio source
162 audioMixSettings.lvInDucking_threshold =
163 mAudioMixSettings->uiInDucking_threshold;
164 audioMixSettings.lvInDucking_lowVolume =
165 ((M4OSA_Float)mAudioMixSettings->uiInDucking_lowVolume) / 100.0;
166 audioMixSettings.lvInDucking_enable =
167 mAudioMixSettings->bInDucking_enable;
168 audioMixSettings.lvPTVolLevel =
169 ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal) / 100.0;
170 audioMixSettings.lvBTVolLevel =
171 ((M4OSA_Float)mAudioMixSettings->uiAddVolume) / 100.0;
172 audioMixSettings.lvBTChannelCount = mAudioMixSettings->uiBTChannelCount;
173 audioMixSettings.lvPTChannelCount = mAudioMixSettings->uiNbChannels;
174
175 // Call to Audio mix param setting
James Dong3bd45592012-01-20 19:28:01 -0800176 mAudioProcess->setMixParams(audioMixSettings);
James Dong727f9e12012-01-20 13:09:13 -0800177
178 CHECK(mStarted);
179
180 if (mAudioSink.get() != NULL) {
181 mAudioSink->start();
182 } else {
183 mAudioTrack->start();
184 }
Richard Fitzgerald94ea60f2013-05-14 15:52:03 +0100185 return OK;
James Dong727f9e12012-01-20 13:09:13 -0800186}
187
188status_t VideoEditorAudioPlayer::seekTo(int64_t time_us) {
189 ALOGV("seekTo: %lld", time_us);
190 Mutex::Autolock autoLock(mLock);
191
192 mSeeking = true;
193 mPositionTimeRealUs = mPositionTimeMediaUs = -1;
194 mReachedEOS = false;
195 mSeekTimeUs = time_us;
196
197 if (mAudioSink != NULL) {
198 mAudioSink->flush();
199 } else {
200 mAudioTrack->flush();
201 }
202
203 return OK;
204}
205
206bool VideoEditorAudioPlayer::isSeeking() {
207 Mutex::Autolock lock(mLock);
208 ALOGV("isSeeking: mSeeking=%d", mSeeking);
209 return mSeeking;
210}
211
212bool VideoEditorAudioPlayer::reachedEOS(status_t *finalStatus) {
213 ALOGV("reachedEOS: status=%d", mFinalStatus);
214 *finalStatus = OK;
215
216 Mutex::Autolock autoLock(mLock);
217 *finalStatus = mFinalStatus;
218 return mReachedEOS;
219}
220
221int64_t VideoEditorAudioPlayer::getRealTimeUs() {
222 Mutex::Autolock autoLock(mLock);
223 return getRealTimeUs_l();
224}
225
226int64_t VideoEditorAudioPlayer::getRealTimeUs_l() {
227 return -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
228}
229
230int64_t VideoEditorAudioPlayer::getMediaTimeUs() {
231 ALOGV("getMediaTimeUs");
232 Mutex::Autolock autoLock(mLock);
233
234 if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) {
235 if (mSeeking) {
236 return mSeekTimeUs;
237 }
238
239 return 0;
240 }
241
242 int64_t realTimeOffset = getRealTimeUs_l() - mPositionTimeRealUs;
243 if (realTimeOffset < 0) {
244 realTimeOffset = 0;
245 }
246
247 return mPositionTimeMediaUs + realTimeOffset;
248}
249
250bool VideoEditorAudioPlayer::getMediaTimeMapping(
251 int64_t *realtime_us, int64_t *mediatime_us) {
252 ALOGV("getMediaTimeMapping");
253 Mutex::Autolock autoLock(mLock);
254
255 *realtime_us = mPositionTimeRealUs;
256 *mediatime_us = mPositionTimeMediaUs;
257
258 return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1;
259}
260
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800261void VideoEditorAudioPlayer::setSource(const sp<MediaSource> &source) {
262 Mutex::Autolock autoLock(mLock);
Rajneesh Chowduryb6e2b5c2011-02-25 22:59:46 -0800263
264 // Before setting source, stop any existing source.
265 // Make sure to release any buffer we hold onto so that the
266 // source is able to stop().
267
268 if (mFirstBuffer != NULL) {
269 mFirstBuffer->release();
270 mFirstBuffer = NULL;
271 }
272
273 if (mInputBuffer != NULL) {
Steve Block2703f232011-10-20 11:56:09 +0100274 ALOGV("VideoEditorAudioPlayer releasing input buffer.");
Rajneesh Chowduryb6e2b5c2011-02-25 22:59:46 -0800275
276 mInputBuffer->release();
277 mInputBuffer = NULL;
278 }
279
280 if (mSource != NULL) {
281 mSource->stop();
282 mSource.clear();
283 }
284
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800285 mSource = source;
286 mReachedEOS = false;
287}
288
289sp<MediaSource> VideoEditorAudioPlayer::getSource() {
290 Mutex::Autolock autoLock(mLock);
291 return mSource;
292}
293
James Dong00f742c2012-01-13 17:34:42 -0800294void VideoEditorAudioPlayer::setObserver(PreviewPlayer *observer) {
Steve Block2703f232011-10-20 11:56:09 +0100295 ALOGV("setObserver");
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800296 //CHECK(!mStarted);
297 mObserver = observer;
298}
299
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800300bool VideoEditorAudioPlayer::isStarted() {
301 return mStarted;
302}
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800303
James Dong727f9e12012-01-20 13:09:13 -0800304// static
305void VideoEditorAudioPlayer::AudioCallback(int event, void *user, void *info) {
306 static_cast<VideoEditorAudioPlayer *>(user)->AudioCallback(event, info);
307}
308
309
310void VideoEditorAudioPlayer::AudioCallback(int event, void *info) {
311 if (event != AudioTrack::EVENT_MORE_DATA) {
312 return;
313 }
314
315 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
316 size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size);
317
318 buffer->size = numBytesWritten;
319}
320
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800321status_t VideoEditorAudioPlayer::start(bool sourceAlreadyStarted) {
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800322 Mutex::Autolock autoLock(mLock);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800323 CHECK(!mStarted);
324 CHECK(mSource != NULL);
Steve Block2703f232011-10-20 11:56:09 +0100325 ALOGV("Start");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800326 status_t err;
327 M4OSA_ERR result = M4NO_ERROR;
328 M4OSA_UInt32 startTime = 0;
329 M4OSA_UInt32 seekTimeStamp = 0;
330 M4OSA_Bool bStoryBoardTSBeyondBTEndCutTime = M4OSA_FALSE;
331
332 if (!sourceAlreadyStarted) {
333 err = mSource->start();
334 if (err != OK) {
335 return err;
336 }
337 }
338
339 // Create the BG Audio handler
340 mAudioProcess = new VideoEditorBGAudioProcessing();
James Dong3bd45592012-01-20 19:28:01 -0800341 AudioMixSettings audioMixSettings;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800342
343 // Pass on the audio ducking parameters
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800344 audioMixSettings.lvInDucking_threshold =
345 mAudioMixSettings->uiInDucking_threshold;
346 audioMixSettings.lvInDucking_lowVolume =
347 ((M4OSA_Float)mAudioMixSettings->uiInDucking_lowVolume) / 100.0;
348 audioMixSettings.lvInDucking_enable =
349 mAudioMixSettings->bInDucking_enable;
350 audioMixSettings.lvPTVolLevel =
351 ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal) / 100.0;
352 audioMixSettings.lvBTVolLevel =
353 ((M4OSA_Float)mAudioMixSettings->uiAddVolume) / 100.0;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800354 audioMixSettings.lvBTChannelCount = mAudioMixSettings->uiBTChannelCount;
355 audioMixSettings.lvPTChannelCount = mAudioMixSettings->uiNbChannels;
356
357 // Call to Audio mix param setting
James Dong3bd45592012-01-20 19:28:01 -0800358 mAudioProcess->setMixParams(audioMixSettings);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800359
360 // Get the BG Audio PCM file details
361 if ( mBGAudioPCMFileHandle ) {
362
363 // TODO : 32bits required for OSAL, to be updated once OSAL is updated
364 M4OSA_UInt32 tmp32 = 0;
365 result = M4OSA_fileReadGetOption(mBGAudioPCMFileHandle,
366 M4OSA_kFileReadGetFileSize,
367 (M4OSA_Void**)&tmp32);
368 mBGAudioPCMFileLength = tmp32;
369 mBGAudioPCMFileTrimmedLength = mBGAudioPCMFileLength;
370
371
Steve Block2703f232011-10-20 11:56:09 +0100372 ALOGV("VideoEditorAudioPlayer::start M4OSA_kFileReadGetFileSize = %lld",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800373 mBGAudioPCMFileLength);
374
375 // Get the duration in time of the audio BT
376 if ( result == M4NO_ERROR ) {
Mark Salyzyndb43b342014-04-04 14:47:28 -0700377 ALOGV("VEAP: channels = %" PRIu32 " freq = %" PRIu32,
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800378 mAudioMixSettings->uiNbChannels, mAudioMixSettings->uiSamplingFrequency);
379
380 // No trim
381 mBGAudioPCMFileDuration = ((
382 (int64_t)(mBGAudioPCMFileLength/sizeof(M4OSA_UInt16)/
383 mAudioMixSettings->uiNbChannels))*1000 ) /
384 mAudioMixSettings->uiSamplingFrequency;
385
Steve Block2703f232011-10-20 11:56:09 +0100386 ALOGV("VideoEditorAudioPlayer:: beginCutMs %d , endCutMs %d",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800387 (unsigned int) mAudioMixSettings->beginCutMs,
388 (unsigned int) mAudioMixSettings->endCutMs);
389
390 // Remove the trim part
391 if ((mAudioMixSettings->beginCutMs == 0) &&
392 (mAudioMixSettings->endCutMs != 0)) {
393 // End time itself the file duration
394 mBGAudioPCMFileDuration = mAudioMixSettings->endCutMs;
395 // Limit the file length also
396 mBGAudioPCMFileTrimmedLength = ((
397 (int64_t)(mBGAudioPCMFileDuration *
398 mAudioMixSettings->uiSamplingFrequency) *
399 mAudioMixSettings->uiNbChannels) *
400 sizeof(M4OSA_UInt16)) / 1000;
401 }
402 else if ((mAudioMixSettings->beginCutMs != 0) &&
403 (mAudioMixSettings->endCutMs == mBGAudioPCMFileDuration)) {
404 // End time itself the file duration
405 mBGAudioPCMFileDuration = mBGAudioPCMFileDuration -
406 mAudioMixSettings->beginCutMs;
407 // Limit the file length also
408 mBGAudioPCMFileTrimmedLength = ((
409 (int64_t)(mBGAudioPCMFileDuration *
410 mAudioMixSettings->uiSamplingFrequency) *
411 mAudioMixSettings->uiNbChannels) *
412 sizeof(M4OSA_UInt16)) / 1000;
413 }
414 else if ((mAudioMixSettings->beginCutMs != 0) &&
415 (mAudioMixSettings->endCutMs != 0)) {
416 // End time itself the file duration
417 mBGAudioPCMFileDuration = mAudioMixSettings->endCutMs -
418 mAudioMixSettings->beginCutMs;
419 // Limit the file length also
420 mBGAudioPCMFileTrimmedLength = ((
421 (int64_t)(mBGAudioPCMFileDuration *
422 mAudioMixSettings->uiSamplingFrequency) *
423 mAudioMixSettings->uiNbChannels) *
424 sizeof(M4OSA_UInt16)) / 1000; /*make to sec from ms*/
425 }
426
Steve Block2703f232011-10-20 11:56:09 +0100427 ALOGV("VideoEditorAudioPlayer: file duration recorded : %lld",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800428 mBGAudioPCMFileDuration);
429 }
430
431 // Last played location to be seeked at for next media item
432 if ( result == M4NO_ERROR ) {
Steve Block2703f232011-10-20 11:56:09 +0100433 ALOGV("VideoEditorAudioPlayer::mBGAudioStoryBoardSkimTimeStamp %lld",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800434 mBGAudioStoryBoardSkimTimeStamp);
Steve Block2703f232011-10-20 11:56:09 +0100435 ALOGV("VideoEditorAudioPlayer::uiAddCts %d",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800436 mAudioMixSettings->uiAddCts);
437 if (mBGAudioStoryBoardSkimTimeStamp >= mAudioMixSettings->uiAddCts) {
438 startTime = (mBGAudioStoryBoardSkimTimeStamp -
439 mAudioMixSettings->uiAddCts);
440 }
441 else {
442 // do nothing
443 }
444
Mark Salyzyndb43b342014-04-04 14:47:28 -0700445 ALOGV("VideoEditorAudioPlayer::startTime %" PRIu32, startTime);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800446 seekTimeStamp = 0;
447 if (startTime) {
448 if (startTime >= mBGAudioPCMFileDuration) {
449 // The BG track should be looped and started again
450 if (mAudioMixSettings->bLoop) {
451 // Add begin cut time to the mod value
452 seekTimeStamp = ((startTime%mBGAudioPCMFileDuration) +
453 mAudioMixSettings->beginCutMs);
454 }else {
455 // Looping disabled, donot do BT Mix , set to file end
456 seekTimeStamp = (mBGAudioPCMFileDuration +
457 mAudioMixSettings->beginCutMs);
458 }
459 }else {
460 // BT still present , just seek to story board time
461 seekTimeStamp = startTime + mAudioMixSettings->beginCutMs;
462 }
463 }
464 else {
465 seekTimeStamp = mAudioMixSettings->beginCutMs;
466 }
467
468 // Convert the seekTimeStamp to file location
469 mBGAudioPCMFileOriginalSeekPoint = (
470 (int64_t)(mAudioMixSettings->beginCutMs)
471 * mAudioMixSettings->uiSamplingFrequency
472 * mAudioMixSettings->uiNbChannels
473 * sizeof(M4OSA_UInt16))/ 1000 ; /*make to sec from ms*/
474
475 mBGAudioPCMFileSeekPoint = ((int64_t)(seekTimeStamp)
476 * mAudioMixSettings->uiSamplingFrequency
477 * mAudioMixSettings->uiNbChannels
478 * sizeof(M4OSA_UInt16))/ 1000 ;
479 }
480 }
481
482 // We allow an optional INFO_FORMAT_CHANGED at the very beginning
483 // of playback, if there is one, getFormat below will retrieve the
484 // updated format, if there isn't, we'll stash away the valid buffer
485 // of data to be used on the first audio callback.
486
487 CHECK(mFirstBuffer == NULL);
488
489 mFirstBufferResult = mSource->read(&mFirstBuffer);
490 if (mFirstBufferResult == INFO_FORMAT_CHANGED) {
Steve Block2703f232011-10-20 11:56:09 +0100491 ALOGV("INFO_FORMAT_CHANGED!!!");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800492
493 CHECK(mFirstBuffer == NULL);
494 mFirstBufferResult = OK;
495 mIsFirstBuffer = false;
496 } else {
497 mIsFirstBuffer = true;
498 }
499
500 sp<MetaData> format = mSource->getFormat();
501 const char *mime;
502 bool success = format->findCString(kKeyMIMEType, &mime);
503 CHECK(success);
504 CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
505
506 success = format->findInt32(kKeySampleRate, &mSampleRate);
507 CHECK(success);
508
509 int32_t numChannels;
510 success = format->findInt32(kKeyChannelCount, &numChannels);
511 CHECK(success);
512
513 if (mAudioSink.get() != NULL) {
514 status_t err = mAudioSink->open(
Jean-Michel Trivi8162c1a2012-03-02 14:34:10 -0800515 mSampleRate, numChannels, CHANNEL_MASK_USE_CHANNEL_ORDER, AUDIO_FORMAT_PCM_16_BIT,
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800516 DEFAULT_AUDIOSINK_BUFFERCOUNT,
517 &VideoEditorAudioPlayer::AudioSinkCallback, this);
518 if (err != OK) {
519 if (mFirstBuffer != NULL) {
520 mFirstBuffer->release();
521 mFirstBuffer = NULL;
522 }
523
524 if (!sourceAlreadyStarted) {
525 mSource->stop();
526 }
527
528 return err;
529 }
530
531 mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
532 mFrameSize = mAudioSink->frameSize();
533
534 mAudioSink->start();
535 } else {
536 mAudioTrack = new AudioTrack(
Dima Zavin68598372011-04-05 16:13:49 -0700537 AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT,
Glenn Kasten28b76b32012-07-03 17:24:41 -0700538 audio_channel_out_mask_from_count(numChannels),
Eric Laurent0ca3cf92012-04-18 09:24:29 -0700539 0, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this, 0);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800540
541 if ((err = mAudioTrack->initCheck()) != OK) {
Glenn Kasten2799d742013-05-30 14:33:29 -0700542 mAudioTrack.clear();
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800543
544 if (mFirstBuffer != NULL) {
545 mFirstBuffer->release();
546 mFirstBuffer = NULL;
547 }
548
549 if (!sourceAlreadyStarted) {
550 mSource->stop();
551 }
552
553 return err;
554 }
555
556 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
557 mFrameSize = mAudioTrack->frameSize();
558
559 mAudioTrack->start();
560 }
561
562 mStarted = true;
563
564 return OK;
565}
566
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800567
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800568void VideoEditorAudioPlayer::reset() {
569
Steve Block2703f232011-10-20 11:56:09 +0100570 ALOGV("reset");
James Dong727f9e12012-01-20 13:09:13 -0800571 clear();
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800572
573 // Capture the current seek point
574 mBGAudioPCMFileSeekPoint = 0;
575 mBGAudioStoryBoardSkimTimeStamp =0;
576 mBGAudioStoryBoardCurrentMediaBeginCutTS=0;
577}
578
579size_t VideoEditorAudioPlayer::AudioSinkCallback(
580 MediaPlayerBase::AudioSink *audioSink,
Richard Fitzgeraldad3af332013-03-25 16:54:37 +0000581 void *buffer, size_t size, void *cookie,
582 MediaPlayerBase::AudioSink::cb_event_t event) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800583 VideoEditorAudioPlayer *me = (VideoEditorAudioPlayer *)cookie;
584
Richard Fitzgeraldad3af332013-03-25 16:54:37 +0000585 if (event == MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER ) {
586 return me->fillBuffer(buffer, size);
587 } else {
588 return 0;
589 }
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800590}
591
592
593size_t VideoEditorAudioPlayer::fillBuffer(void *data, size_t size) {
594
595 if (mReachedEOS) {
596 return 0;
597 }
598
599 size_t size_done = 0;
600 size_t size_remaining = size;
601
602 M4OSA_ERR err = M4NO_ERROR;
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800603 M4AM_Buffer16 bgFrame = {NULL, 0};
604 M4AM_Buffer16 mixFrame = {NULL, 0};
605 M4AM_Buffer16 ptFrame = {NULL, 0};
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800606 int64_t currentSteamTS = 0;
607 int64_t startTimeForBT = 0;
608 M4OSA_Float fPTVolLevel =
609 ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal)/100;
Basavapatna Dattaguru100d0182011-03-04 09:48:24 -0800610 M4OSA_Int16 *pPTMdata=NULL;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800611 M4OSA_UInt32 uiPCMsize = 0;
612
Andreas Huber838daaf2011-04-04 11:38:25 -0700613 bool postSeekComplete = false;
614 bool postEOS = false;
615
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800616 while ((size_remaining > 0)&&(err==M4NO_ERROR)) {
617 MediaSource::ReadOptions options;
618
619 {
620 Mutex::Autolock autoLock(mLock);
621 if (mSeeking) {
622 if (mIsFirstBuffer) {
623 if (mFirstBuffer != NULL) {
624 mFirstBuffer->release();
625 mFirstBuffer = NULL;
626 }
627 mIsFirstBuffer = false;
628 }
629
630 options.setSeekTo(mSeekTimeUs);
631
632 if (mInputBuffer != NULL) {
633 mInputBuffer->release();
634 mInputBuffer = NULL;
635 }
636
637 mSeeking = false;
Andreas Huber838daaf2011-04-04 11:38:25 -0700638
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800639 if (mObserver) {
Andreas Huber838daaf2011-04-04 11:38:25 -0700640 postSeekComplete = true;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800641 }
642 }
643 }
644
645 if (mInputBuffer == NULL) {
646 status_t status = OK;
647
648 if (mIsFirstBuffer) {
649 mInputBuffer = mFirstBuffer;
650 mFirstBuffer = NULL;
651 status = mFirstBufferResult;
652
653 mIsFirstBuffer = false;
654 } else {
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800655
656 {
657 Mutex::Autolock autoLock(mLock);
658 status = mSource->read(&mInputBuffer, &options);
659 }
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800660 // Data is Primary Track, mix with background track
661 // after reading same size from Background track PCM file
662 if (status == OK)
663 {
664 // Mix only when skim point is after startTime of BT
665 if (((mBGAudioStoryBoardSkimTimeStamp* 1000) +
666 (mPositionTimeMediaUs - mSeekTimeUs)) >=
667 (int64_t)(mAudioMixSettings->uiAddCts * 1000)) {
668
Steve Block2703f232011-10-20 11:56:09 +0100669 ALOGV("VideoEditorAudioPlayer::INSIDE MIXING");
670 ALOGV("Checking %lld <= %lld",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800671 mBGAudioPCMFileSeekPoint-mBGAudioPCMFileOriginalSeekPoint,
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -0800672 mBGAudioPCMFileTrimmedLength);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800673
674
675 M4OSA_Void* ptr;
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000676 ptr = reinterpret_cast<M4OSA_Void*>(
677 reinterpret_cast<uintptr_t>(mInputBuffer->data()) +
678 mInputBuffer->range_offset());
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800679
680 M4OSA_UInt32 len = mInputBuffer->range_length();
681 M4OSA_Context fp = M4OSA_NULL;
682
683 uiPCMsize = (mInputBuffer->range_length())/2;
Kenny Rooteb5b2652011-02-08 11:13:19 -0800684 pPTMdata = (M4OSA_Int16*) ((uint8_t*) mInputBuffer->data()
685 + mInputBuffer->range_offset());
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800686
Steve Block2703f232011-10-20 11:56:09 +0100687 ALOGV("mix with background malloc to do len %d", len);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800688
Shyam Pallapothu694816d2011-04-21 09:48:41 -0700689 bgFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_32bitAlignedMalloc( len, 1,
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800690 (M4OSA_Char*)"bgFrame");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800691 bgFrame.m_bufferSize = len;
692
Shyam Pallapothu694816d2011-04-21 09:48:41 -0700693 mixFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_32bitAlignedMalloc(len, 1,
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800694 (M4OSA_Char*)"mixFrame");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800695 mixFrame.m_bufferSize = len;
696
Steve Block2703f232011-10-20 11:56:09 +0100697 ALOGV("mix with bgm with size %lld", mBGAudioPCMFileLength);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800698
699 CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime,
700 &mPositionTimeMediaUs));
701
702 if (mBGAudioPCMFileSeekPoint -
703 mBGAudioPCMFileOriginalSeekPoint <=
704 (mBGAudioPCMFileTrimmedLength - len)) {
705
Kévin PETIT2b4e26a2014-02-28 10:48:38 +0000706 ALOGV("Checking mBGAudioPCMFileHandle %p",
707 mBGAudioPCMFileHandle);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800708
709 if (mBGAudioPCMFileHandle != M4OSA_NULL) {
Steve Block2703f232011-10-20 11:56:09 +0100710 ALOGV("fillBuffer seeking file to %lld",
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800711 mBGAudioPCMFileSeekPoint);
712
713 // TODO : 32bits required for OSAL
714 M4OSA_UInt32 tmp32 =
715 (M4OSA_UInt32)mBGAudioPCMFileSeekPoint;
716 err = M4OSA_fileReadSeek(mBGAudioPCMFileHandle,
717 M4OSA_kFileSeekBeginning,
718 (M4OSA_FilePosition*)&tmp32);
719
720 mBGAudioPCMFileSeekPoint = tmp32;
721
722 if (err != M4NO_ERROR){
Steve Blockf8bd29c2012-01-08 10:14:44 +0000723 ALOGE("M4OSA_fileReadSeek err %d",(int)err);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800724 }
725
726 err = M4OSA_fileReadData(mBGAudioPCMFileHandle,
727 (M4OSA_Int8*)bgFrame.m_dataAddress,
728 (M4OSA_UInt32*)&len);
729 if (err == M4WAR_NO_DATA_YET ) {
730
Steve Block2703f232011-10-20 11:56:09 +0100731 ALOGV("fillBuffer End of file reached");
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800732 err = M4NO_ERROR;
733
734 // We reached the end of file
735 // move to begin cut time equal value
736 if (mAudioMixSettings->bLoop) {
737 mBGAudioPCMFileSeekPoint =
738 (((int64_t)(mAudioMixSettings->beginCutMs) *
739 mAudioMixSettings->uiSamplingFrequency) *
740 mAudioMixSettings->uiNbChannels *
741 sizeof(M4OSA_UInt16)) / 1000;
Steve Block2703f232011-10-20 11:56:09 +0100742 ALOGV("fillBuffer Looping \
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800743 to mBGAudioPCMFileSeekPoint %lld",
744 mBGAudioPCMFileSeekPoint);
745 }
746 else {
747 // No mixing;
748 // take care of volume of primary track
749 if (fPTVolLevel < 1.0) {
750 setPrimaryTrackVolume(pPTMdata,
751 uiPCMsize, fPTVolLevel);
752 }
753 }
754 } else if (err != M4NO_ERROR ) {
Steve Block2703f232011-10-20 11:56:09 +0100755 ALOGV("fileReadData for audio err %d", err);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800756 } else {
757 mBGAudioPCMFileSeekPoint += len;
Steve Block2703f232011-10-20 11:56:09 +0100758 ALOGV("fillBuffer mBGAudioPCMFileSeekPoint \
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800759 %lld", mBGAudioPCMFileSeekPoint);
760
761 // Assign the ptr data to primary track
762 ptFrame.m_dataAddress = (M4OSA_UInt16*)ptr;
763 ptFrame.m_bufferSize = len;
764
765 // Call to mix and duck
James Dong3bd45592012-01-20 19:28:01 -0800766 mAudioProcess->mixAndDuck(
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800767 &ptFrame, &bgFrame, &mixFrame);
768
769 // Overwrite the decoded buffer
Shyam Pallapothu32ed3f42011-04-20 21:00:48 -0700770 memcpy((void *)ptr,
771 (void *)mixFrame.m_dataAddress, len);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800772 }
773 }
774 } else if (mAudioMixSettings->bLoop){
775 // Move to begin cut time equal value
776 mBGAudioPCMFileSeekPoint =
777 mBGAudioPCMFileOriginalSeekPoint;
778 } else {
779 // No mixing;
780 // take care of volume level of primary track
781 if(fPTVolLevel < 1.0) {
782 setPrimaryTrackVolume(
783 pPTMdata, uiPCMsize, fPTVolLevel);
784 }
785 }
786 if (bgFrame.m_dataAddress) {
Shyam Pallapothu694816d2011-04-21 09:48:41 -0700787 free(bgFrame.m_dataAddress);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800788 }
789 if (mixFrame.m_dataAddress) {
Shyam Pallapothu694816d2011-04-21 09:48:41 -0700790 free(mixFrame.m_dataAddress);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800791 }
792 } else {
793 // No mixing;
794 // take care of volume level of primary track
795 if(fPTVolLevel < 1.0) {
796 setPrimaryTrackVolume(pPTMdata, uiPCMsize,
797 fPTVolLevel);
798 }
799 }
800 }
801 }
802
803 CHECK((status == OK && mInputBuffer != NULL)
804 || (status != OK && mInputBuffer == NULL));
805
806 Mutex::Autolock autoLock(mLock);
807
808 if (status != OK) {
Steve Block2703f232011-10-20 11:56:09 +0100809 ALOGV("fillBuffer: mSource->read returned err %d", status);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800810 if (mObserver && !mReachedEOS) {
Andreas Huber838daaf2011-04-04 11:38:25 -0700811 postEOS = true;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800812 }
813
814 mReachedEOS = true;
815 mFinalStatus = status;
816 break;
817 }
818
819 CHECK(mInputBuffer->meta_data()->findInt64(
820 kKeyTime, &mPositionTimeMediaUs));
821
822 mPositionTimeRealUs =
823 ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
824 / mSampleRate;
825
Steve Block2703f232011-10-20 11:56:09 +0100826 ALOGV("buffer->size() = %d, "
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800827 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
828 mInputBuffer->range_length(),
829 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
830 }
831
832 if (mInputBuffer->range_length() == 0) {
833 mInputBuffer->release();
834 mInputBuffer = NULL;
835
836 continue;
837 }
838
839 size_t copy = size_remaining;
840 if (copy > mInputBuffer->range_length()) {
841 copy = mInputBuffer->range_length();
842 }
843
844 memcpy((char *)data + size_done,
845 (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),
846 copy);
847
848 mInputBuffer->set_range(mInputBuffer->range_offset() + copy,
849 mInputBuffer->range_length() - copy);
850
851 size_done += copy;
852 size_remaining -= copy;
853 }
854
Andreas Huber838daaf2011-04-04 11:38:25 -0700855 {
856 Mutex::Autolock autoLock(mLock);
857 mNumFramesPlayed += size_done / mFrameSize;
858 }
859
860 if (postEOS) {
861 mObserver->postAudioEOS();
862 }
863
864 if (postSeekComplete) {
865 mObserver->postAudioSeekComplete();
866 }
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800867
868 return size_done;
869}
870
871void VideoEditorAudioPlayer::setAudioMixSettings(
872 M4xVSS_AudioMixingSettings* pAudioMixSettings) {
873 mAudioMixSettings = pAudioMixSettings;
874}
875
876void VideoEditorAudioPlayer::setAudioMixPCMFileHandle(
877 M4OSA_Context pBGAudioPCMFileHandle){
878 mBGAudioPCMFileHandle = pBGAudioPCMFileHandle;
879}
880
881void VideoEditorAudioPlayer::setAudioMixStoryBoardSkimTimeStamp(
882 M4OSA_UInt32 pBGAudioStoryBoardSkimTimeStamp,
883 M4OSA_UInt32 pBGAudioCurrentMediaBeginCutTS,
884 M4OSA_UInt32 pBGAudioCurrentMediaVolumeVal) {
885
886 mBGAudioStoryBoardSkimTimeStamp = pBGAudioStoryBoardSkimTimeStamp;
887 mBGAudioStoryBoardCurrentMediaBeginCutTS = pBGAudioCurrentMediaBeginCutTS;
888 mBGAudioStoryBoardCurrentMediaVolumeVal = pBGAudioCurrentMediaVolumeVal;
889}
890
891void VideoEditorAudioPlayer::setPrimaryTrackVolume(
892 M4OSA_Int16 *data, M4OSA_UInt32 size, M4OSA_Float volLevel) {
893
894 while(size-- > 0) {
895 *data = (M4OSA_Int16)((*data)*volLevel);
896 data++;
897 }
898}
899
900}