AudioStreamOut.cpp revision e78fa3676f07529a565b6b073d8c63d14f8c383a
1ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen/*
2ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen**
3ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen** Copyright 2012, The Android Open Source Project
4ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen**
5ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen** Licensed under the Apache License, Version 2.0 (the "License");
6ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen** you may not use this file except in compliance with the License.
7ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen** You may obtain a copy of the License at
8ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen**
9ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen**     http://www.apache.org/licenses/LICENSE-2.0
10ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen**
11ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen** Unless required by applicable law or agreed to in writing, software
12ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen** distributed under the License is distributed on an "AS IS" BASIS,
13ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen** See the License for the specific language governing permissions and
15ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen** limitations under the License.
16ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen*/
17ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
18ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#define LOG_TAG "AudioHAL:AudioStreamOut"
19ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
20ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#include <utils/Log.h>
21ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
22ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#include "AudioHardwareOutput.h"
23ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#include "AudioStreamOut.h"
24ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
25ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen// Set to 1 to print timestamp data in CSV format.
26ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#ifndef HAL_PRINT_TIMESTAMP_CSV
27ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#define HAL_PRINT_TIMESTAMP_CSV 0
28ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#endif
29ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
30ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen//#define VERY_VERBOSE_LOGGING
31ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#ifdef VERY_VERBOSE_LOGGING
32ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#define ALOGVV ALOGV
33ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#else
34ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#define ALOGVV(a...) do { } while(0)
35ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#endif
36ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
37ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chennamespace android {
38ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
39ae089528c7e3a8107be65657e52276dd068c1039Mike J. ChenAudioStreamOut::AudioStreamOut(AudioHardwareOutput& owner, bool mcOut)
40ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    : mFramesPresented(0)
41e78fa3676f07529a565b6b073d8c63d14f8c383aPhil Burk    , mFramesRendered(0)
42ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    , mFramesWrittenRemainder(0)
43ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    , mOwnerHAL(owner)
44ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    , mFramesWritten(0)
45ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    , mTgtDevices(0)
46ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    , mAudioFlingerTgtDevices(0)
47ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    , mIsMCOutput(mcOut)
48ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    , mIsEncoded(false)
49ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    , mSPDIFEncoder(this)
50ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
51ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    assert(mLocalClock.initCheck());
52ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
53ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mPhysOutputs.setCapacity(3);
54ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
55ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Set some reasonable defaults for these.  All of this should be eventually
56ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // be overwritten by a specific audio flinger configuration, but it does not
57ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // hurt to have something here by default.
58ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mInputSampleRate = 48000;
59ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mInputChanMask = AUDIO_CHANNEL_OUT_STEREO;
60ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mInputFormat = AUDIO_FORMAT_PCM_16_BIT;
61ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mInputNominalChunksInFlight = 4;
62ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    updateInputNums();
63ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
64ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mThrottleValid = false;
65ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
66ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    memset(&mUSecToLocalTime, 0, sizeof(mUSecToLocalTime));
67ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mUSecToLocalTime.a_to_b_numer = mLocalClock.getLocalFreq();
68ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mUSecToLocalTime.a_to_b_denom = 1000000;
69ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    LinearTransform::reduce(&mUSecToLocalTime.a_to_b_numer,
70ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                            &mUSecToLocalTime.a_to_b_denom);
71ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
72ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
73ae089528c7e3a8107be65657e52276dd068c1039Mike J. ChenAudioStreamOut::~AudioStreamOut()
74ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
75ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    releaseAllOutputs();
76ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
77ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
78ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenstatus_t AudioStreamOut::set(
79ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        audio_format_t *pFormat,
80ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        uint32_t *pChannels,
81ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        uint32_t *pRate)
82ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
83ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    Mutex::Autolock _l(mLock);
84ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    audio_format_t lFormat   = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT;
85ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    uint32_t       lChannels = pChannels ? *pChannels : 0;
86ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    uint32_t       lRate     = pRate ? *pRate : 0;
87ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
88ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // fix up defaults
89ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (lFormat == AUDIO_FORMAT_DEFAULT) lFormat = format();
90ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (lChannels == 0)                  lChannels = chanMask();
91ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (lRate == 0)                      lRate = sampleRate();
92ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
93ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (pFormat)   *pFormat   = lFormat;
94ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (pChannels) *pChannels = lChannels;
95ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (pRate)     *pRate     = lRate;
96ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
97ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mIsEncoded = !audio_is_linear_pcm(lFormat);
98ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
99ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (!mIsMCOutput && !mIsEncoded) {
100ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // If this is the primary stream out, then demand our defaults.
101ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        if ((lFormat   != format()) ||
102ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            (lChannels != chanMask()) ||
103ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            (lRate     != sampleRate()))
104ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            return BAD_VALUE;
105ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    } else {
106ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // Else check to see if our HDMI sink supports this format before proceeding.
107ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        if (!mOwnerHAL.getHDMIAudioCaps().supportsFormat(lFormat,
108ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                                                     lRate,
109ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                                                     audio_channel_count_from_out_mask(lChannels)))
110ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            return BAD_VALUE;
111ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
112ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
113ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mInputFormat = lFormat;
114ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mInputChanMask = lChannels;
115ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mInputSampleRate = lRate;
116ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    ALOGI("AudioStreamOut::set: lRate = %u, mIsEncoded = %d\n", lRate, mIsEncoded);
117ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    updateInputNums();
118ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
119ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    return NO_ERROR;
120ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
121ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
122ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenvoid AudioStreamOut::setTgtDevices(uint32_t tgtDevices)
123ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
124ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    Mutex::Autolock _l(mRoutingLock);
125ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (mTgtDevices != tgtDevices) {
126ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        mTgtDevices = tgtDevices;
127ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
128ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
129ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
130ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenstatus_t AudioStreamOut::standby()
131ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
132e78fa3676f07529a565b6b073d8c63d14f8c383aPhil Burk    mFramesRendered = 0;
133ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    releaseAllOutputs();
134ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    return NO_ERROR;
135ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
136ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
137ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenvoid AudioStreamOut::releaseAllOutputs() {
138ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    Mutex::Autolock _l(mRoutingLock);
139ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
140ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    ALOGI("releaseAllOutputs: releasing %d mPhysOutputs", mPhysOutputs.size());
141ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    AudioOutputList::iterator I;
142ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    for (I = mPhysOutputs.begin(); I != mPhysOutputs.end(); ++I)
143ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        mOwnerHAL.releaseOutput(*this, *I);
144ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
145ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mPhysOutputs.clear();
146ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
147ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
148ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenvoid AudioStreamOut::updateInputNums()
149ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
150ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    assert(mLocalClock.initCheck());
151ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
152ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // mInputBufSize determines how many audio frames AudioFlinger is going to
153ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // mix at a time.  We also use the mInputBufSize to determine the ALSA
154ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // period_size, the number of of samples which need to play out (at most)
155ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // before low level ALSA driver code is required to wake up upper levels of
156ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // SW to fill a new buffer.  As it turns out, ALSA is going to apply some
157ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // rules and modify the period_size which we pass to it.  One of the things
158ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // ALSA seems to do is attempt to round the period_size up to a value which
159ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // will make the period an integral number of 0.5 mSec.  This round-up
160ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // behavior can cause the low levels of ALSA to consume more data per period
161ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // than the AudioFlinger mixer has been told to produce.  If there are only
162ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // two buffers in flight at any given point in time, this can lead to a
163ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // situation where the pipeline ends up slipping an extra buffer and
164ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // underflowing.  There are two approaches to mitigate this, both of which
165ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // are implemented in this HAL...
166ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //
167ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // 1) Try as hard as possible to make certain that the buffer size we choose
168ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //    results in a period_size which is not going to get rounded up by ALSA.
169ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //    This means that we want a buffer size which at the chosen sample rate
170ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //    and frame size will be an integral multiple of 1/2 mSec.
171ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // 2) Increate the number of chunks we keep in flight.  If the system slips
172ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //    a single period, its only really a problem if there is no data left in
173ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //    the pipeline waiting to be played out.  The mixer should going to mix
174ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //    as fast as possible until the buffer has been topped off.  By
175ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //    decreasing the buffer size and increasing the number of buffers in
176ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //    flight, we increase the number of interrups and mix events per second,
177ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //    but buy ourselves some insurance against the negative side effects of
178ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //    slipping one buffer in the schedule.  We end up using 4 buffers at
179ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //    10mSec, making the total audio latency somewhere between 40 and 50
180ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //    mSec, depending on when a sample begins playback relative to
181ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //    AudioFlinger's mixing schedule.
182ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //
183ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mInputChanCount = audio_channel_count_from_out_mask(mInputChanMask);
184ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
185ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Picking a chunk duration 10mSec should satisfy #1 for both major families
186ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // of audio sample rates (the 44.1K and 48K families).  In the case of 44.1
187ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // (or higher) we will end up with a multiple of 441 frames of audio per
188ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // chunk, while for 48K, we will have a multiple of 480 frames of audio per
189ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // chunk.  This will not work well for lower sample rates in the 44.1 family
190ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // (22.05K and 11.025K); it is unlikely that we will ever be configured to
191ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // deliver those rates, and if we ever do, we will need to rely on having
192ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // extra chunks in flight to deal with the jitter problem described above.
193ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mInputChunkFrames = outputSampleRate() / 100;
194ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
195ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // FIXME: Currently, audio flinger demands an input buffer size which is a
196ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // multiple of 16 audio frames.  Right now, there is no good way to
197ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // reconcile this with ALSA round-up behavior described above when the
198ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // desired sample rate is a member of the 44.1 family.  For now, we just
199ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // round up to the nearest multiple of 16 frames and roll the dice, but
200ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // someday it would be good to fix one or the other halves of the problem
201ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // (either ALSA or AudioFlinger)
202ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mInputChunkFrames = (mInputChunkFrames + 0xF) & ~0xF;
203ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
204ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    ALOGD("AudioStreamOut::updateInputNums: chunk size %u from output rate %u\n",
205ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        mInputChunkFrames, outputSampleRate());
206ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
207ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Buffer size is just the frame size multiplied by the number of
208ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // frames per chunk.
209ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mInputBufSize = mInputChunkFrames * getBytesPerOutputFrame();
210ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
211ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // The nominal latency is just the duration of a chunk * the number of
212ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // chunks we nominally keep in flight at any given point in time.
213ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mInputNominalLatencyUSec = static_cast<uint32_t>(((
214ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                    static_cast<uint64_t>(mInputChunkFrames)
215ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                    * 1000000 * mInputNominalChunksInFlight)
216ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                    / mInputSampleRate));
217ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
218ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    memset(&mLocalTimeToFrames, 0, sizeof(mLocalTimeToFrames));
219ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mLocalTimeToFrames.a_to_b_numer = mInputSampleRate;
220ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mLocalTimeToFrames.a_to_b_denom = mLocalClock.getLocalFreq();
221ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    LinearTransform::reduce(
222ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            &mLocalTimeToFrames.a_to_b_numer,
223ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            &mLocalTimeToFrames.a_to_b_denom);
224ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
225ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
226ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenvoid AudioStreamOut::finishedWriteOp(size_t framesWritten,
227ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                                     bool needThrottle)
228ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
229ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    assert(mLocalClock.initCheck());
230ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
231ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    int64_t now = mLocalClock.getLocalTime();
232ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
233ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (!mThrottleValid || !needThrottle) {
234ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        mThrottleValid = true;
235ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        mWriteStartLT  = now;
236ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        mFramesWritten = 0;
237ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
238ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
239ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    size_t framesWrittenAppRate;
240ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    uint32_t multiplier = getRateMultiplier();
241ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (multiplier != 1) {
242ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // Accumulate round-off error from previous call.
243ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        framesWritten += mFramesWrittenRemainder;
244ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // Scale from device sample rate to application rate.
245ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        framesWrittenAppRate = framesWritten / multiplier;
246ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        ALOGV("finishedWriteOp() framesWrittenAppRate = %d = %d / %d\n",
247ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            framesWrittenAppRate, framesWritten, multiplier);
248ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // Save remainder for next time to prevent error accumulation.
249ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        mFramesWrittenRemainder = framesWritten - (framesWrittenAppRate * multiplier);
250ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    } else {
251ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        framesWrittenAppRate = framesWritten;
252ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
253ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
254ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mFramesWritten += framesWrittenAppRate;
255ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mFramesPresented += framesWrittenAppRate;
256e78fa3676f07529a565b6b073d8c63d14f8c383aPhil Burk    mFramesRendered += framesWrittenAppRate;
257ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
258ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (needThrottle) {
259ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        int64_t deltaLT;
260ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        mLocalTimeToFrames.doReverseTransform(mFramesWritten, &deltaLT);
261ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        deltaLT += mWriteStartLT;
262ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        deltaLT -= now;
263ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
264ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        int64_t deltaUSec;
265ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        mUSecToLocalTime.doReverseTransform(deltaLT, &deltaUSec);
266ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
267ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        if (deltaUSec > 0) {
268ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            useconds_t sleep_time;
269ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
270ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            // We should never be a full second ahead of schedule; sanity check
271ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            // our throttle time and cap the max sleep time at 1 second.
272ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            if (deltaUSec > 1000000)
273ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                sleep_time = 1000000;
274ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            else
275ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                sleep_time = static_cast<useconds_t>(deltaUSec);
276ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
277ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            usleep(sleep_time);
278ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        }
279ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
280ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
281ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
282ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenstatic const String8 keyRouting(AudioParameter::keyRouting);
283ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenstatic const String8 keySupSampleRates("sup_sampling_rates");
284ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenstatic const String8 keySupFormats("sup_formats");
285ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenstatic const String8 keySupChannels("sup_channels");
286ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenstatus_t AudioStreamOut::setParameters(__unused struct audio_stream *stream, const char *kvpairs)
287ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
288ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    AudioParameter param = AudioParameter(String8(kvpairs));
289ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    String8 key = String8(AudioParameter::keyRouting);
290ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    int tmpInt;
291ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
292ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (param.getInt(key, tmpInt) == NO_ERROR) {
293ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // The audio HAL handles routing to physical devices entirely
294ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // internally and mostly ignores what audio flinger tells it to do.  JiC
295ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // there is something (now or in the future) in audio flinger which
296ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // cares about the routing value in a call to getParameters, we hang on
297ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // to the last routing value set by audio flinger so we can at least be
298ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // consistent when we lie to the upper levels about doing what they told
299ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // us to do.
300ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        mAudioFlingerTgtDevices = static_cast<uint32_t>(tmpInt);
301ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
302ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
303ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    return NO_ERROR;
304ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
305ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
306ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenchar* AudioStreamOut::getParameters(const char* k)
307ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
308ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    AudioParameter param = AudioParameter(String8(k));
309ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    String8 value;
310ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
311ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (param.get(keyRouting, value) == NO_ERROR) {
312ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        param.addInt(keyRouting, (int)mAudioFlingerTgtDevices);
313ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
314ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
315ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    HDMIAudioCaps& hdmiCaps = mOwnerHAL.getHDMIAudioCaps();
316ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
317ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (param.get(keySupSampleRates, value) == NO_ERROR) {
318ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        if (mIsMCOutput) {
319ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            hdmiCaps.getRatesForAF(value);
320ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            param.add(keySupSampleRates, value);
321ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        } else {
322ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            param.add(keySupSampleRates, String8("48000"));
323ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        }
324ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
325ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
326ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (param.get(keySupFormats, value) == NO_ERROR) {
327ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        if (mIsMCOutput) {
328ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            hdmiCaps.getFmtsForAF(value);
329ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            param.add(keySupFormats, value);
330ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        } else {
331ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            param.add(keySupFormats, String8("AUDIO_FORMAT_PCM_16_BIT"));
332ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        }
333ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
334ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
335ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (param.get(keySupChannels, value) == NO_ERROR) {
336ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        if (mIsMCOutput) {
337fb00fc03145686357e87621e3744579f3829091fEric Laurent            hdmiCaps.getChannelMasksForAF(value, false);
338ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            param.add(keySupChannels, value);
339ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        } else {
340ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            param.add(keySupChannels, String8("AUDIO_CHANNEL_OUT_STEREO"));
341ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        }
342ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
343ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
344ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    return strdup(param.toString().string());
345ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
346ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
347ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenuint32_t AudioStreamOut::getRateMultiplier() const
348ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
349ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    return (mIsEncoded) ? mSPDIFEncoder.getRateMultiplier() : 1;
350ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
351ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
352ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenuint32_t AudioStreamOut::outputSampleRate() const
353ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
354ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    return mInputSampleRate * getRateMultiplier();
355ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
356ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
357ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenint AudioStreamOut::getBytesPerOutputFrame()
358ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
359ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    return (mIsEncoded) ? mSPDIFEncoder.getBytesPerOutputFrame()
360ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        : (mInputChanCount * sizeof(int16_t));
361ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
362ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
363ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenuint32_t AudioStreamOut::latency() const {
364ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    uint32_t uSecLatency = mInputNominalLatencyUSec;
365ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    uint32_t vcompDelay = mOwnerHAL.getVideoDelayCompUsec();
366ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
367ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (uSecLatency < vcompDelay)
368ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        return 0;
369ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
370ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    return ((uSecLatency - vcompDelay) / 1000);
371ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
372ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
373ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen// Used to implement get_presentation_position() for Audio HAL.
374ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen// According to the prototype in audio.h, the frame count should not get
375ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen// reset on standby().
376ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenstatus_t AudioStreamOut::getPresentationPosition(uint64_t *frames,
377ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        struct timespec *timestamp)
378ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
379ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    Mutex::Autolock _l(mRoutingLock);
380ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    status_t result = -ENODEV;
381ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // The presentation timestamp should be the same for all devices.
382ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Also Molly only has one output device at the moment.
383ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // So just use the first one in the list.
384ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (!mPhysOutputs.isEmpty()) {
385ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        const unsigned int kInsaneAvail = 10 * 48000;
386ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        unsigned int avail = 0;
387ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        sp<AudioOutput> audioOutput = mPhysOutputs.itemAt(0);
388ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        if (audioOutput->getHardwareTimestamp(&avail, timestamp) == 0) {
389ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            if (avail < kInsaneAvail) {
390ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // FIXME av sync fudge factor
391ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // Use a fudge factor to account for hidden buffering in the
392ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // HDMI output path. This is a hack until we can determine the
393ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // actual buffer sizes.
394ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // Increasing kFudgeMSec will move the audio earlier in
395ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // relation to the video.
396ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                const int kFudgeMSec = 40;
397ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                int fudgeFrames = kFudgeMSec * sampleRate() / 1000;
398ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
399ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // Scale the frames in the driver because it might be running at
400ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // a higher rate for EAC3.
401ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                int64_t framesInDriverBuffer =
402ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                    (int64_t)audioOutput->getKernelBufferSize() - (int64_t)avail;
403ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                framesInDriverBuffer = framesInDriverBuffer / getRateMultiplier();
404ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
405ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                int64_t pendingFrames = framesInDriverBuffer + fudgeFrames;
406ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                int64_t signedFrames = mFramesPresented - pendingFrames;
407ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                if (pendingFrames < 0) {
408ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                    ALOGE("getPresentationPosition: negative pendingFrames = %lld",
409ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                        pendingFrames);
410ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                } else if (signedFrames < 0) {
411ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                    ALOGI("getPresentationPosition: playing silent preroll"
412ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                        ", mFramesPresented = %llu, pendingFrames = %lld",
413ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                        mFramesPresented, pendingFrames);
414ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                } else {
415ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#if HAL_PRINT_TIMESTAMP_CSV
416ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                    // Print comma separated values for spreadsheet analysis.
417ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                    uint64_t nanos = (((uint64_t)timestamp->tv_sec) * 1000000000L)
418ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                            + timestamp->tv_nsec;
419ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                    ALOGI("getPresentationPosition, %lld, %4u, %lld, %llu",
420ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                            mFramesPresented, avail, signedFrames, nanos);
421ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#endif
422ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                    *frames = (uint64_t) signedFrames;
423ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                    result = NO_ERROR;
424ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                }
425ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            } else {
426ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                ALOGE("getPresentationPosition: avail too large = %u", avail);
427ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            }
428ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        } else {
429ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            ALOGE("getPresentationPosition: getHardwareTimestamp returned non-zero");
430ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        }
431ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    } else {
432b7d477723e64b7526106641de168788e59152617Andre Eisenbach        ALOGVV("getPresentationPosition: no physical outputs! This HAL is inactive!");
433ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
434ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    return result;
435ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
436ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
437ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenstatus_t AudioStreamOut::getRenderPosition(__unused uint32_t *dspFrames)
438ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
439e78fa3676f07529a565b6b073d8c63d14f8c383aPhil Burk    if (dspFrames == NULL) {
440e78fa3676f07529a565b6b073d8c63d14f8c383aPhil Burk        return -EINVAL;
441e78fa3676f07529a565b6b073d8c63d14f8c383aPhil Burk    }
442e78fa3676f07529a565b6b073d8c63d14f8c383aPhil Burk    if (mPhysOutputs.isEmpty()) {
443e78fa3676f07529a565b6b073d8c63d14f8c383aPhil Burk        *dspFrames = 0;
444e78fa3676f07529a565b6b073d8c63d14f8c383aPhil Burk        return -ENODEV;
445e78fa3676f07529a565b6b073d8c63d14f8c383aPhil Burk    }
446e78fa3676f07529a565b6b073d8c63d14f8c383aPhil Burk    *dspFrames = (uint32_t) mFramesRendered;
447e78fa3676f07529a565b6b073d8c63d14f8c383aPhil Burk    return NO_ERROR;
448ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
449ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
450ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenvoid AudioStreamOut::updateTargetOutputs()
451ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
452ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    Mutex::Autolock _l(mRoutingLock);
453ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
454ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    AudioOutputList::iterator I;
455ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    uint32_t cur_outputs = 0;
456ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
457ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    for (I = mPhysOutputs.begin(); I != mPhysOutputs.end(); ++I)
458ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        cur_outputs |= (*I)->devMask();
459ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
460ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (cur_outputs == mTgtDevices)
461ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        return;
462ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
463ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    uint32_t outputsToObtain  = mTgtDevices & ~cur_outputs;
464ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    uint32_t outputsToRelease = cur_outputs & ~mTgtDevices;
465ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
466ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Start by releasing any outputs we should no longer have back to the HAL.
467ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (outputsToRelease) {
468ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
469ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        I = mPhysOutputs.begin();
470ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        while (I != mPhysOutputs.end()) {
471ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            if (!(outputsToRelease & (*I)->devMask())) {
472ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                ++I;
473ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                continue;
474ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            }
475ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
476ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            outputsToRelease &= ~((*I)->devMask());
477ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            mOwnerHAL.releaseOutput(*this, *I);
478ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            I = mPhysOutputs.erase(I);
479ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        }
480ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
481ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
482ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (outputsToRelease) {
483ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        ALOGW("Bookkeeping error!  Still have outputs to release (%08x), but"
484ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen              " none of them appear to be in the mPhysOutputs list!",
485ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen              outputsToRelease);
486ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
487ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
488ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Now attempt to obtain any outputs we should be using, but are not
489ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // currently.
490ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (outputsToObtain) {
491ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        uint32_t mask;
492ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
493ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // Buffer configuration may need updating now that we have decoded
494ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        // the start of a stream. For example, EAC3, needs 4X sampleRate.
495ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        updateInputNums();
496ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
497ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        for (mask = 0x1; outputsToObtain; mask <<= 1) {
498ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            if (!(mask & outputsToObtain))
499ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                continue;
500ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
501ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            sp<AudioOutput> newOutput;
502ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            status_t res;
503ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
504ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            res = mOwnerHAL.obtainOutput(*this, mask, &newOutput);
505ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            outputsToObtain &= ~mask;
506ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
507ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            if (OK != res) {
508ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // If we get an error back from obtain output, it means that
509ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // something went really wrong at a lower level (probably failed
510ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // to open the driver).  We should not try to obtain this output
511ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // again, at least until the next routing change.
512ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                ALOGW("Failed to obtain output %08x for %s audio stream out."
513ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                      " (res %d)", mask, getName(), res);
514ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                mTgtDevices &= ~mask;
515ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                continue;
516ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            }
517ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
518ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            if (newOutput != NULL) {
519ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // If we actually got an output, go ahead and add it to our list
520ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // of physical outputs.  The rest of the system will handle
521ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // starting it up.  If we didn't get an output, but also go no
522ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // error code, it just means that the output is currently busy
523ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                // and should become available soon.
524ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                ALOGI("updateTargetOutputs: adding output back to mPhysOutputs");
525ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                mPhysOutputs.push_back(newOutput);
526ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            }
527ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        }
528ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
529ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
530ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
531ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenvoid AudioStreamOut::adjustOutputs(int64_t maxTime)
532ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
533ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    AudioOutputList::iterator I;
534ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
535ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Check to see if any outputs are active and see what their buffer levels
536ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // are.
537ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    for (I = mPhysOutputs.begin(); I != mPhysOutputs.end(); ++I) {
538ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        if ((*I)->getState() == AudioOutput::DMA_START) {
539ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            int64_t lastWriteTS = (*I)->getLastNextWriteTS();
540ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            int64_t padAmt;
541ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
542ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            mLocalTimeToFrames.a_zero = lastWriteTS;
543ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            mLocalTimeToFrames.b_zero = 0;
544ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            if (mLocalTimeToFrames.doForwardTransform(maxTime,
545ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                                                      &padAmt)) {
546ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                (*I)->adjustDelay(((int32_t)padAmt));
547ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            }
548ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        }
549ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
550ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
551ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
552ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenssize_t AudioStreamOut::write(const void* buffer, size_t bytes)
553ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
554ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    uint8_t *data = (uint8_t *)buffer;
555ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    ALOGVV("AudioStreamOut::write(%u)   0x%02X, 0x%02X, 0x%02X, 0x%02X,"
556ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen          " 0x%02X, 0x%02X, 0x%02X, 0x%02X,"
557ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen          " 0x%02X, 0x%02X, 0x%02X, 0x%02X,"
558ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen          " 0x%02X, 0x%02X, 0x%02X, 0x%02X ====",
559ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        bytes, data[0], data[1], data[2], data[3],
560ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        data[4], data[5], data[6], data[7],
561ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        data[8], data[9], data[10], data[11],
562ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        data[12], data[13], data[14], data[15]
563ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        );
564ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (mIsEncoded) {
565ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        return mSPDIFEncoder.write(buffer, bytes);
566ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    } else {
567ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        return writeInternal(buffer, bytes);
568ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
569ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
570ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
571ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenssize_t AudioStreamOut::writeInternal(const void* buffer, size_t bytes)
572ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
573ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    uint8_t *data = (uint8_t *)buffer;
574ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    ALOGVV("AudioStreamOut::write_l(%u) 0x%02X, 0x%02X, 0x%02X, 0x%02X,"
575ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen          " 0x%02X, 0x%02X, 0x%02X, 0x%02X,"
576ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen          " 0x%02X, 0x%02X, 0x%02X, 0x%02X,"
577ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen          " 0x%02X, 0x%02X, 0x%02X, 0x%02X",
578ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        bytes, data[0], data[1], data[2], data[3],
579ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        data[4], data[5], data[6], data[7],
580ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        data[8], data[9], data[10], data[11],
581ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        data[12], data[13], data[14], data[15]
582ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        );
583ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Note: no lock is obtained here.  Calls to write and getNextWriteTimestamp
584ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // happen only on the AudioFlinger mixer thread which owns this particular
585ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // output stream, so there is no need to worry that there will be two
586ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // threads in this instance method concurrently.
587ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //
588ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // In addition, only calls to write change the contents of the mPhysOutputs
589ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // collection (during the call to updateTargetOutputs).  updateTargetOutputs
590ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // will hold the routing lock during the operation, as should any reader of
591ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // mPhysOutputs, unless the reader is a call to write or
592ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // getNextWriteTimestamp (we know that it is safe for write and gnwt to read
593ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // the collection because the only collection mutator is the same thread
594ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // which calls write and gnwt).
595ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    updateTargetOutputs();
596ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
597ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // If any of our outputs is in the PRIMED state when ::write is called, it
598ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // means one of two things.  First, it could be that the DMA output really
599ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // has not started yet.  This is odd, but certainly not impossible.  The
600ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // other possibility is that AudioFlinger is in its silence-pushing mode and
601ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // is not calling getNextWriteTimestamp.  After an output is primed, its in
602ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // GNWTS where the amt of padding to compensate for different DMA start
603ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // times is taken into account.  Go ahead and force a call to GNWTS, just to
604ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // be certain that we have checked recently and are not stuck in silence
605ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // fill mode.  Failure to do this will cause the AudioOutput state machine
606ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // to eventually give up on DMA starting and reset the output over and over
607ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // again (spamming the log and producing general confusion).
608ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //
609ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // While we are in the process of checking our various output states, check
610ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // to see if any outputs have made it to the ACTIVE state.  Pass this
611ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // information along to the call to processOneChunk.  If any of our outputs
612ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // are waiting to be primed while other outputs have made it to steady
613ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // state, we need to change our priming behavior slightly.  Instead of
614ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // filling an output's buffer completely, we want to fill it to slightly
615ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // less than full and let the adjustDelay mechanism take care of the rest.
616ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    //
617ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Failure to do this during steady state operation will almost certainly
618ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // lead to the new output being over-filled relative to the other outputs
619ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // causing it to be slightly out of sync.
620ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    AudioOutputList::iterator I;
621ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    bool checkDMAStart = false;
622ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    bool hasActiveOutputs = false;
623ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    for (I = mPhysOutputs.begin(); I != mPhysOutputs.end(); ++I) {
624ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        if (AudioOutput::PRIMED == (*I)->getState())
625ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            checkDMAStart = true;
626ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
627ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        if ((*I)->getState() == AudioOutput::ACTIVE)
628ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            hasActiveOutputs = true;
629ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
630ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
631ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (checkDMAStart) {
632ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        int64_t junk;
633ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        getNextWriteTimestamp_internal(&junk);
634ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
635ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
636ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // We always call processOneChunk on the outputs, as it is the
637ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // tick for their state machines.
638ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    for (I = mPhysOutputs.begin(); I != mPhysOutputs.end(); ++I) {
639ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        (*I)->processOneChunk((uint8_t *)buffer, bytes, hasActiveOutputs);
640ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
641ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
642ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // If we don't actually have any physical outputs to write to, just sleep
643ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // for the proper amt of time in order to simulate the throttle that writing
644ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // to the hardware would impose.
645ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    finishedWriteOp(bytes / getBytesPerOutputFrame(), (0 == mPhysOutputs.size()));
646ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
647ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    return static_cast<ssize_t>(bytes);
648ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
649ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
650ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenstatus_t AudioStreamOut::getNextWriteTimestamp(int64_t *timestamp)
651ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
652ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    return getNextWriteTimestamp_internal(timestamp);
653ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
654ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
655ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenstatus_t AudioStreamOut::getNextWriteTimestamp_internal(
656ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        int64_t *timestamp)
657ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
658ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    int64_t max_time = LLONG_MIN;
659ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    bool    max_time_valid = false;
660ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    bool    need_adjust = false;
661ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
662ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Across all of our physical outputs, figure out the max time when
663ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // a write operation will hit the speakers.  Assume that if an
664ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // output cannot answer the question, its because it has never
665ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // started or because it has recently underflowed and needs to be
666ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // restarted.  If this is the case, we will need to prime the
667ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // pipeline with a chunk's worth of data before proceeding.
668ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // If any of the outputs indicate a discontinuity (meaning that the
669ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // DMA start time was valid and is now invalid, or was and is valid
670ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // but was different from before; almost certainly caused by a low
671ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // level underfow), then just stop now.  We will need to reset and
672ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // re-prime all of the outputs in order to make certain that the
673ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // lead-times on all of the outputs match.
674ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
675ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    AudioOutputList::iterator I;
676ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    bool discon = false;
677ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
678ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Find the largest next write timestamp. The goal is to make EVERY
679ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // output have the same value, but we also need this to pass back
680ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // up the layers.
681ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    for (I = mPhysOutputs.begin(); I != mPhysOutputs.end(); ++I) {
682ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        int64_t tmp;
683ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        if (OK == (*I)->getNextWriteTimestamp(&tmp, &discon)) {
684ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            if (!max_time_valid || (max_time < tmp)) {
685ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                max_time = tmp;
686ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen                max_time_valid = true;
687ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            }
688ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        }
689ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
690ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
691ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Check the state of each output and determine if we need to align them.
692ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Make sure to do this after we have called each outputs'
693ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // getNextWriteTimestamp as the transition from PRIMED to DMA_START happens
694ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // there.
695ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    for (I = mPhysOutputs.begin(); I != mPhysOutputs.end(); ++I) {
696ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        if ((*I)->getState() == AudioOutput::DMA_START) {
697ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            need_adjust = true;
698ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen            break;
699ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        }
700ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
701ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
702ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // At this point, if we still have not found at least one output
703ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // who knows when their data is going to hit the speakers, then we
704ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // just can't answer the getNextWriteTimestamp question and we
705ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // should give up.
706ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (!max_time_valid) {
707ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        return INVALID_OPERATION;
708ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    }
709ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
710ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // Stuff silence into the non-aligned outputs so that the effective
711ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // timestamp is the same for all the outputs.
712ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    if (need_adjust)
713ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        adjustOutputs(max_time);
714ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
715ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // We are done. The time at which the next written audio should
716ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // hit the speakers is just max_time plus the maximum amt of delay
717ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    // compensation in the system.
718ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    *timestamp = max_time;
719ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    return OK;
720ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
721ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
722ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#define DUMP(a...) \
723ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    snprintf(buffer, SIZE, a); \
724ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    buffer[SIZE - 1] = 0; \
725ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    result.append(buffer);
726ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#define B2STR(b) b ? "true" : "false"
727ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
728ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chenstatus_t AudioStreamOut::dump(int fd)
729ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen{
730ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    const size_t SIZE = 256;
731ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    char buffer[SIZE];
732ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    String8 result;
733ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    DUMP("\n%s AudioStreamOut::dump\n", getName());
734ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    DUMP("\tsample rate            : %d\n", sampleRate());
735ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    DUMP("\tbuffer size            : %d\n", bufferSize());
736ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    DUMP("\tchannel mask           : 0x%04x\n", chanMask());
737ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    DUMP("\tformat                 : %d\n", format());
738ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    DUMP("\tdevice mask            : 0x%04x\n", mTgtDevices);
739ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
740ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mRoutingLock.lock();
741ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    AudioOutputList outSnapshot(mPhysOutputs);
742ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    mRoutingLock.unlock();
743ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
744ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    AudioOutputList::iterator I;
745ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    for (I = outSnapshot.begin(); I != outSnapshot.end(); ++I)
746ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen        (*I)->dump(result);
747ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
748ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    ::write(fd, result.string(), result.size());
749ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
750ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen    return NO_ERROR;
751ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}
752ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
753ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#undef B2STR
754ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen#undef DUMP
755ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen
756ae089528c7e3a8107be65657e52276dd068c1039Mike J. Chen}  // android
757