Add defines and support for audio offload

- Add non-blocking write support, set_callback() function
- Add pause, resume, flush, drain functions to audio output stream
- Add audio parameter defines for compressed audio metadata
- Extend audio_config_t to include an audio_offload_info_t field
- Add is_offload_supported() function to test whether there is
    hardware decode support for a given compressed audio format
- Change audio_stream_frame_size() to handle offloaded streams.
    For an offloaded stream the size is always counted in bytes
    (frame size == 1) and the number of channels is irrelevant.

Change-Id: I5b82c3fdcfa1456502d0042888f166bf02d8d54b
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: Eric Laurent <elaurent@google.com>
This commit is contained in:
Richard Fitzgerald
2013-03-25 16:11:44 +00:00
committed by Eric Laurent
parent 6a96df3b33
commit f37f187bba
2 changed files with 112 additions and 13 deletions

View File

@@ -67,6 +67,7 @@ __BEGIN_DECLS
#define AUDIO_HARDWARE_MODULE_ID_A2DP "a2dp" #define AUDIO_HARDWARE_MODULE_ID_A2DP "a2dp"
#define AUDIO_HARDWARE_MODULE_ID_USB "usb" #define AUDIO_HARDWARE_MODULE_ID_USB "usb"
#define AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX "r_submix" #define AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX "r_submix"
#define AUDIO_HARDWARE_MODULE_ID_CODEC_OFFLOAD "codec_offload"
/**************************************/ /**************************************/
@@ -117,16 +118,35 @@ __BEGIN_DECLS
* "sup_sampling_rates=44100|48000" */ * "sup_sampling_rates=44100|48000" */
#define AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES "sup_sampling_rates" #define AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES "sup_sampling_rates"
/**
* audio codec parameters
*/
#define AUDIO_OFFLOAD_CODEC_PARAMS "music_offload_codec_param"
#define AUDIO_OFFLOAD_CODEC_BIT_PER_SAMPLE "music_offload_bit_per_sample"
#define AUDIO_OFFLOAD_CODEC_BIT_RATE "music_offload_bit_rate"
#define AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE "music_offload_avg_bit_rate"
#define AUDIO_OFFLOAD_CODEC_ID "music_offload_codec_id"
#define AUDIO_OFFLOAD_CODEC_BLOCK_ALIGN "music_offload_block_align"
#define AUDIO_OFFLOAD_CODEC_SAMPLE_RATE "music_offload_sample_rate"
#define AUDIO_OFFLOAD_CODEC_ENCODE_OPTION "music_offload_encode_option"
#define AUDIO_OFFLOAD_CODEC_NUM_CHANNEL "music_offload_num_channels"
#define AUDIO_OFFLOAD_CODEC_DOWN_SAMPLING "music_offload_down_sampling"
#define AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES "delay_samples"
#define AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES "padding_samples"
/**************************************/ /**************************************/
/* common audio stream configuration parameters */ /* common audio stream configuration parameters
* You should memset() the entire structure to zero before use to
* ensure forward compatibility
*/
struct audio_config { struct audio_config {
uint32_t sample_rate; uint32_t sample_rate;
audio_channel_mask_t channel_mask; audio_channel_mask_t channel_mask;
audio_format_t format; audio_format_t format;
audio_offload_info_t offload_info;
}; };
typedef struct audio_config audio_config_t; typedef struct audio_config audio_config_t;
/* common audio stream parameters and operations */ /* common audio stream parameters and operations */
@@ -213,6 +233,22 @@ struct audio_stream {
}; };
typedef struct audio_stream audio_stream_t; typedef struct audio_stream audio_stream_t;
/* type of asynchronous write callback events. Mutually exclusive */
typedef enum {
STREAM_CBK_EVENT_WRITE_READY, /* non blocking write completed */
STREAM_CBK_EVENT_DRAIN_READY /* drain completed */
} stream_callback_event_t;
typedef int (*stream_callback_t)(stream_callback_event_t event, void *param, void *cookie);
/* type of drain requested to audio_stream_out->drain(). Mutually exclusive */
typedef enum {
AUDIO_DRAIN_ALL, /* drain() returns when all data has been played */
AUDIO_DRAIN_EARLY_NOTIFY /* drain() returns a short time before all data
from the current track has been played to
give time for gapless track switch */
} audio_drain_type_t;
/** /**
* audio_stream_out is the abstraction interface for the audio output hardware. * audio_stream_out is the abstraction interface for the audio output hardware.
* *
@@ -242,6 +278,13 @@ struct audio_stream_out {
* negative status_t. If at least one frame was written successfully prior to the error, * negative status_t. If at least one frame was written successfully prior to the error,
* it is suggested that the driver return that successful (short) byte count * it is suggested that the driver return that successful (short) byte count
* and then return an error in the subsequent call. * and then return an error in the subsequent call.
*
* If set_callback() has previously been called to enable non-blocking mode
* the write() is not allowed to block. It must write only the number of
* bytes that currently fit in the driver/hardware buffer and then return
* this byte count. If this is less than the requested write size the
* callback function must be called when more space is available in the
* driver/hardware buffer.
*/ */
ssize_t (*write)(struct audio_stream_out *stream, const void* buffer, ssize_t (*write)(struct audio_stream_out *stream, const void* buffer,
size_t bytes); size_t bytes);
@@ -259,6 +302,60 @@ struct audio_stream_out {
int (*get_next_write_timestamp)(const struct audio_stream_out *stream, int (*get_next_write_timestamp)(const struct audio_stream_out *stream,
int64_t *timestamp); int64_t *timestamp);
/**
* set the callback function 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.
*/
int (*set_callback)(struct audio_stream_out *stream,
stream_callback_t callback, void *cookie);
/**
* 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 should be implemented for hardware with non-trivial
* latency. In the pause state audio hardware could still be using power. User may
* consider calling suspend after a timeout.
*
* Implementation of this function is mandatory for offloaded playback.
*/
int (*pause)(struct audio_stream_out* stream);
/**
* Notifies to the audio driver to resume playback following a pause.
* Returns error if called without matching pause.
*
* Implementation of this function is mandatory for offloaded playback.
*/
int (*resume)(struct audio_stream_out* stream);
/**
* Requests notification when data buffered by the driver/hardware has
* been played. If set_callback() has previously been called to enable
* non-blocking mode, the drain() must not block, instead it should return
* quickly and completion of the drain is notified through the callback.
* If set_callback() has not been called, the drain() must block until
* completion.
* If type==AUDIO_DRAIN_ALL, the drain completes when all previously written
* data has been played.
* If type==AUDIO_DRAIN_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() call
*
* Implementation of this function is mandatory for offloaded playback.
*/
int (*drain)(struct audio_stream_out* stream, audio_drain_type_t type );
/**
* 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.
*/
int (*flush)(struct audio_stream_out* stream);
}; };
typedef struct audio_stream_out audio_stream_out_t; typedef struct audio_stream_out audio_stream_out_t;
@@ -296,18 +393,14 @@ typedef struct audio_stream_in audio_stream_in_t;
static inline size_t audio_stream_frame_size(const struct audio_stream *s) static inline size_t audio_stream_frame_size(const struct audio_stream *s)
{ {
size_t chan_samp_sz; size_t chan_samp_sz;
audio_format_t format = s->get_format(s);
switch (s->get_format(s)) { if (audio_is_linear_pcm(format)) {
case AUDIO_FORMAT_PCM_16_BIT: chan_samp_sz = audio_bytes_per_sample(format);
chan_samp_sz = sizeof(int16_t); return popcount(s->get_channels(s)) * chan_samp_sz;
break;
case AUDIO_FORMAT_PCM_8_BIT:
default:
chan_samp_sz = sizeof(int8_t);
break;
} }
return popcount(s->get_channels(s)) * chan_samp_sz; return sizeof(int8_t);
} }

View File

@@ -133,7 +133,8 @@ struct audio_policy {
uint32_t samplingRate, uint32_t samplingRate,
audio_format_t format, audio_format_t format,
audio_channel_mask_t channelMask, audio_channel_mask_t channelMask,
audio_output_flags_t flags); audio_output_flags_t flags,
const audio_offload_info_t *offloadInfo);
/* indicates to the audio policy manager that the output starts being used /* indicates to the audio policy manager that the output starts being used
* by corresponding stream. */ * by corresponding stream. */
@@ -241,6 +242,10 @@ struct audio_policy {
/* dump state */ /* dump state */
int (*dump)(const struct audio_policy *pol, int fd); int (*dump)(const struct audio_policy *pol, int fd);
/* check if offload is possible for given sample rate, bitrate, duration, ... */
bool (*is_offload_supported)(const struct audio_policy *pol,
const audio_offload_info_t *info);
}; };
/* audio hw module handle used by load_hw_module(), open_output_on_module() /* audio hw module handle used by load_hw_module(), open_output_on_module()
@@ -390,7 +395,8 @@ struct audio_policy_service_ops {
audio_format_t *pFormat, audio_format_t *pFormat,
audio_channel_mask_t *pChannelMask, audio_channel_mask_t *pChannelMask,
uint32_t *pLatencyMs, uint32_t *pLatencyMs,
audio_output_flags_t flags); audio_output_flags_t flags,
const audio_offload_info_t *offloadInfo);
/* Opens an audio input on a particular HW module. /* Opens an audio input on a particular HW module.
* *