1/*
2**
3** Copyright 2018, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18//#define LOG_NDEBUG 0
19#define LOG_TAG "MediaPlayer2AudioOutput"
20#include <mediaplayer2/MediaPlayer2AudioOutput.h>
21
22#include <cutils/properties.h> // for property_get
23#include <utils/Log.h>
24
25#include <media/AudioPolicyHelper.h>
26#include <media/AudioTrack.h>
27#include <media/stagefright/foundation/ADebug.h>
28
29namespace {
30
31const float kMaxRequiredSpeed = 8.0f; // for PCM tracks allow up to 8x speedup.
32
33} // anonymous namespace
34
35namespace android {
36
37// TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround
38/* static */ int MediaPlayer2AudioOutput::mMinBufferCount = 4;
39/* static */ bool MediaPlayer2AudioOutput::mIsOnEmulator = false;
40
41status_t MediaPlayer2AudioOutput::dump(int fd, const Vector<String16>& args) const {
42    const size_t SIZE = 256;
43    char buffer[SIZE];
44    String8 result;
45
46    result.append(" MediaPlayer2AudioOutput\n");
47    snprintf(buffer, 255, "  stream type(%d), left - right volume(%f, %f)\n",
48            mStreamType, mLeftVolume, mRightVolume);
49    result.append(buffer);
50    snprintf(buffer, 255, "  msec per frame(%f), latency (%d)\n",
51            mMsecsPerFrame, (mTrack != 0) ? mTrack->latency() : -1);
52    result.append(buffer);
53    snprintf(buffer, 255, "  aux effect id(%d), send level (%f)\n",
54            mAuxEffectId, mSendLevel);
55    result.append(buffer);
56
57    ::write(fd, result.string(), result.size());
58    if (mTrack != 0) {
59        mTrack->dump(fd, args);
60    }
61    return NO_ERROR;
62}
63
64MediaPlayer2AudioOutput::MediaPlayer2AudioOutput(audio_session_t sessionId, uid_t uid, int pid,
65        const audio_attributes_t* attr, const sp<AudioSystem::AudioDeviceCallback>& deviceCallback)
66    : mCallback(NULL),
67      mCallbackCookie(NULL),
68      mCallbackData(NULL),
69      mStreamType(AUDIO_STREAM_MUSIC),
70      mLeftVolume(1.0),
71      mRightVolume(1.0),
72      mPlaybackRate(AUDIO_PLAYBACK_RATE_DEFAULT),
73      mSampleRateHz(0),
74      mMsecsPerFrame(0),
75      mFrameSize(0),
76      mSessionId(sessionId),
77      mUid(uid),
78      mPid(pid),
79      mSendLevel(0.0),
80      mAuxEffectId(0),
81      mFlags(AUDIO_OUTPUT_FLAG_NONE),
82      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
83      mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE),
84      mDeviceCallbackEnabled(false),
85      mDeviceCallback(deviceCallback) {
86    ALOGV("MediaPlayer2AudioOutput(%d)", sessionId);
87    if (attr != NULL) {
88        mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
89        if (mAttributes != NULL) {
90            memcpy(mAttributes, attr, sizeof(audio_attributes_t));
91            mStreamType = audio_attributes_to_stream_type(attr);
92        }
93    } else {
94        mAttributes = NULL;
95    }
96
97    setMinBufferCount();
98}
99
100MediaPlayer2AudioOutput::~MediaPlayer2AudioOutput() {
101    close();
102    free(mAttributes);
103    delete mCallbackData;
104}
105
106//static
107void MediaPlayer2AudioOutput::setMinBufferCount() {
108    char value[PROPERTY_VALUE_MAX];
109    if (property_get("ro.kernel.qemu", value, 0)) {
110        mIsOnEmulator = true;
111        mMinBufferCount = 12;  // to prevent systematic buffer underrun for emulator
112    }
113}
114
115// static
116bool MediaPlayer2AudioOutput::isOnEmulator() {
117    setMinBufferCount();  // benign race wrt other threads
118    return mIsOnEmulator;
119}
120
121// static
122int MediaPlayer2AudioOutput::getMinBufferCount() {
123    setMinBufferCount();  // benign race wrt other threads
124    return mMinBufferCount;
125}
126
127ssize_t MediaPlayer2AudioOutput::bufferSize() const {
128    Mutex::Autolock lock(mLock);
129    if (mTrack == 0) {
130        return NO_INIT;
131    }
132    return mTrack->frameCount() * mFrameSize;
133}
134
135ssize_t MediaPlayer2AudioOutput::frameCount() const {
136    Mutex::Autolock lock(mLock);
137    if (mTrack == 0) {
138        return NO_INIT;
139    }
140    return mTrack->frameCount();
141}
142
143ssize_t MediaPlayer2AudioOutput::channelCount() const {
144    Mutex::Autolock lock(mLock);
145    if (mTrack == 0) {
146        return NO_INIT;
147    }
148    return mTrack->channelCount();
149}
150
151ssize_t MediaPlayer2AudioOutput::frameSize() const {
152    Mutex::Autolock lock(mLock);
153    if (mTrack == 0) {
154        return NO_INIT;
155    }
156    return mFrameSize;
157}
158
159uint32_t MediaPlayer2AudioOutput::latency () const {
160    Mutex::Autolock lock(mLock);
161    if (mTrack == 0) {
162        return 0;
163    }
164    return mTrack->latency();
165}
166
167float MediaPlayer2AudioOutput::msecsPerFrame() const {
168    Mutex::Autolock lock(mLock);
169    return mMsecsPerFrame;
170}
171
172status_t MediaPlayer2AudioOutput::getPosition(uint32_t *position) const {
173    Mutex::Autolock lock(mLock);
174    if (mTrack == 0) {
175        return NO_INIT;
176    }
177    return mTrack->getPosition(position);
178}
179
180status_t MediaPlayer2AudioOutput::getTimestamp(AudioTimestamp &ts) const {
181    Mutex::Autolock lock(mLock);
182    if (mTrack == 0) {
183        return NO_INIT;
184    }
185    return mTrack->getTimestamp(ts);
186}
187
188// TODO: Remove unnecessary calls to getPlayedOutDurationUs()
189// as it acquires locks and may query the audio driver.
190//
191// Some calls could conceivably retrieve extrapolated data instead of
192// accessing getTimestamp() or getPosition() every time a data buffer with
193// a media time is received.
194//
195// Calculate duration of played samples if played at normal rate (i.e., 1.0).
196int64_t MediaPlayer2AudioOutput::getPlayedOutDurationUs(int64_t nowUs) const {
197    Mutex::Autolock lock(mLock);
198    if (mTrack == 0 || mSampleRateHz == 0) {
199        return 0;
200    }
201
202    uint32_t numFramesPlayed;
203    int64_t numFramesPlayedAtUs;
204    AudioTimestamp ts;
205
206    status_t res = mTrack->getTimestamp(ts);
207    if (res == OK) {                 // case 1: mixing audio tracks and offloaded tracks.
208        numFramesPlayed = ts.mPosition;
209        numFramesPlayedAtUs = ts.mTime.tv_sec * 1000000LL + ts.mTime.tv_nsec / 1000;
210        //ALOGD("getTimestamp: OK %d %lld", numFramesPlayed, (long long)numFramesPlayedAtUs);
211    } else if (res == WOULD_BLOCK) { // case 2: transitory state on start of a new track
212        numFramesPlayed = 0;
213        numFramesPlayedAtUs = nowUs;
214        //ALOGD("getTimestamp: WOULD_BLOCK %d %lld",
215        //        numFramesPlayed, (long long)numFramesPlayedAtUs);
216    } else {                         // case 3: transitory at new track or audio fast tracks.
217        res = mTrack->getPosition(&numFramesPlayed);
218        CHECK_EQ(res, (status_t)OK);
219        numFramesPlayedAtUs = nowUs;
220        numFramesPlayedAtUs += 1000LL * mTrack->latency() / 2; /* XXX */
221        //ALOGD("getPosition: %u %lld", numFramesPlayed, (long long)numFramesPlayedAtUs);
222    }
223
224    // CHECK_EQ(numFramesPlayed & (1 << 31), 0);  // can't be negative until 12.4 hrs, test
225    // TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours.
226    int64_t durationUs = (int64_t)((int32_t)numFramesPlayed * 1000000LL / mSampleRateHz)
227            + nowUs - numFramesPlayedAtUs;
228    if (durationUs < 0) {
229        // Occurs when numFramesPlayed position is very small and the following:
230        // (1) In case 1, the time nowUs is computed before getTimestamp() is called and
231        //     numFramesPlayedAtUs is greater than nowUs by time more than numFramesPlayed.
232        // (2) In case 3, using getPosition and adding mAudioSink->latency() to
233        //     numFramesPlayedAtUs, by a time amount greater than numFramesPlayed.
234        //
235        // Both of these are transitory conditions.
236        ALOGV("getPlayedOutDurationUs: negative duration %lld set to zero", (long long)durationUs);
237        durationUs = 0;
238    }
239    ALOGV("getPlayedOutDurationUs(%lld) nowUs(%lld) frames(%u) framesAt(%lld)",
240            (long long)durationUs, (long long)nowUs,
241            numFramesPlayed, (long long)numFramesPlayedAtUs);
242    return durationUs;
243}
244
245status_t MediaPlayer2AudioOutput::getFramesWritten(uint32_t *frameswritten) const {
246    Mutex::Autolock lock(mLock);
247    if (mTrack == 0) {
248        return NO_INIT;
249    }
250    ExtendedTimestamp ets;
251    status_t status = mTrack->getTimestamp(&ets);
252    if (status == OK || status == WOULD_BLOCK) {
253        *frameswritten = (uint32_t)ets.mPosition[ExtendedTimestamp::LOCATION_CLIENT];
254    }
255    return status;
256}
257
258status_t MediaPlayer2AudioOutput::setParameters(const String8& keyValuePairs) {
259    Mutex::Autolock lock(mLock);
260    if (mTrack == 0) {
261        return NO_INIT;
262    }
263    return mTrack->setParameters(keyValuePairs);
264}
265
266String8  MediaPlayer2AudioOutput::getParameters(const String8& keys) {
267    Mutex::Autolock lock(mLock);
268    if (mTrack == 0) {
269        return String8::empty();
270    }
271    return mTrack->getParameters(keys);
272}
273
274void MediaPlayer2AudioOutput::setAudioAttributes(const audio_attributes_t * attributes) {
275    Mutex::Autolock lock(mLock);
276    if (attributes == NULL) {
277        free(mAttributes);
278        mAttributes = NULL;
279    } else {
280        if (mAttributes == NULL) {
281            mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
282        }
283        memcpy(mAttributes, attributes, sizeof(audio_attributes_t));
284        mStreamType = audio_attributes_to_stream_type(attributes);
285    }
286}
287
288void MediaPlayer2AudioOutput::setAudioStreamType(audio_stream_type_t streamType) {
289    Mutex::Autolock lock(mLock);
290    // do not allow direct stream type modification if attributes have been set
291    if (mAttributes == NULL) {
292        mStreamType = streamType;
293    }
294}
295
296void MediaPlayer2AudioOutput::close_l() {
297    mTrack.clear();
298}
299
300status_t MediaPlayer2AudioOutput::open(
301        uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
302        audio_format_t format, int bufferCount,
303        AudioCallback cb, void *cookie,
304        audio_output_flags_t flags,
305        const audio_offload_info_t *offloadInfo,
306        bool doNotReconnect,
307        uint32_t suggestedFrameCount) {
308    ALOGV("open(%u, %d, 0x%x, 0x%x, %d, %d 0x%x)", sampleRate, channelCount, channelMask,
309                format, bufferCount, mSessionId, flags);
310
311    // offloading is only supported in callback mode for now.
312    // offloadInfo must be present if offload flag is set
313    if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) &&
314            ((cb == NULL) || (offloadInfo == NULL))) {
315        return BAD_VALUE;
316    }
317
318    // compute frame count for the AudioTrack internal buffer
319    size_t frameCount;
320    if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
321        frameCount = 0; // AudioTrack will get frame count from AudioFlinger
322    } else {
323        // try to estimate the buffer processing fetch size from AudioFlinger.
324        // framesPerBuffer is approximate and generally correct, except when it's not :-).
325        uint32_t afSampleRate;
326        size_t afFrameCount;
327        if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) {
328            return NO_INIT;
329        }
330        if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) {
331            return NO_INIT;
332        }
333        const size_t framesPerBuffer =
334                (unsigned long long)sampleRate * afFrameCount / afSampleRate;
335
336        if (bufferCount == 0) {
337            // use suggestedFrameCount
338            bufferCount = (suggestedFrameCount + framesPerBuffer - 1) / framesPerBuffer;
339        }
340        // Check argument bufferCount against the mininum buffer count
341        if (bufferCount != 0 && bufferCount < mMinBufferCount) {
342            ALOGV("bufferCount (%d) increased to %d", bufferCount, mMinBufferCount);
343            bufferCount = mMinBufferCount;
344        }
345        // if frameCount is 0, then AudioTrack will get frame count from AudioFlinger
346        // which will be the minimum size permitted.
347        frameCount = bufferCount * framesPerBuffer;
348    }
349
350    if (channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
351        channelMask = audio_channel_out_mask_from_count(channelCount);
352        if (0 == channelMask) {
353            ALOGE("open() error, can\'t derive mask for %d audio channels", channelCount);
354            return NO_INIT;
355        }
356    }
357
358    Mutex::Autolock lock(mLock);
359    mCallback = cb;
360    mCallbackCookie = cookie;
361
362    sp<AudioTrack> t;
363    CallbackData *newcbd = NULL;
364
365    ALOGV("creating new AudioTrack");
366
367    if (mCallback != NULL) {
368        newcbd = new CallbackData(this);
369        t = new AudioTrack(
370                mStreamType,
371                sampleRate,
372                format,
373                channelMask,
374                frameCount,
375                flags,
376                CallbackWrapper,
377                newcbd,
378                0,  // notification frames
379                mSessionId,
380                AudioTrack::TRANSFER_CALLBACK,
381                offloadInfo,
382                mUid,
383                mPid,
384                mAttributes,
385                doNotReconnect,
386                1.0f,  // default value for maxRequiredSpeed
387                mSelectedDeviceId);
388    } else {
389        // TODO: Due to buffer memory concerns, we use a max target playback speed
390        // based on mPlaybackRate at the time of open (instead of kMaxRequiredSpeed),
391        // also clamping the target speed to 1.0 <= targetSpeed <= kMaxRequiredSpeed.
392        const float targetSpeed =
393                std::min(std::max(mPlaybackRate.mSpeed, 1.0f), kMaxRequiredSpeed);
394        ALOGW_IF(targetSpeed != mPlaybackRate.mSpeed,
395                "track target speed:%f clamped from playback speed:%f",
396                targetSpeed, mPlaybackRate.mSpeed);
397        t = new AudioTrack(
398                mStreamType,
399                sampleRate,
400                format,
401                channelMask,
402                frameCount,
403                flags,
404                NULL, // callback
405                NULL, // user data
406                0, // notification frames
407                mSessionId,
408                AudioTrack::TRANSFER_DEFAULT,
409                NULL, // offload info
410                mUid,
411                mPid,
412                mAttributes,
413                doNotReconnect,
414                targetSpeed,
415                mSelectedDeviceId);
416    }
417
418    if ((t == 0) || (t->initCheck() != NO_ERROR)) {
419        ALOGE("Unable to create audio track");
420        delete newcbd;
421        // t goes out of scope, so reference count drops to zero
422        return NO_INIT;
423    } else {
424        // successful AudioTrack initialization implies a legacy stream type was generated
425        // from the audio attributes
426        mStreamType = t->streamType();
427    }
428
429    CHECK((t != NULL) && ((mCallback == NULL) || (newcbd != NULL)));
430
431    mCallbackData = newcbd;
432    ALOGV("setVolume");
433    t->setVolume(mLeftVolume, mRightVolume);
434
435    mSampleRateHz = sampleRate;
436    mFlags = flags;
437    mMsecsPerFrame = 1E3f / (mPlaybackRate.mSpeed * sampleRate);
438    mFrameSize = t->frameSize();
439    mTrack = t;
440
441    return updateTrack_l();
442}
443
444status_t MediaPlayer2AudioOutput::updateTrack_l() {
445    if (mTrack == NULL) {
446        return NO_ERROR;
447    }
448
449    status_t res = NO_ERROR;
450    // Note some output devices may give us a direct track even though we don't specify it.
451    // Example: Line application b/17459982.
452    if ((mTrack->getFlags()
453            & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT)) == 0) {
454        res = mTrack->setPlaybackRate(mPlaybackRate);
455        if (res == NO_ERROR) {
456            mTrack->setAuxEffectSendLevel(mSendLevel);
457            res = mTrack->attachAuxEffect(mAuxEffectId);
458        }
459    }
460    mTrack->setOutputDevice(mSelectedDeviceId);
461    if (mDeviceCallbackEnabled) {
462        mTrack->addAudioDeviceCallback(mDeviceCallback.promote());
463    }
464    ALOGV("updateTrack_l() DONE status %d", res);
465    return res;
466}
467
468status_t MediaPlayer2AudioOutput::start() {
469    ALOGV("start");
470    Mutex::Autolock lock(mLock);
471    if (mCallbackData != NULL) {
472        mCallbackData->endTrackSwitch();
473    }
474    if (mTrack != 0) {
475        mTrack->setVolume(mLeftVolume, mRightVolume);
476        mTrack->setAuxEffectSendLevel(mSendLevel);
477        status_t status = mTrack->start();
478        return status;
479    }
480    return NO_INIT;
481}
482
483ssize_t MediaPlayer2AudioOutput::write(const void* buffer, size_t size, bool blocking) {
484    Mutex::Autolock lock(mLock);
485    LOG_ALWAYS_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
486
487    //ALOGV("write(%p, %u)", buffer, size);
488    if (mTrack != 0) {
489        return mTrack->write(buffer, size, blocking);
490    }
491    return NO_INIT;
492}
493
494void MediaPlayer2AudioOutput::stop() {
495    ALOGV("stop");
496    Mutex::Autolock lock(mLock);
497    if (mTrack != 0) {
498        mTrack->stop();
499    }
500}
501
502void MediaPlayer2AudioOutput::flush() {
503    ALOGV("flush");
504    Mutex::Autolock lock(mLock);
505    if (mTrack != 0) {
506        mTrack->flush();
507    }
508}
509
510void MediaPlayer2AudioOutput::pause() {
511    ALOGV("pause");
512    Mutex::Autolock lock(mLock);
513    if (mTrack != 0) {
514        mTrack->pause();
515    }
516}
517
518void MediaPlayer2AudioOutput::close() {
519    ALOGV("close");
520    sp<AudioTrack> track;
521    {
522        Mutex::Autolock lock(mLock);
523        track = mTrack;
524        close_l(); // clears mTrack
525    }
526    // destruction of the track occurs outside of mutex.
527}
528
529void MediaPlayer2AudioOutput::setVolume(float left, float right) {
530    ALOGV("setVolume(%f, %f)", left, right);
531    Mutex::Autolock lock(mLock);
532    mLeftVolume = left;
533    mRightVolume = right;
534    if (mTrack != 0) {
535        mTrack->setVolume(left, right);
536    }
537}
538
539status_t MediaPlayer2AudioOutput::setPlaybackRate(const AudioPlaybackRate &rate) {
540    ALOGV("setPlaybackRate(%f %f %d %d)",
541                rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
542    Mutex::Autolock lock(mLock);
543    if (mTrack == 0) {
544        // remember rate so that we can set it when the track is opened
545        mPlaybackRate = rate;
546        return OK;
547    }
548    status_t res = mTrack->setPlaybackRate(rate);
549    if (res != NO_ERROR) {
550        return res;
551    }
552    // rate.mSpeed is always greater than 0 if setPlaybackRate succeeded
553    CHECK_GT(rate.mSpeed, 0.f);
554    mPlaybackRate = rate;
555    if (mSampleRateHz != 0) {
556        mMsecsPerFrame = 1E3f / (rate.mSpeed * mSampleRateHz);
557    }
558    return res;
559}
560
561status_t MediaPlayer2AudioOutput::getPlaybackRate(AudioPlaybackRate *rate) {
562    ALOGV("setPlaybackRate");
563    Mutex::Autolock lock(mLock);
564    if (mTrack == 0) {
565        return NO_INIT;
566    }
567    *rate = mTrack->getPlaybackRate();
568    return NO_ERROR;
569}
570
571status_t MediaPlayer2AudioOutput::setAuxEffectSendLevel(float level) {
572    ALOGV("setAuxEffectSendLevel(%f)", level);
573    Mutex::Autolock lock(mLock);
574    mSendLevel = level;
575    if (mTrack != 0) {
576        return mTrack->setAuxEffectSendLevel(level);
577    }
578    return NO_ERROR;
579}
580
581status_t MediaPlayer2AudioOutput::attachAuxEffect(int effectId) {
582    ALOGV("attachAuxEffect(%d)", effectId);
583    Mutex::Autolock lock(mLock);
584    mAuxEffectId = effectId;
585    if (mTrack != 0) {
586        return mTrack->attachAuxEffect(effectId);
587    }
588    return NO_ERROR;
589}
590
591status_t MediaPlayer2AudioOutput::setOutputDevice(audio_port_handle_t deviceId) {
592    ALOGV("setOutputDevice(%d)", deviceId);
593    Mutex::Autolock lock(mLock);
594    mSelectedDeviceId = deviceId;
595    if (mTrack != 0) {
596        return mTrack->setOutputDevice(deviceId);
597    }
598    return NO_ERROR;
599}
600
601status_t MediaPlayer2AudioOutput::getRoutedDeviceId(audio_port_handle_t* deviceId) {
602    ALOGV("getRoutedDeviceId");
603    Mutex::Autolock lock(mLock);
604    if (mTrack != 0) {
605        mRoutedDeviceId = mTrack->getRoutedDeviceId();
606    }
607    *deviceId = mRoutedDeviceId;
608    return NO_ERROR;
609}
610
611status_t MediaPlayer2AudioOutput::enableAudioDeviceCallback(bool enabled) {
612    ALOGV("enableAudioDeviceCallback, %d", enabled);
613    Mutex::Autolock lock(mLock);
614    mDeviceCallbackEnabled = enabled;
615    if (mTrack != 0) {
616        status_t status;
617        if (enabled) {
618            status = mTrack->addAudioDeviceCallback(mDeviceCallback.promote());
619        } else {
620            status = mTrack->removeAudioDeviceCallback(mDeviceCallback.promote());
621        }
622        return status;
623    }
624    return NO_ERROR;
625}
626
627// static
628void MediaPlayer2AudioOutput::CallbackWrapper(
629        int event, void *cookie, void *info) {
630    //ALOGV("callbackwrapper");
631    CallbackData *data = (CallbackData*)cookie;
632    // lock to ensure we aren't caught in the middle of a track switch.
633    data->lock();
634    MediaPlayer2AudioOutput *me = data->getOutput();
635    AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
636    if (me == NULL) {
637        // no output set, likely because the track was scheduled to be reused
638        // by another player, but the format turned out to be incompatible.
639        data->unlock();
640        if (buffer != NULL) {
641            buffer->size = 0;
642        }
643        return;
644    }
645
646    switch(event) {
647    case AudioTrack::EVENT_MORE_DATA: {
648        size_t actualSize = (*me->mCallback)(
649                me, buffer->raw, buffer->size, me->mCallbackCookie,
650                CB_EVENT_FILL_BUFFER);
651
652        // Log when no data is returned from the callback.
653        // (1) We may have no data (especially with network streaming sources).
654        // (2) We may have reached the EOS and the audio track is not stopped yet.
655        // Note that AwesomePlayer/AudioPlayer will only return zero size when it reaches the EOS.
656        // NuPlayer2Renderer will return zero when it doesn't have data (it doesn't block to fill).
657        //
658        // This is a benign busy-wait, with the next data request generated 10 ms or more later;
659        // nevertheless for power reasons, we don't want to see too many of these.
660
661        ALOGV_IF(actualSize == 0 && buffer->size > 0, "callbackwrapper: empty buffer returned");
662
663        buffer->size = actualSize;
664        } break;
665
666    case AudioTrack::EVENT_STREAM_END:
667        // currently only occurs for offloaded callbacks
668        ALOGV("callbackwrapper: deliver EVENT_STREAM_END");
669        (*me->mCallback)(me, NULL /* buffer */, 0 /* size */,
670                me->mCallbackCookie, CB_EVENT_STREAM_END);
671        break;
672
673    case AudioTrack::EVENT_NEW_IAUDIOTRACK :
674        ALOGV("callbackwrapper: deliver EVENT_TEAR_DOWN");
675        (*me->mCallback)(me,  NULL /* buffer */, 0 /* size */,
676                me->mCallbackCookie, CB_EVENT_TEAR_DOWN);
677        break;
678
679    case AudioTrack::EVENT_UNDERRUN:
680        // This occurs when there is no data available, typically
681        // when there is a failure to supply data to the AudioTrack.  It can also
682        // occur in non-offloaded mode when the audio device comes out of standby.
683        //
684        // If an AudioTrack underruns it outputs silence. Since this happens suddenly
685        // it may sound like an audible pop or glitch.
686        //
687        // The underrun event is sent once per track underrun; the condition is reset
688        // when more data is sent to the AudioTrack.
689        ALOGD("callbackwrapper: EVENT_UNDERRUN (discarded)");
690        break;
691
692    default:
693        ALOGE("received unknown event type: %d inside CallbackWrapper !", event);
694    }
695
696    data->unlock();
697}
698
699audio_session_t MediaPlayer2AudioOutput::getSessionId() const
700{
701    Mutex::Autolock lock(mLock);
702    return mSessionId;
703}
704
705uint32_t MediaPlayer2AudioOutput::getSampleRate() const
706{
707    Mutex::Autolock lock(mLock);
708    if (mTrack == 0) {
709        return 0;
710    }
711    return mTrack->getSampleRate();
712}
713
714int64_t MediaPlayer2AudioOutput::getBufferDurationInUs() const
715{
716    Mutex::Autolock lock(mLock);
717    if (mTrack == 0) {
718        return 0;
719    }
720    int64_t duration;
721    if (mTrack->getBufferDurationInUs(&duration) != OK) {
722        return 0;
723    }
724    return duration;
725}
726
727} // namespace android
728