summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/hardware/audio.h8
-rw-r--r--include/hardware/tv_input.h49
-rw-r--r--modules/audio_remote_submix/audio_hw.cpp42
3 files changed, 84 insertions, 15 deletions
diff --git a/include/hardware/audio.h b/include/hardware/audio.h
index 763ca58..8d5b2f0 100644
--- a/include/hardware/audio.h
+++ b/include/hardware/audio.h
@@ -112,6 +112,10 @@ __BEGIN_DECLS
/* Bluetooth SCO wideband */
#define AUDIO_PARAMETER_KEY_BT_SCO_WB "bt_wbs"
+/* Get a new HW synchronization source identifier.
+ * Return a valid source (positive integer) or AUDIO_HW_SYNC_INVALID if an error occurs
+ * or no HW sync is available. */
+#define AUDIO_PARAMETER_HW_AV_SYNC "hw_av_sync"
/**
* audio stream parameters
@@ -136,9 +140,7 @@ __BEGIN_DECLS
* "sup_sampling_rates=44100|48000" */
#define AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES "sup_sampling_rates"
-/* Get the HW synchronization source used for an output stream.
- * Return a valid source (positive integer) or AUDIO_HW_SYNC_INVALID if an error occurs
- * or no HW sync source is used. */
+/* Set the HW synchronization source for an output stream. */
#define AUDIO_PARAMETER_STREAM_HW_AV_SYNC "hw_av_sync"
/**
diff --git a/include/hardware/tv_input.h b/include/hardware/tv_input.h
index a94e4ea..ed3fafb 100644
--- a/include/hardware/tv_input.h
+++ b/include/hardware/tv_input.h
@@ -110,29 +110,78 @@ typedef struct tv_input_device_info {
int32_t reserved[16];
} tv_input_device_info_t;
+/* See tv_input_event_t for more details. */
enum {
/*
* Hardware notifies the framework that a device is available.
+ *
+ * Note that DEVICE_AVAILABLE and DEVICE_UNAVAILABLE events do not represent
+ * hotplug events (i.e. plugging cable into or out of the physical port).
+ * These events notify the framework whether the port is available or not.
+ * For a concrete example, when a user plugs in or pulls out the HDMI cable
+ * from a HDMI port, it does not generate DEVICE_AVAILABLE and/or
+ * DEVICE_UNAVAILABLE events. However, if a user inserts a pluggable USB
+ * tuner into the Android device, it will generate a DEVICE_AVAILABLE event
+ * and when the port is removed, it should generate a DEVICE_UNAVAILABLE
+ * event.
+ *
+ * For hotplug events, please see STREAM_CONFIGURATION_CHANGED for more
+ * details.
+ *
+ * HAL implementation should register devices by using this event when the
+ * device boots up. The framework will recognize device reported via this
+ * event only. In addition, the implementation could use this event to
+ * notify the framework that a removable TV input device (such as USB tuner
+ * as stated in the example above) is attached.
*/
TV_INPUT_EVENT_DEVICE_AVAILABLE = 1,
/*
* Hardware notifies the framework that a device is unavailable.
+ *
+ * HAL implementation should generate this event when a device registered
+ * by TV_INPUT_EVENT_DEVICE_AVAILABLE is no longer available. For example,
+ * the event can indicate that a USB tuner is plugged out from the Android
+ * device.
+ *
+ * Note that this event is not for indicating cable plugged out of the port;
+ * for that purpose, the implementation should use
+ * STREAM_CONFIGURATION_CHANGED event. This event represents the port itself
+ * being no longer available.
*/
TV_INPUT_EVENT_DEVICE_UNAVAILABLE = 2,
/*
* Stream configurations are changed. Client should regard all open streams
* at the specific device are closed, and should call
* get_stream_configurations() again, opening some of them if necessary.
+ *
+ * HAL implementation should generate this event when the available stream
+ * configurations change for any reason. A typical use case of this event
+ * would be to notify the framework that the input signal has changed
+ * resolution, or that the cable is plugged out so that the number of
+ * available streams is 0.
+ *
+ * The implementation may use this event to indicate hotplug status of the
+ * port. the framework regards input devices with no available streams as
+ * disconnected, so the implementation can generate this event with no
+ * available streams to indicate that this device is disconnected, and vice
+ * versa.
*/
TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED = 3,
/*
* Hardware is done with capture request with the buffer. Client can assume
* ownership of the buffer again.
+ *
+ * HAL implementation should generate this event after request_capture() if
+ * it succeeded. The event shall have the buffer with the captured image.
*/
TV_INPUT_EVENT_CAPTURE_SUCCEEDED = 4,
/*
* Hardware met a failure while processing a capture request or client
* canceled the request. Client can assume ownership of the buffer again.
+ *
+ * The event is similar to TV_INPUT_EVENT_CAPTURE_SUCCEEDED, but HAL
+ * implementation generates this event upon a failure to process
+ * request_capture(), or a request cancellation.
*/
TV_INPUT_EVENT_CAPTURE_FAILED = 5,
};
diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp
index 014da8e..8fed8e4 100644
--- a/modules/audio_remote_submix/audio_hw.cpp
+++ b/modules/audio_remote_submix/audio_hw.cpp
@@ -95,6 +95,8 @@ namespace android {
// File permissions for stream log files.
#define LOG_STREAM_FILE_PERMISSIONS (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#endif // LOG_STREAMS_TO_FILES
+// limit for number of read error log entries to avoid spamming the logs
+#define MAX_READ_ERROR_LOGS 5
// Common limits macros.
#ifndef min
@@ -194,6 +196,8 @@ struct submix_stream_in {
#if LOG_STREAMS_TO_FILES
int log_fd;
#endif // LOG_STREAMS_TO_FILES
+
+ volatile int16_t read_error_count;
};
// Determine whether the specified sample rate is supported by the submix module.
@@ -350,7 +354,7 @@ static void submix_audio_device_create_pipe(struct submix_audio_device * const r
struct submix_stream_out * const out)
{
ALOG_ASSERT(in || out);
- ALOGV("submix_audio_device_create_pipe()");
+ ALOGD("submix_audio_device_create_pipe()");
pthread_mutex_lock(&rsxadev->lock);
// Save a reference to the specified input or output stream and the associated channel
// mask.
@@ -435,7 +439,7 @@ static void submix_audio_device_create_pipe(struct submix_audio_device * const r
// before they shutdown.
static void submix_audio_device_release_pipe(struct submix_audio_device * const rsxadev)
{
- ALOGV("submix_audio_device_release_pipe()");
+ ALOGD("submix_audio_device_release_pipe()");
rsxadev->rsxSink.clear();
rsxadev->rsxSource.clear();
}
@@ -463,9 +467,9 @@ static void submix_audio_device_destroy_pipe(struct submix_audio_device * const
#endif // ENABLE_LEGACY_INPUT_OPEN
}
if (out != NULL) rsxadev->output = NULL;
- if (rsxadev->input != NULL && rsxadev->output != NULL) {
+ if (rsxadev->input == NULL && rsxadev->output == NULL) {
submix_audio_device_release_pipe(rsxadev);
- ALOGV("submix_audio_device_destroy_pipe(): pipe destroyed");
+ ALOGD("submix_audio_device_destroy_pipe(): pipe destroyed");
}
pthread_mutex_unlock(&rsxadev->lock);
}
@@ -655,7 +659,7 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
return 0;
}
- ALOGI("out_set_parameters(): shutdown");
+ ALOGD("out_set_parameters(): shutting down MonoPipe sink");
sink->shutdown(true);
} // done using the sink
pthread_mutex_unlock(&rsxadev->lock);
@@ -975,7 +979,9 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
// about to read from audio source
sp<MonoPipeReader> source = rsxadev->rsxSource;
if (source == NULL) {
- ALOGE("no audio pipe yet we're trying to read!");
+ in->read_error_count++;// ok if it rolls over
+ ALOGE_IF(in->read_error_count < MAX_READ_ERROR_LOGS,
+ "no audio pipe yet we're trying to read! (not all errors will be logged)");
pthread_mutex_unlock(&rsxadev->lock);
usleep(frames_to_read * 1000000 / in_get_sample_rate(&stream->common));
memset(buffer, 0, bytes);
@@ -1192,7 +1198,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
const char *address __unused)
{
struct submix_audio_device * const rsxadev = audio_hw_device_get_submix_audio_device(dev);
- ALOGV("adev_open_output_stream()");
+ ALOGD("adev_open_output_stream()");
struct submix_stream_out *out;
bool force_pipe_creation = false;
(void)handle;
@@ -1247,7 +1253,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
// Store a pointer to the device from the output stream.
out->dev = rsxadev;
// Initialize the pipe.
- ALOGV("adev_open_output_stream(): Initializing pipe");
+ ALOGV("adev_open_output_stream(): about to create pipe");
submix_audio_device_create_pipe(rsxadev, config, DEFAULT_PIPE_SIZE_IN_FRAMES,
DEFAULT_PIPE_PERIOD_COUNT, NULL, out);
#if LOG_STREAMS_TO_FILES
@@ -1267,7 +1273,7 @@ static void adev_close_output_stream(struct audio_hw_device *dev,
struct audio_stream_out *stream)
{
struct submix_stream_out * const out = audio_stream_out_get_submix_stream_out(stream);
- ALOGV("adev_close_output_stream()");
+ ALOGD("adev_close_output_stream()");
submix_audio_device_destroy_pipe(audio_hw_device_get_submix_audio_device(dev), NULL, out);
#if LOG_STREAMS_TO_FILES
if (out->log_fd >= 0) close(out->log_fd);
@@ -1381,7 +1387,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
{
struct submix_audio_device *rsxadev = audio_hw_device_get_submix_audio_device(dev);
struct submix_stream_in *in;
- ALOGI("adev_open_input_stream()");
+ ALOGD("adev_open_input_stream()");
(void)handle;
(void)devices;
@@ -1402,7 +1408,17 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
sp<MonoPipe> sink = rsxadev->rsxSink;
ALOG_ASSERT(sink != NULL);
// If the sink has been shutdown, delete the pipe.
- if (sink->isShutdown()) submix_audio_device_release_pipe(rsxadev);
+ if (sink != NULL) {
+ if (sink->isShutdown()) {
+ ALOGD(" Non-NULL shut down sink when opening input stream, releasing, refcount=%d",
+ in->ref_count);
+ submix_audio_device_release_pipe(rsxadev);
+ } else {
+ ALOGD(" Non-NULL sink when opening input stream, refcount=%d", in->ref_count);
+ }
+ } else {
+ ALOGE("NULL sink when opening input stream, refcount=%d", in->ref_count);
+ }
}
pthread_mutex_unlock(&rsxadev->lock);
#else
@@ -1436,7 +1452,9 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
in->read_counter_frames = 0;
in->output_standby = rsxadev->output_standby;
in->dev = rsxadev;
+ in->read_error_count = 0;
// Initialize the pipe.
+ ALOGV("adev_open_input_stream(): about to create pipe");
submix_audio_device_create_pipe(rsxadev, config, DEFAULT_PIPE_SIZE_IN_FRAMES,
DEFAULT_PIPE_PERIOD_COUNT, in, NULL);
#if LOG_STREAMS_TO_FILES
@@ -1456,7 +1474,7 @@ static void adev_close_input_stream(struct audio_hw_device *dev,
struct audio_stream_in *stream)
{
struct submix_stream_in * const in = audio_stream_in_get_submix_stream_in(stream);
- ALOGV("adev_close_input_stream()");
+ ALOGD("adev_close_input_stream()");
submix_audio_device_destroy_pipe(audio_hw_device_get_submix_audio_device(dev), in, NULL);
#if LOG_STREAMS_TO_FILES
if (in->log_fd >= 0) close(in->log_fd);