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