1 /*
2 * Copyright (C) 2009 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 #include <inttypes.h>
18
19 //#define LOG_NDEBUG 0
20 #define LOG_TAG "AudioPlayer"
21 #include <utils/Log.h>
22 #include <cutils/compiler.h>
23
24 #include <binder/IPCThreadState.h>
25 #include <media/AudioTrack.h>
26 #include <media/openmax/OMX_Audio.h>
27 #include <media/stagefright/foundation/ADebug.h>
28 #include <media/stagefright/foundation/ALookup.h>
29 #include <media/stagefright/foundation/ALooper.h>
30 #include <media/stagefright/AudioPlayer.h>
31 #include <media/stagefright/MediaDefs.h>
32 #include <media/stagefright/MediaErrors.h>
33 #include <media/stagefright/MediaSource.h>
34 #include <media/stagefright/MetaData.h>
35 #include <media/stagefright/Utils.h>
36
37 namespace android {
38
AudioPlayer(const sp<MediaPlayerBase::AudioSink> & audioSink,uint32_t flags)39 AudioPlayer::AudioPlayer(
40 const sp<MediaPlayerBase::AudioSink> &audioSink,
41 uint32_t flags)
42 : mInputBuffer(NULL),
43 mSampleRate(0),
44 mLatencyUs(0),
45 mFrameSize(0),
46 mNumFramesPlayed(0),
47 mNumFramesPlayedSysTimeUs(ALooper::GetNowUs()),
48 mPositionTimeMediaUs(-1),
49 mPositionTimeRealUs(-1),
50 mSeeking(false),
51 mReachedEOS(false),
52 mFinalStatus(OK),
53 mSeekTimeUs(0),
54 mStarted(false),
55 mIsFirstBuffer(false),
56 mFirstBufferResult(OK),
57 mFirstBuffer(NULL),
58 mAudioSink(audioSink),
59 mPlaying(false),
60 mStartPosUs(0),
61 mCreateFlags(flags) {
62 }
63
~AudioPlayer()64 AudioPlayer::~AudioPlayer() {
65 if (mStarted) {
66 reset();
67 }
68 }
69
setSource(const sp<IMediaSource> & source)70 void AudioPlayer::setSource(const sp<IMediaSource> &source) {
71 CHECK(mSource == NULL);
72 mSource = source;
73 }
74
75 ALookup<audio_format_t, int32_t> sAudioFormatToPcmEncoding {
76 {
77 { AUDIO_FORMAT_PCM_16_BIT, kAudioEncodingPcm16bit },
78 { AUDIO_FORMAT_PCM_8_BIT, kAudioEncodingPcm8bit },
79 { AUDIO_FORMAT_PCM_FLOAT, kAudioEncodingPcmFloat },
80 }
81 };
82
start(bool sourceAlreadyStarted)83 status_t AudioPlayer::start(bool sourceAlreadyStarted) {
84 CHECK(!mStarted);
85 CHECK(mSource != NULL);
86
87 status_t err;
88 if (!sourceAlreadyStarted) {
89 err = mSource->start();
90
91 if (err != OK) {
92 return err;
93 }
94 }
95
96 // We allow an optional INFO_FORMAT_CHANGED at the very beginning
97 // of playback, if there is one, getFormat below will retrieve the
98 // updated format, if there isn't, we'll stash away the valid buffer
99 // of data to be used on the first audio callback.
100
101 CHECK(mFirstBuffer == NULL);
102
103 MediaSource::ReadOptions options;
104 if (mSeeking) {
105 options.setSeekTo(mSeekTimeUs);
106 mSeeking = false;
107 }
108
109 mFirstBufferResult = mSource->read(&mFirstBuffer, &options);
110 if (mFirstBufferResult == INFO_FORMAT_CHANGED) {
111 ALOGV("INFO_FORMAT_CHANGED!!!");
112
113 CHECK(mFirstBuffer == NULL);
114 mFirstBufferResult = OK;
115 mIsFirstBuffer = false;
116 } else {
117 mIsFirstBuffer = true;
118 }
119
120 sp<MetaData> format = mSource->getFormat();
121 const char *mime;
122 bool success = format->findCString(kKeyMIMEType, &mime);
123 CHECK(success);
124 CHECK(useOffload() || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
125
126 success = format->findInt32(kKeySampleRate, &mSampleRate);
127 CHECK(success);
128
129 int32_t numChannels, channelMask;
130 success = format->findInt32(kKeyChannelCount, &numChannels);
131 CHECK(success);
132
133 if(!format->findInt32(kKeyChannelMask, &channelMask)) {
134 // log only when there's a risk of ambiguity of channel mask selection
135 ALOGI_IF(numChannels > 2,
136 "source format didn't specify channel mask, using (%d) channel order", numChannels);
137 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
138 }
139
140 audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
141 int32_t pcmEncoding;
142 if (format->findInt32(kKeyPcmEncoding, &pcmEncoding)) {
143 sAudioFormatToPcmEncoding.map(pcmEncoding, &audioFormat);
144 }
145
146 if (useOffload()) {
147 if (mapMimeToAudioFormat(audioFormat, mime) != OK) {
148 ALOGE("Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format", mime);
149 audioFormat = AUDIO_FORMAT_INVALID;
150 } else {
151 ALOGV("Mime type \"%s\" mapped to audio_format 0x%x", mime, audioFormat);
152 }
153
154 int32_t aacaot = -1;
155 if ((audioFormat == AUDIO_FORMAT_AAC) && format->findInt32(kKeyAACAOT, &aacaot)) {
156 // Redefine AAC format corrosponding to aac profile
157 mapAACProfileToAudioFormat(audioFormat,(OMX_AUDIO_AACPROFILETYPE) aacaot);
158 }
159 }
160
161 int avgBitRate = -1;
162 format->findInt32(kKeyBitRate, &avgBitRate);
163
164 if (mAudioSink.get() != NULL) {
165
166 uint32_t flags = AUDIO_OUTPUT_FLAG_NONE;
167 audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
168
169 if (allowDeepBuffering()) {
170 flags |= AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
171 }
172 if (useOffload()) {
173 flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
174
175 int64_t durationUs;
176 if (format->findInt64(kKeyDuration, &durationUs)) {
177 offloadInfo.duration_us = durationUs;
178 } else {
179 offloadInfo.duration_us = -1;
180 }
181
182 offloadInfo.sample_rate = mSampleRate;
183 offloadInfo.channel_mask = channelMask;
184 offloadInfo.format = audioFormat;
185 offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
186 offloadInfo.bit_rate = avgBitRate;
187 offloadInfo.has_video = ((mCreateFlags & HAS_VIDEO) != 0);
188 offloadInfo.is_streaming = ((mCreateFlags & IS_STREAMING) != 0);
189 }
190
191 status_t err = mAudioSink->open(
192 mSampleRate, numChannels, channelMask, audioFormat,
193 DEFAULT_AUDIOSINK_BUFFERCOUNT,
194 &AudioPlayer::AudioSinkCallback,
195 this,
196 (audio_output_flags_t)flags,
197 useOffload() ? &offloadInfo : NULL);
198
199 if (err == OK) {
200 mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
201 mFrameSize = mAudioSink->frameSize();
202
203 if (useOffload()) {
204 // If the playback is offloaded to h/w we pass the
205 // HAL some metadata information
206 // We don't want to do this for PCM because it will be going
207 // through the AudioFlinger mixer before reaching the hardware
208 sendMetaDataToHal(mAudioSink, format);
209 }
210
211 err = mAudioSink->start();
212 // do not alter behavior for non offloaded tracks: ignore start status.
213 if (!useOffload()) {
214 err = OK;
215 }
216 }
217
218 if (err != OK) {
219 if (mFirstBuffer != NULL) {
220 mFirstBuffer->release();
221 mFirstBuffer = NULL;
222 }
223
224 if (!sourceAlreadyStarted) {
225 mSource->stop();
226 }
227
228 return err;
229 }
230
231 } else {
232 // playing to an AudioTrack, set up mask if necessary
233 audio_channel_mask_t audioMask = channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER ?
234 audio_channel_out_mask_from_count(numChannels) : channelMask;
235 if (0 == audioMask) {
236 return BAD_VALUE;
237 }
238
239 mAudioTrack = new AudioTrack(
240 AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, audioMask,
241 0 /*frameCount*/, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this,
242 0 /*notificationFrames*/);
243
244 if ((err = mAudioTrack->initCheck()) != OK) {
245 mAudioTrack.clear();
246
247 if (mFirstBuffer != NULL) {
248 mFirstBuffer->release();
249 mFirstBuffer = NULL;
250 }
251
252 if (!sourceAlreadyStarted) {
253 mSource->stop();
254 }
255
256 return err;
257 }
258
259 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
260 mFrameSize = mAudioTrack->frameSize();
261
262 mAudioTrack->start();
263 }
264
265 mStarted = true;
266 mPlaying = true;
267
268 return OK;
269 }
270
pause(bool playPendingSamples)271 void AudioPlayer::pause(bool playPendingSamples) {
272 CHECK(mStarted);
273
274 if (playPendingSamples) {
275 if (mAudioSink.get() != NULL) {
276 mAudioSink->stop();
277 } else {
278 mAudioTrack->stop();
279 }
280
281 mNumFramesPlayed = 0;
282 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
283 } else {
284 if (mAudioSink.get() != NULL) {
285 mAudioSink->pause();
286 } else {
287 mAudioTrack->pause();
288 }
289 }
290
291 mPlaying = false;
292 }
293
resume()294 status_t AudioPlayer::resume() {
295 CHECK(mStarted);
296 status_t err;
297
298 if (mAudioSink.get() != NULL) {
299 err = mAudioSink->start();
300 } else {
301 err = mAudioTrack->start();
302 }
303
304 if (err == OK) {
305 mPlaying = true;
306 }
307
308 return err;
309 }
310
reset()311 void AudioPlayer::reset() {
312 CHECK(mStarted);
313
314 ALOGV("reset: mPlaying=%d mReachedEOS=%d useOffload=%d",
315 mPlaying, mReachedEOS, useOffload() );
316
317 if (mAudioSink.get() != NULL) {
318 mAudioSink->stop();
319 // If we're closing and have reached EOS, we don't want to flush
320 // the track because if it is offloaded there could be a small
321 // amount of residual data in the hardware buffer which we must
322 // play to give gapless playback.
323 // But if we're resetting when paused or before we've reached EOS
324 // we can't be doing a gapless playback and there could be a large
325 // amount of data queued in the hardware if the track is offloaded,
326 // so we must flush to prevent a track switch being delayed playing
327 // the buffered data that we don't want now
328 if (!mPlaying || !mReachedEOS) {
329 mAudioSink->flush();
330 }
331
332 mAudioSink->close();
333 } else {
334 mAudioTrack->stop();
335
336 if (!mPlaying || !mReachedEOS) {
337 mAudioTrack->flush();
338 }
339
340 mAudioTrack.clear();
341 }
342
343 // Make sure to release any buffer we hold onto so that the
344 // source is able to stop().
345
346 if (mFirstBuffer != NULL) {
347 mFirstBuffer->release();
348 mFirstBuffer = NULL;
349 }
350
351 if (mInputBuffer != NULL) {
352 ALOGV("AudioPlayer releasing input buffer.");
353
354 mInputBuffer->release();
355 mInputBuffer = NULL;
356 }
357
358 mSource->stop();
359
360 // The following hack is necessary to ensure that the OMX
361 // component is completely released by the time we may try
362 // to instantiate it again.
363 // When offloading, the OMX component is not used so this hack
364 // is not needed
365 if (!useOffload()) {
366 wp<IMediaSource> tmp = mSource;
367 mSource.clear();
368 while (tmp.promote() != NULL) {
369 usleep(1000);
370 }
371 } else {
372 mSource.clear();
373 }
374 IPCThreadState::self()->flushCommands();
375
376 mNumFramesPlayed = 0;
377 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
378 mPositionTimeMediaUs = -1;
379 mPositionTimeRealUs = -1;
380 mSeeking = false;
381 mSeekTimeUs = 0;
382 mReachedEOS = false;
383 mFinalStatus = OK;
384 mStarted = false;
385 mPlaying = false;
386 mStartPosUs = 0;
387 }
388
389 // static
AudioCallback(int event,void * user,void * info)390 void AudioPlayer::AudioCallback(int event, void *user, void *info) {
391 static_cast<AudioPlayer *>(user)->AudioCallback(event, info);
392 }
393
reachedEOS(status_t * finalStatus)394 bool AudioPlayer::reachedEOS(status_t *finalStatus) {
395 *finalStatus = OK;
396
397 Mutex::Autolock autoLock(mLock);
398 *finalStatus = mFinalStatus;
399 return mReachedEOS;
400 }
401
setPlaybackRate(const AudioPlaybackRate & rate)402 status_t AudioPlayer::setPlaybackRate(const AudioPlaybackRate &rate) {
403 if (mAudioSink.get() != NULL) {
404 return mAudioSink->setPlaybackRate(rate);
405 } else if (mAudioTrack != 0){
406 return mAudioTrack->setPlaybackRate(rate);
407 } else {
408 return NO_INIT;
409 }
410 }
411
getPlaybackRate(AudioPlaybackRate * rate)412 status_t AudioPlayer::getPlaybackRate(AudioPlaybackRate *rate /* nonnull */) {
413 if (mAudioSink.get() != NULL) {
414 return mAudioSink->getPlaybackRate(rate);
415 } else if (mAudioTrack != 0) {
416 *rate = mAudioTrack->getPlaybackRate();
417 return OK;
418 } else {
419 return NO_INIT;
420 }
421 }
422
423 // static
AudioSinkCallback(MediaPlayerBase::AudioSink *,void * buffer,size_t size,void * cookie,MediaPlayerBase::AudioSink::cb_event_t event)424 size_t AudioPlayer::AudioSinkCallback(
425 MediaPlayerBase::AudioSink * /* audioSink */,
426 void *buffer, size_t size, void *cookie,
427 MediaPlayerBase::AudioSink::cb_event_t event) {
428 AudioPlayer *me = (AudioPlayer *)cookie;
429
430 switch(event) {
431 case MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER:
432 return me->fillBuffer(buffer, size);
433
434 case MediaPlayerBase::AudioSink::CB_EVENT_STREAM_END:
435 ALOGV("AudioSinkCallback: stream end");
436 me->mReachedEOS = true;
437 break;
438
439 case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN:
440 ALOGV("AudioSinkCallback: Tear down event");
441 break;
442 }
443
444 return 0;
445 }
446
AudioCallback(int event,void * info)447 void AudioPlayer::AudioCallback(int event, void *info) {
448 switch (event) {
449 case AudioTrack::EVENT_MORE_DATA:
450 {
451 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
452 size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size);
453 buffer->size = numBytesWritten;
454 }
455 break;
456
457 case AudioTrack::EVENT_STREAM_END:
458 mReachedEOS = true;
459 break;
460 }
461 }
462
fillBuffer(void * data,size_t size)463 size_t AudioPlayer::fillBuffer(void *data, size_t size) {
464 if (mNumFramesPlayed == 0) {
465 ALOGV("AudioCallback");
466 }
467
468 if (mReachedEOS) {
469 return 0;
470 }
471
472 size_t size_done = 0;
473 size_t size_remaining = size;
474 while (size_remaining > 0) {
475 MediaSource::ReadOptions options;
476 bool refreshSeekTime = false;
477
478 {
479 Mutex::Autolock autoLock(mLock);
480
481 if (mSeeking) {
482 if (mIsFirstBuffer) {
483 if (mFirstBuffer != NULL) {
484 mFirstBuffer->release();
485 mFirstBuffer = NULL;
486 }
487 mIsFirstBuffer = false;
488 }
489
490 options.setSeekTo(mSeekTimeUs);
491 refreshSeekTime = true;
492
493 if (mInputBuffer != NULL) {
494 mInputBuffer->release();
495 mInputBuffer = NULL;
496 }
497
498 mSeeking = false;
499 }
500 }
501
502 if (mInputBuffer == NULL) {
503 status_t err;
504
505 if (mIsFirstBuffer) {
506 mInputBuffer = mFirstBuffer;
507 mFirstBuffer = NULL;
508 err = mFirstBufferResult;
509
510 mIsFirstBuffer = false;
511 } else {
512 err = mSource->read(&mInputBuffer, &options);
513 }
514
515 CHECK((err == OK && mInputBuffer != NULL)
516 || (err != OK && mInputBuffer == NULL));
517
518 Mutex::Autolock autoLock(mLock);
519
520 if (err != OK) {
521 if (!mReachedEOS) {
522 if (useOffload()) {
523 // no more buffers to push - stop() and wait for STREAM_END
524 // don't set mReachedEOS until stream end received
525 if (mAudioSink != NULL) {
526 mAudioSink->stop();
527 } else {
528 mAudioTrack->stop();
529 }
530 } else {
531 mReachedEOS = true;
532 }
533 }
534
535 mFinalStatus = err;
536 break;
537 }
538
539 if (mAudioSink != NULL) {
540 mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
541 } else {
542 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
543 }
544
545 if(mInputBuffer->range_length() != 0) {
546 CHECK(mInputBuffer->meta_data()->findInt64(
547 kKeyTime, &mPositionTimeMediaUs));
548 }
549
550 // need to adjust the mStartPosUs for offload decoding since parser
551 // might not be able to get the exact seek time requested.
552 if (refreshSeekTime) {
553 if (useOffload()) {
554 mStartPosUs = mPositionTimeMediaUs;
555 ALOGV("adjust seek time to: %.2f", mStartPosUs/ 1E6);
556 }
557 // clear seek time with mLock locked and once we have valid mPositionTimeMediaUs
558 // and mPositionTimeRealUs
559 // before clearing mSeekTimeUs check if a new seek request has been received while
560 // we were reading from the source with mLock released.
561 if (!mSeeking) {
562 mSeekTimeUs = 0;
563 }
564 }
565
566 if (!useOffload()) {
567 mPositionTimeRealUs =
568 ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
569 / mSampleRate;
570 ALOGV("buffer->size() = %zu, "
571 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
572 mInputBuffer->range_length(),
573 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
574 }
575
576 }
577
578 if (mInputBuffer->range_length() == 0) {
579 mInputBuffer->release();
580 mInputBuffer = NULL;
581
582 continue;
583 }
584
585 size_t copy = size_remaining;
586 if (copy > mInputBuffer->range_length()) {
587 copy = mInputBuffer->range_length();
588 }
589
590 memcpy((char *)data + size_done,
591 (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),
592 copy);
593
594 mInputBuffer->set_range(mInputBuffer->range_offset() + copy,
595 mInputBuffer->range_length() - copy);
596
597 size_done += copy;
598 size_remaining -= copy;
599 }
600
601 if (useOffload()) {
602 // We must ask the hardware what it has played
603 mPositionTimeRealUs = getOutputPlayPositionUs_l();
604 ALOGV("mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
605 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
606 }
607
608 {
609 Mutex::Autolock autoLock(mLock);
610 mNumFramesPlayed += size_done / mFrameSize;
611 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
612 }
613
614 return size_done;
615 }
616
getOutputPlayPositionUs_l()617 int64_t AudioPlayer::getOutputPlayPositionUs_l()
618 {
619 uint32_t playedSamples = 0;
620 uint32_t sampleRate;
621 if (mAudioSink != NULL) {
622 mAudioSink->getPosition(&playedSamples);
623 sampleRate = mAudioSink->getSampleRate();
624 } else {
625 mAudioTrack->getPosition(&playedSamples);
626 sampleRate = mAudioTrack->getSampleRate();
627 }
628 if (sampleRate != 0) {
629 mSampleRate = sampleRate;
630 }
631
632 int64_t playedUs;
633 if (mSampleRate != 0) {
634 playedUs = (static_cast<int64_t>(playedSamples) * 1000000 ) / mSampleRate;
635 } else {
636 playedUs = 0;
637 }
638
639 // HAL position is relative to the first buffer we sent at mStartPosUs
640 const int64_t renderedDuration = mStartPosUs + playedUs;
641 ALOGV("getOutputPlayPositionUs_l %" PRId64, renderedDuration);
642 return renderedDuration;
643 }
644
seekTo(int64_t time_us)645 status_t AudioPlayer::seekTo(int64_t time_us) {
646 Mutex::Autolock autoLock(mLock);
647
648 ALOGV("seekTo( %" PRId64 " )", time_us);
649
650 mSeeking = true;
651 mPositionTimeRealUs = mPositionTimeMediaUs = -1;
652 mReachedEOS = false;
653 mSeekTimeUs = time_us;
654 mStartPosUs = time_us;
655
656 // Flush resets the number of played frames
657 mNumFramesPlayed = 0;
658 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
659
660 if (mAudioSink != NULL) {
661 if (mPlaying) {
662 mAudioSink->pause();
663 }
664 mAudioSink->flush();
665 if (mPlaying) {
666 mAudioSink->start();
667 }
668 } else {
669 if (mPlaying) {
670 mAudioTrack->pause();
671 }
672 mAudioTrack->flush();
673 if (mPlaying) {
674 mAudioTrack->start();
675 }
676 }
677
678 return OK;
679 }
680
681 }
682