Merge remote-tracking branch 'goog/stage-aosp-master' into HEAD
am: 7b6c6ffc8d
Change-Id: I6b1c348bf0a82a6c100e3862f5e47b8e8805a99c
diff --git a/modules/camera/3_0/Metadata.cpp b/modules/camera/3_0/Metadata.cpp
index 440da5f..9b8eb1d 100644
--- a/modules/camera/3_0/Metadata.cpp
+++ b/modules/camera/3_0/Metadata.cpp
@@ -16,6 +16,8 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "Metadata"
+#include <errno.h>
+
#include <system/camera_metadata.h>
#include <log/log.h>
diff --git a/modules/camera/3_4/README.md b/modules/camera/3_4/README.md
index 73d0c13..30f36d7 100644
--- a/modules/camera/3_4/README.md
+++ b/modules/camera/3_4/README.md
@@ -28,7 +28,7 @@
Devices and cameras wishing to use this HAL must meet
the following requirements:
-* The camera must support BGR32, YUV420, and JPEG formats.
+* The camera must support RGB24, YUV420, and JPEG formats.
* The gralloc and other graphics modules used by the device must use
`HAL_PIXEL_FORMAT_RGBA_8888` as the `HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED`
@@ -146,6 +146,3 @@
* A variety of features are unimplemented: High speed capture,
flash torch mode, hotplugging/unplugging.
-* The HAL uses BGR for RGBA. Again, the HAL was designed for the Raspberry Pi
-camera, which doesn't support RGB, but RGB is a common default format for
-graphics stacks.
diff --git a/modules/camera/3_4/camera.cpp b/modules/camera/3_4/camera.cpp
index 7f42eef..0f9e378 100644
--- a/modules/camera/3_4/camera.cpp
+++ b/modules/camera/3_4/camera.cpp
@@ -455,6 +455,7 @@
__func__, mId, strerror(-res), res);
return res;
}
+ ::close(buffer->acquire_fence);
}
// Acquire fence has been waited upon.
diff --git a/modules/camera/3_4/stream_format.cpp b/modules/camera/3_4/stream_format.cpp
index c85c26b..70900ab 100644
--- a/modules/camera/3_4/stream_format.cpp
+++ b/modules/camera/3_4/stream_format.cpp
@@ -57,7 +57,7 @@
case V4L2_PIX_FMT_JPEG:
return kFormatCategoryStalling;
case V4L2_PIX_FMT_YUV420: // Fall through.
- case V4L2_PIX_FMT_BGR32:
+ case V4L2_PIX_FMT_RGB24:
return kFormatCategoryNonStalling;
default:
// Note: currently no supported RAW formats.
@@ -87,7 +87,7 @@
case V4L2_PIX_FMT_YUV420:
hal_pixel_format = HAL_PIXEL_FORMAT_YCbCr_420_888;
break;
- case V4L2_PIX_FMT_BGR32:
+ case V4L2_PIX_FMT_RGB24:
hal_pixel_format = HAL_PIXEL_FORMAT_RGBA_8888;
break;
default:
@@ -106,7 +106,7 @@
case HAL_PIXEL_FORMAT_RGBA_8888:
// Should be RGB32, but RPi doesn't support that.
// For now we accept that the colors will be off.
- v4l2_pixel_format = V4L2_PIX_FMT_BGR32;
+ v4l2_pixel_format = V4L2_PIX_FMT_RGB24;
break;
case HAL_PIXEL_FORMAT_YCbCr_420_888:
v4l2_pixel_format = V4L2_PIX_FMT_YUV420;
diff --git a/modules/camera/3_4/v4l2_camera.cpp b/modules/camera/3_4/v4l2_camera.cpp
index 3e5b859..2bc0c9f 100644
--- a/modules/camera/3_4/v4l2_camera.cpp
+++ b/modules/camera/3_4/v4l2_camera.cpp
@@ -295,32 +295,36 @@
bool V4L2Camera::dequeueRequestBuffers() {
// Dequeue a buffer.
uint32_t result_index;
- int res = device_->DequeueBuffer(&result_index);
- if (res) {
- if (res == -EAGAIN) {
- // EAGAIN just means nothing to dequeue right now.
- // Wait until something is available before looping again.
- std::unique_lock<std::mutex> lock(in_flight_lock_);
- while (in_flight_.empty()) {
- buffers_in_flight_.wait(lock);
+ int res;
+
+ {
+ std::lock_guard<std::mutex> guard(in_flight_lock_);
+ res = device_->DequeueBuffer(&result_index);
+ if (!res) {
+ // Find the associated request and complete it.
+ auto index_request = in_flight_.find(result_index);
+ if (index_request != in_flight_.end()) {
+ completeRequest(index_request->second, 0);
+ in_flight_.erase(index_request);
+ } else {
+ HAL_LOGW(
+ "Dequeued non in-flight buffer index %d. "
+ "This buffer may have been flushed from the HAL but not the device.",
+ index_request->first);
}
- } else {
- HAL_LOGW("Device failed to dequeue buffer: %d", res);
+ return true;
}
- return true;
}
- // Find the associated request and complete it.
- std::lock_guard<std::mutex> guard(in_flight_lock_);
- auto index_request = in_flight_.find(result_index);
- if (index_request != in_flight_.end()) {
- completeRequest(index_request->second, 0);
- in_flight_.erase(index_request);
+ if (res == -EAGAIN) {
+ // EAGAIN just means nothing to dequeue right now.
+ // Wait until something is available before looping again.
+ std::unique_lock<std::mutex> lock(in_flight_lock_);
+ while (in_flight_.empty()) {
+ buffers_in_flight_.wait(lock);
+ }
} else {
- HAL_LOGW(
- "Dequeued non in-flight buffer index %d. "
- "This buffer may have been flushed from the HAL but not the device.",
- index_request->first);
+ HAL_LOGW("Device failed to dequeue buffer: %d", res);
}
return true;
}
diff --git a/modules/camera/3_4/v4l2_gralloc.cpp b/modules/camera/3_4/v4l2_gralloc.cpp
index 7da3c4e..2fcef35 100644
--- a/modules/camera/3_4/v4l2_gralloc.cpp
+++ b/modules/camera/3_4/v4l2_gralloc.cpp
@@ -146,6 +146,7 @@
return ret;
}
break;
+ case V4L2_PIX_FMT_RGB24: // Fall-through.
case V4L2_PIX_FMT_BGR32: // Fall-through.
case V4L2_PIX_FMT_RGB32:
// RGB formats have nice agreed upon representation. Unless using android
@@ -204,6 +205,19 @@
const camera3_stream_buffer_t* camera_buffer = buffer_data->camera_buffer;
const buffer_handle_t buffer = *camera_buffer->buffer;
+ if (StreamFormat::HalToV4L2PixelFormat(camera_buffer->stream->format) == V4L2_PIX_FMT_RGB24) {
+ // Convert RGB24 to RGB32.
+ size_t rgb_size = camera_buffer->stream->width * camera_buffer->stream->height;
+ uint8_t* tail_rgb24 = (uint8_t*)data + 3 * rgb_size - 1;
+ uint8_t* tail_rgb32 = (uint8_t*)data + 4 * rgb_size - 1;
+ for (int i = 0; i < rgb_size; i++) {
+ *(tail_rgb32--) = 0xff;
+ *(tail_rgb32--) = *(tail_rgb24--);
+ *(tail_rgb32--) = *(tail_rgb24--);
+ *(tail_rgb32--) = *(tail_rgb24--);
+ }
+ }
+
// Check for transform.
if (buffer_data->transform_dest) {
HAL_LOGV("Transforming V4L2 YUV to gralloc YUV.");
diff --git a/modules/camera/3_4/v4l2_wrapper.cpp b/modules/camera/3_4/v4l2_wrapper.cpp
index 3fafffd..b5a1c71 100644
--- a/modules/camera/3_4/v4l2_wrapper.cpp
+++ b/modules/camera/3_4/v4l2_wrapper.cpp
@@ -535,6 +535,7 @@
std::lock_guard<std::mutex> guard(buffer_queue_lock_);
for (int i = 0; i < buffers_.size(); ++i) {
if (!buffers_[i]) {
+ buffers_[i] = true;
index = i;
break;
}
@@ -557,6 +558,9 @@
// and fill out remaining fields.
if (IoctlLocked(VIDIOC_QUERYBUF, &device_buffer) < 0) {
HAL_LOGE("QUERYBUF fails: %s", strerror(errno));
+ // Return buffer index.
+ std::lock_guard<std::mutex> guard(buffer_queue_lock_);
+ buffers_[index] = false;
return -ENODEV;
}
@@ -565,18 +569,20 @@
gralloc_->lock(camera_buffer, format_->bytes_per_line(), &device_buffer);
if (res) {
HAL_LOGE("Gralloc failed to lock buffer.");
+ // Return buffer index.
+ std::lock_guard<std::mutex> guard(buffer_queue_lock_);
+ buffers_[index] = false;
return res;
}
if (IoctlLocked(VIDIOC_QBUF, &device_buffer) < 0) {
HAL_LOGE("QBUF fails: %s", strerror(errno));
gralloc_->unlock(&device_buffer);
+ // Return buffer index.
+ std::lock_guard<std::mutex> guard(buffer_queue_lock_);
+ buffers_[index] = false;
return -ENODEV;
}
- // Mark the buffer as in flight.
- std::lock_guard<std::mutex> guard(buffer_queue_lock_);
- buffers_[index] = true;
-
if (enqueued_index) {
*enqueued_index = index;
}
diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c
index e93396f..43d1daf 100644
--- a/modules/usbaudio/audio_hal.c
+++ b/modules/usbaudio/audio_hal.c
@@ -69,6 +69,8 @@
bool mic_muted;
bool standby;
+
+ int32_t inputs_open; /* number of input streams currently open. */
};
struct stream_lock {
@@ -85,7 +87,12 @@
struct audio_device *adev; /* hardware information - only using this for the lock */
- alsa_device_profile * profile; /* Points to the alsa_device_profile in the audio_device */
+ const alsa_device_profile *profile; /* Points to the alsa_device_profile in the audio_device.
+ * Const, so modifications go through adev->out_profile
+ * and thus should have the hardware lock and ensure
+ * stream is not active and no other open output streams.
+ */
+
alsa_device_proxy proxy; /* state of the stream */
unsigned hal_channel_count; /* channel count exposed to AudioFlinger.
@@ -116,7 +123,12 @@
struct audio_device *adev; /* hardware information - only using this for the lock */
- alsa_device_profile * profile; /* Points to the alsa_device_profile in the audio_device */
+ const alsa_device_profile *profile; /* Points to the alsa_device_profile in the audio_device.
+ * Const, so modifications go through adev->out_profile
+ * and thus should have the hardware lock and ensure
+ * stream is not active and no other open input streams.
+ */
+
alsa_device_proxy proxy; /* state of the stream */
unsigned hal_channel_count; /* channel count exposed to AudioFlinger.
@@ -232,7 +244,7 @@
return *card >= 0 && *device >= 0;
}
-static char * device_get_parameters(alsa_device_profile * profile, const char * keys)
+static char *device_get_parameters(const alsa_device_profile *profile, const char * keys)
{
if (profile->card < 0 || profile->device < 0) {
return strdup("");
@@ -384,12 +396,12 @@
else {
int saved_card = out->profile->card;
int saved_device = out->profile->device;
- out->profile->card = card;
- out->profile->device = device;
- ret_value = profile_read_device_info(out->profile) ? 0 : -EINVAL;
+ out->adev->out_profile.card = card;
+ out->adev->out_profile.device = device;
+ ret_value = profile_read_device_info(&out->adev->out_profile) ? 0 : -EINVAL;
if (ret_value != 0) {
- out->profile->card = saved_card;
- out->profile->device = saved_device;
+ out->adev->out_profile.card = saved_card;
+ out->adev->out_profile.device = saved_device;
}
}
}
@@ -572,9 +584,9 @@
memset(&proxy_config, 0, sizeof(proxy_config));
/* Pull out the card/device pair */
- parse_card_device_params(address, &(out->profile->card), &(out->profile->device));
+ parse_card_device_params(address, &out->adev->out_profile.card, &out->adev->out_profile.device);
- profile_read_device_info(out->profile);
+ profile_read_device_info(&out->adev->out_profile);
int ret = 0;
@@ -787,18 +799,18 @@
device_lock(in->adev);
if (card >= 0 && device >= 0 && !profile_is_cached_for(in->profile, card, device)) {
- /* cannot read pcm device info if playback is active */
- if (!in->standby)
+ /* cannot read pcm device info if playback is active, or more than one open stream */
+ if (!in->standby || in->adev->inputs_open > 1)
ret_value = -ENOSYS;
else {
int saved_card = in->profile->card;
int saved_device = in->profile->device;
- in->profile->card = card;
- in->profile->device = device;
- ret_value = profile_read_device_info(in->profile) ? 0 : -EINVAL;
+ in->adev->in_profile.card = card;
+ in->adev->in_profile.device = device;
+ ret_value = profile_read_device_info(&in->adev->in_profile) ? 0 : -EINVAL;
if (ret_value != 0) {
- in->profile->card = saved_card;
- in->profile->device = saved_device;
+ in->adev->in_profile.card = saved_card;
+ in->adev->in_profile.device = saved_device;
}
}
}
@@ -868,7 +880,7 @@
in->standby = false;
}
- alsa_device_profile * profile = in->profile;
+ const alsa_device_profile *profile = in->profile;
/*
* OK, we need to figure out how much data to read to be able to output the requested
@@ -940,10 +952,17 @@
ALOGV("adev_open_input_stream() rate:%" PRIu32 ", chanMask:0x%" PRIX32 ", fmt:%" PRIu8,
config->sample_rate, config->channel_mask, config->format);
- struct stream_in *in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
- int ret = 0;
+ /* Pull out the card/device pair */
+ int32_t card, device;
+ if (!parse_card_device_params(address, &card, &device)) {
+ ALOGW("%s fail - invalid address %s", __func__, address);
+ *stream_in = NULL;
+ return -EINVAL;
+ }
+ struct stream_in * const in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
if (in == NULL) {
+ *stream_in = NULL;
return -ENOMEM;
}
@@ -975,10 +994,29 @@
struct pcm_config proxy_config;
memset(&proxy_config, 0, sizeof(proxy_config));
- /* Pull out the card/device pair */
- parse_card_device_params(address, &(in->profile->card), &(in->profile->device));
-
- profile_read_device_info(in->profile);
+ int ret = 0;
+ /* Check if an input stream is already open */
+ if (in->adev->inputs_open > 0) {
+ if (!profile_is_cached_for(in->profile, card, device)) {
+ ALOGW("%s fail - address card:%d device:%d doesn't match existing profile",
+ __func__, card, device);
+ ret = -EINVAL;
+ }
+ } else {
+ /* Read input profile only if necessary */
+ in->adev->in_profile.card = card;
+ in->adev->in_profile.device = device;
+ if (!profile_read_device_info(&in->adev->in_profile)) {
+ ALOGW("%s fail - cannot read profile", __func__);
+ ret = -EINVAL;
+ }
+ }
+ if (ret != 0) {
+ device_unlock(in->adev);
+ free(in);
+ *stream_in = NULL;
+ return ret;
+ }
/* Rate */
if (config->sample_rate == 0) {
@@ -1083,6 +1121,10 @@
free(in);
}
+ device_lock(in->adev);
+ ++in->adev->inputs_open;
+ device_unlock(in->adev);
+
return ret;
}
@@ -1094,6 +1136,12 @@
adev_remove_stream_from_list(in->adev, &in->list_node);
+ device_lock(in->adev);
+ --in->adev->inputs_open;
+ LOG_ALWAYS_FATAL_IF(in->adev->inputs_open < 0,
+ "invalid inputs_open: %d", in->adev->inputs_open);
+ device_unlock(in->adev);
+
/* Close the pcm device */
in_standby(&stream->common);
diff --git a/modules/usbcamera/Metadata.cpp b/modules/usbcamera/Metadata.cpp
index 78318f3..b0d2f93 100644
--- a/modules/usbcamera/Metadata.cpp
+++ b/modules/usbcamera/Metadata.cpp
@@ -17,6 +17,8 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "Metadata"
+#include <errno.h>
+
#include <log/log.h>
#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)