Use correct gralloc flags in V4L2 Camera HAL
Also checks gralloc return results, and cleans up style.
BUG: https://b/31595935, https://b/31589070
TEST: test streaming app works
Change-Id: I4d910524ae21a7b666a1f456e2b7122a8671560f
diff --git a/modules/camera/3_4/camera.cpp b/modules/camera/3_4/camera.cpp
index 7a34af5..60b3eed 100644
--- a/modules/camera/3_4/camera.cpp
+++ b/modules/camera/3_4/camera.cpp
@@ -335,9 +335,9 @@
for (int i = 0; i < count; i++) {
uint32_t usage = 0;
if (streams[i]->isOutputType())
- usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;
+ usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
if (streams[i]->isInputType())
- usage |= GRALLOC_USAGE_HW_CAMERA_READ;
+ usage |= GRALLOC_USAGE_SW_READ_OFTEN;
streams[i]->setUsage(usage);
uint32_t max_buffers;
diff --git a/modules/camera/3_4/v4l2_gralloc.cpp b/modules/camera/3_4/v4l2_gralloc.cpp
index 64fa306..9ada128 100644
--- a/modules/camera/3_4/v4l2_gralloc.cpp
+++ b/modules/camera/3_4/v4l2_gralloc.cpp
@@ -31,8 +31,11 @@
// Copy |height| lines from |src| to |dest|,
// where |src| and |dest| may have different line lengths.
-void copyWithPadding(uint8_t* dest, const uint8_t* src, size_t dest_stride,
- size_t src_stride, size_t height) {
+void copyWithPadding(uint8_t* dest,
+ const uint8_t* src,
+ size_t dest_stride,
+ size_t src_stride,
+ size_t height) {
size_t copy_stride = dest_stride;
if (copy_stride > src_stride) {
// Adding padding, not reducing. 0 out the extra memory.
@@ -41,8 +44,8 @@
}
uint8_t* dest_line_start = dest;
const uint8_t* src_line_start = src;
- for (size_t row = 0; row < height; ++row,
- dest_line_start += dest_stride, src_line_start += src_stride) {
+ for (size_t row = 0; row < height;
+ ++row, dest_line_start += dest_stride, src_line_start += src_stride) {
memcpy(dest_line_start, src_line_start, copy_stride);
}
}
@@ -62,10 +65,11 @@
// This class only supports Gralloc v0, not Gralloc V1.
if (gralloc->common.module_api_version > GRALLOC_MODULE_API_VERSION_0_3) {
- HAL_LOGE("Invalid gralloc version %x. Only 0.3 (%x) "
- "and below are supported by this HAL.",
- gralloc->common.module_api_version,
- GRALLOC_MODULE_API_VERSION_0_3);
+ HAL_LOGE(
+ "Invalid gralloc version %x. Only 0.3 (%x) "
+ "and below are supported by this HAL.",
+ gralloc->common.module_api_version,
+ GRALLOC_MODULE_API_VERSION_0_3);
return nullptr;
}
@@ -74,8 +78,7 @@
// Private. As checked by above factory, module will be non-null
// and a supported version.
-V4L2Gralloc::V4L2Gralloc(const gralloc_module_t* module)
- : mModule(module) {
+V4L2Gralloc::V4L2Gralloc(const gralloc_module_t* module) : mModule(module) {
HAL_LOG_ENTER();
}
@@ -92,29 +95,39 @@
HAL_LOG_ENTER();
// Lock the camera buffer (varies depending on if the buffer is YUV or not).
- std::unique_ptr<BufferData> buffer_data(new BufferData {
- camera_buffer, nullptr, bytes_per_line});
+ std::unique_ptr<BufferData> buffer_data(
+ new BufferData{camera_buffer, nullptr, bytes_per_line});
buffer_handle_t buffer = *camera_buffer->buffer;
void* data;
camera3_stream_t* stream = camera_buffer->stream;
- switch(StreamFormat::HalToV4L2PixelFormat(stream->format)) {
+ int ret = 0;
+ switch (StreamFormat::HalToV4L2PixelFormat(stream->format)) {
// TODO(b/30119452): support more YCbCr formats.
case V4L2_PIX_FMT_YUV420:
android_ycbcr yuv_data;
- mModule->lock_ycbcr(mModule, buffer, stream->usage, 0, 0,
- stream->width, stream->height, &yuv_data);
+ ret = mModule->lock_ycbcr(mModule,
+ buffer,
+ stream->usage,
+ 0,
+ 0,
+ stream->width,
+ stream->height,
+ &yuv_data);
+ if (ret) {
+ HAL_LOGE("Failed to lock ycbcr buffer: %d", ret);
+ return ret;
+ }
// Check if gralloc format matches v4l2 format
// (same padding, not interleaved, contiguous).
if (yuv_data.ystride == bytes_per_line &&
- yuv_data.cstride == bytes_per_line / 2 &&
- yuv_data.chroma_step == 1 &&
+ yuv_data.cstride == bytes_per_line / 2 && yuv_data.chroma_step == 1 &&
(reinterpret_cast<uint8_t*>(yuv_data.cb) ==
reinterpret_cast<uint8_t*>(yuv_data.y) +
- (stream->height * yuv_data.ystride)) &&
+ (stream->height * yuv_data.ystride)) &&
(reinterpret_cast<uint8_t*>(yuv_data.cr) ==
reinterpret_cast<uint8_t*>(yuv_data.cb) +
- (stream->height / 2 * yuv_data.cstride))) {
+ (stream->height / 2 * yuv_data.cstride))) {
// If so, great, point to the beginning.
HAL_LOGV("V4L2 YUV matches gralloc YUV.");
data = yuv_data.y;
@@ -130,17 +143,45 @@
break;
case V4L2_PIX_FMT_JPEG:
// Jpeg buffers are just contiguous blobs; lock length * 1.
- mModule->lock(mModule, buffer, stream->usage, 0, 0, device_buffer->length, 1, &data);
+ ret = mModule->lock(mModule,
+ buffer,
+ stream->usage,
+ 0,
+ 0,
+ device_buffer->length,
+ 1,
+ &data);
+ if (ret) {
+ HAL_LOGE("Failed to lock jpeg buffer: %d", ret);
+ return ret;
+ }
break;
case V4L2_PIX_FMT_BGR32: // Fall-through.
case V4L2_PIX_FMT_RGB32:
- // RGB formats have nice agreed upon representation. Unless using android flex formats.
- mModule->lock(mModule, buffer, stream->usage, 0, 0, stream->width, stream->height, &data);
+ // RGB formats have nice agreed upon representation. Unless using android
+ // flex formats.
+ ret = mModule->lock(mModule,
+ buffer,
+ stream->usage,
+ 0,
+ 0,
+ stream->width,
+ stream->height,
+ &data);
+ if (ret) {
+ HAL_LOGE("Failed to lock RGB buffer: %d", ret);
+ return ret;
+ }
break;
default:
return -EINVAL;
}
+ if (!data) {
+ ALOGE("Gralloc lock returned null ptr");
+ return -ENODEV;
+ }
+
// Set up the device buffer.
static_assert(sizeof(unsigned long) >= sizeof(void*),
"void* must be able to fit in the v4l2_buffer m.userptr "
@@ -200,11 +241,14 @@
memcpy(yuv_data->y, data, y_len);
} else {
HAL_LOGV("Changing padding on Y plane from %u to %u.",
- bytes_per_line, yuv_data->ystride);
+ bytes_per_line,
+ yuv_data->ystride);
// Wrong padding from V4L2.
copyWithPadding(reinterpret_cast<uint8_t*>(yuv_data->y),
reinterpret_cast<uint8_t*>(data),
- yuv_data->ystride, bytes_per_line, height);
+ yuv_data->ystride,
+ bytes_per_line,
+ height);
}
// C data.
// TODO(b/30119452): These calculations assume YCbCr_420_888.
@@ -222,19 +266,25 @@
memcpy(yuv_data->cr, cr_device, c_len);
} else {
HAL_LOGV("Changing padding on C plane from %u to %u.",
- c_bytes_per_line, yuv_data->cstride);
+ c_bytes_per_line,
+ yuv_data->cstride);
// Wrong padding from V4L2.
copyWithPadding(reinterpret_cast<uint8_t*>(yuv_data->cb),
- cb_device, yuv_data->cstride,
- c_bytes_per_line, height / 2);
+ cb_device,
+ yuv_data->cstride,
+ c_bytes_per_line,
+ height / 2);
copyWithPadding(reinterpret_cast<uint8_t*>(yuv_data->cr),
- cr_device, yuv_data->cstride,
- c_bytes_per_line, height / 2);
+ cr_device,
+ yuv_data->cstride,
+ c_bytes_per_line,
+ height / 2);
}
} else {
// Desire semiplanar (cb and cr interleaved).
HAL_LOGV("Interleaving cb and cr. Padding going from %u to %u.",
- c_bytes_per_line, yuv_data->cstride);
+ c_bytes_per_line,
+ yuv_data->cstride);
uint32_t c_height = height / 2;
uint32_t c_width = camera_buffer->stream->width / 2;
// Zero out destination
@@ -244,8 +294,10 @@
// Interleaving means we need to copy the cb and cr bytes one by one.
for (size_t line = 0; line < c_height; ++line,
- cb_gralloc += yuv_data->cstride, cr_gralloc += yuv_data->cstride,
- cb_device += c_bytes_per_line, cr_device += c_bytes_per_line) {
+ cb_gralloc += yuv_data->cstride,
+ cr_gralloc += yuv_data->cstride,
+ cb_device += c_bytes_per_line,
+ cr_device += c_bytes_per_line) {
for (size_t i = 0; i < c_width; ++i) {
*(cb_gralloc + (i * step)) = *(cb_device + i);
*(cr_gralloc + (i * step)) = *(cr_device + i);
@@ -276,7 +328,7 @@
// When there is a transform to be made, the buffer returned by lock()
// is dynamically allocated (to hold the pre-transform data).
if (entry.second->transform_dest) {
- delete [] reinterpret_cast<uint8_t*>(entry.first);
+ delete[] reinterpret_cast<uint8_t*>(entry.first);
}
// The BufferData entry is always dynamically allocated in lock().
delete entry.second;
diff --git a/modules/camera/3_4/v4l2_gralloc.h b/modules/camera/3_4/v4l2_gralloc.h
index 7ece59d..82129e3 100644
--- a/modules/camera/3_4/v4l2_gralloc.h
+++ b/modules/camera/3_4/v4l2_gralloc.h
@@ -33,7 +33,7 @@
// V4L2Gralloc is a wrapper around relevant parts of a gralloc module,
// with some assistive transformations.
class V4L2Gralloc {
-public:
+ public:
// Use this method to create V4L2Gralloc objects. Functionally equivalent
// to "new V4L2Gralloc", except that it may return nullptr in case of failure.
static V4L2Gralloc* NewV4L2Gralloc();
@@ -49,7 +49,7 @@
// Release all held locks.
int unlockAllBuffers();
-private:
+ private:
// Constructor is private to allow failing on bad input.
// Use NewV4L2Gralloc instead.
V4L2Gralloc(const gralloc_module_t* module);