diff options
-rw-r--r-- | include/hardware/audio.h | 8 | ||||
-rw-r--r-- | include/hardware/tv_input.h | 49 | ||||
-rw-r--r-- | modules/audio_remote_submix/audio_hw.cpp | 42 |
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); |