• 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/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