platform_hardware_interfaces/audio/2.0/IStreamOut.hal
Mikhail Naganov ee901e3fd8 audiohal: Fix incompatibility with legacy hal for writes
The combo call to stream_out->write + get_presentation_position
wasn't delivering the results of these calls entirely
correctly. Since the 'WriteResult' struct was lacking the field
for returning the status of the call to
'get_presentation_position', the client could erroneously update
the presentation position to bogus values if the call to the
legacy HAL had failed.

Updated IStreamOut.WriteStatus to include the missing field,
and updated the code to fill it out.

Also fixed logspam resulting from calling a stubbed
stream_in->get_capture_position.

Bug: 30222631
Test: Loopback RTT, media CTS
Change-Id: I38ac3b01beb095e176b54608e11e71ae5d5eafb6
2017-01-12 09:39:56 -08:00

235 lines
9.4 KiB
Text

/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.audio@2.0;
import android.hardware.audio.common@2.0;
import IStream;
import IStreamOutCallback;
interface IStreamOut extends IStream {
typedef android.hardware.audio@2.0::Result Result;
/*
* Return the audio hardware driver estimated latency in milliseconds.
*
* @return latencyMs latency in milliseconds.
*/
getLatency() generates (uint32_t latencyMs);
/*
* This method is used in situations where audio mixing is done in the
* hardware. This method serves as a direct interface with hardware,
* allowing to directly set the volume as apposed to via the framework.
* This method might produce multiple PCM outputs or hardware accelerated
* codecs, such as MP3 or AAC.
*
* @param left left channel attenuation, 1.0f is unity, 0.0f is zero.
* @param right right channel attenuation, 1.0f is unity, 0.0f is zero.
* @return retval operation completion status.
*/
setVolume(float left, float right) generates (Result retval);
/*
* Data structure passed back to the client via status message queue
* of 'write' operation.
*
* Possible values of 'writeRetval' field:
* - OK, write operation was successful;
* - INVALID_ARGUMENTS, stream was not configured properly;
* - INVALID_STATE, stream is in a state that doesn't allow writes.
*
* Possible values of 'presentationPositionRetval' field (must only
* be considered if 'writeRetval' field is set to 'OK'):
* - OK, presentation position retrieved successfully;
* - INVALID_ARGUMENTS, indicates that the position can't be retrieved;
* - INVALID_OPERATION, retrieving presentation position isn't supported;
*/
struct WriteStatus {
Result writeRetval;
uint64_t written;
Result presentationPositionRetval;
uint64_t frames; // presentation position
TimeSpec timeStamp; // presentation position
};
/*
* Set up required transports for passing audio buffers to the driver.
*
* The transport consists of two message queues: one is used for passing
* audio data from the client to the driver, another is used for reporting
* write operation status (amount of bytes actually written or error code),
* and the presentation position immediately after the write, see
* WriteStatus structure definition.
*
* @param frameSize the size of a single frame, in bytes.
* @param framesCount the number of frames in a buffer.
* @param threadPriority priority of the thread that performs writes.
* @return retval OK if both message queues were created successfully.
* INVALID_STATE if the method was already called.
* INVALID_ARGUMENTS if there was a problem setting up
* the queues.
* @return dataMQ a message queue used for passing audio data in the format
* specified at the stream opening.
* @return statusMQ a message queue used for passing status from the driver
* using WriteStatus structures.
*/
prepareForWriting(
uint32_t frameSize, uint32_t framesCount,
ThreadPriority threadPriority)
generates (
Result retval,
fmq_sync<uint8_t> dataMQ, fmq_sync<WriteStatus> statusMQ);
/*
* Return the number of audio frames written by the audio DSP to DAC since
* the output has exited standby.
*
* @return retval operation completion status.
* @return dspFrames number of audio frames written.
*/
getRenderPosition() generates (Result retval, uint32_t dspFrames);
/*
* Get the local time at which the next write to the audio driver will be
* presented. The units are microseconds, where the epoch is decided by the
* local audio HAL.
*
* @return retval operation completion status.
* @return timestampUs time of the next write.
*/
getNextWriteTimestamp() generates (Result retval, int64_t timestampUs);
/*
* Set the callback interface for notifying completion of non-blocking
* write and drain.
*
* Calling this function implies that all future 'write' and 'drain'
* must be non-blocking and use the callback to signal completion.
*
* 'clearCallback' method needs to be called in order to release the local
* callback proxy on the server side and thus dereference the callback
* implementation on the client side.
*
* @return retval operation completion status.
*/
setCallback(IStreamOutCallback callback) generates (Result retval);
/*
* Clears the callback previously set via 'setCallback' method.
*
* Warning: failure to call this method results in callback implementation
* on the client side being held until the HAL server termination.
*
* @return retval operation completion status: OK or NOT_SUPPORTED.
*/
clearCallback() generates (Result retval);
/*
* Returns whether HAL supports pausing and resuming of streams.
*
* @return supportsPause true if pausing is supported.
* @return supportsResume true if resume is supported.
*/
supportsPauseAndResume()
generates (bool supportsPause, bool supportsResume);
/**
* Notifies to the audio driver to stop playback however the queued buffers
* are retained by the hardware. Useful for implementing pause/resume. Empty
* implementation if not supported however must be implemented for hardware
* with non-trivial latency. In the pause state, some audio hardware may
* still be using power. Client code may consider calling 'suspend' after a
* timeout to prevent that excess power usage.
*
* Implementation of this function is mandatory for offloaded playback.
*
* @return retval operation completion status.
*/
pause() generates (Result retval);
/*
* Notifies to the audio driver to resume playback following a pause.
* Returns error INVALID_STATE if called without matching pause.
*
* Implementation of this function is mandatory for offloaded playback.
*
* @return retval operation completion status.
*/
resume() generates (Result retval);
/*
* Returns whether HAL supports draining of streams.
*
* @return supports true if draining is supported.
*/
supportsDrain() generates (bool supports);
/**
* Requests notification when data buffered by the driver/hardware has been
* played. If 'setCallback' has previously been called to enable
* non-blocking mode, then 'drain' must not block, instead it must return
* quickly and completion of the drain is notified through the callback. If
* 'setCallback' has not been called, then 'drain' must block until
* completion.
*
* If 'type' is 'ALL', the drain completes when all previously written data
* has been played.
*
* If 'type' is 'EARLY_NOTIFY', the drain completes shortly before all data
* for the current track has played to allow time for the framework to
* perform a gapless track switch.
*
* Drain must return immediately on 'stop' and 'flush' calls.
*
* Implementation of this function is mandatory for offloaded playback.
*
* @param type type of drain.
* @return retval operation completion status.
*/
drain(AudioDrain type) generates (Result retval);
/*
* Notifies to the audio driver to flush the queued data. Stream must
* already be paused before calling 'flush'.
*
* Implementation of this function is mandatory for offloaded playback.
*
* @return retval operation completion status.
*/
flush() generates (Result retval);
/*
* Return a recent count of the number of audio frames presented to an
* external observer. This excludes frames which have been written but are
* still in the pipeline. The count is not reset to zero when output enters
* standby. Also returns the value of CLOCK_MONOTONIC as of this
* presentation count. The returned count is expected to be 'recent', but
* does not need to be the most recent possible value. However, the
* associated time must correspond to whatever count is returned.
*
* Example: assume that N+M frames have been presented, where M is a 'small'
* number. Then it is permissible to return N instead of N+M, and the
* timestamp must correspond to N rather than N+M. The terms 'recent' and
* 'small' are not defined. They reflect the quality of the implementation.
*
* @return retval operation completion status.
* @return frames count of presented audio frames.
* @return timeStamp associated clock time.
*/
getPresentationPosition()
generates (Result retval, uint64_t frames, TimeSpec timeStamp);
};