Refactor camera initialization support of gralloc.
Switch to a factory model so that initialization can fail when the gralloc module can't be found or isn't supported. BUG: 30140438 Change-Id: I6e0a62a207797aef96c532cff7632c1a4da8818f
This commit is contained in:
parent
24e541c925
commit
681eaa283f
5 changed files with 70 additions and 45 deletions
|
@ -47,9 +47,23 @@ static std::vector<int32_t> getMetadataKeys(
|
|||
return keys;
|
||||
}
|
||||
|
||||
V4L2Camera::V4L2Camera(int id, std::string path)
|
||||
V4L2Camera* V4L2Camera::NewV4L2Camera(int id, const std::string path) {
|
||||
HAL_LOG_ENTER();
|
||||
|
||||
std::unique_ptr<V4L2Gralloc> gralloc(V4L2Gralloc::NewV4L2Gralloc());
|
||||
if (!gralloc) {
|
||||
HAL_LOGE("Failed to initialize gralloc helper.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new V4L2Camera(id, path, std::move(gralloc));
|
||||
}
|
||||
|
||||
V4L2Camera::V4L2Camera(int id, std::string path,
|
||||
std::unique_ptr<V4L2Gralloc> gralloc)
|
||||
: default_camera_hal::Camera(id),
|
||||
mDevicePath(std::move(path)),
|
||||
mGralloc(std::move(gralloc)),
|
||||
mOutStreamType(0),
|
||||
mOutStreamFormat(0),
|
||||
mOutStreamWidth(0),
|
||||
|
@ -753,21 +767,6 @@ int V4L2Camera::initDevice() {
|
|||
HAL_LOG_ENTER();
|
||||
int res;
|
||||
|
||||
// Initialize and check the gralloc module.
|
||||
const hw_module_t* module;
|
||||
res = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
|
||||
if (res) {
|
||||
HAL_LOGE("Couldn't get gralloc module.");
|
||||
return -ENODEV;
|
||||
}
|
||||
const gralloc_module_t* gralloc =
|
||||
reinterpret_cast<const gralloc_module_t*>(module);
|
||||
mGralloc = V4L2Gralloc(gralloc);
|
||||
if (!mGralloc.isValid()) {
|
||||
HAL_LOGE("Invalid gralloc module.");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
// Templates should be set up if they haven't already been.
|
||||
if (!mTemplatesInitialized) {
|
||||
res = initTemplates();
|
||||
|
@ -800,14 +799,14 @@ int V4L2Camera::enqueueBuffer(const camera3_stream_buffer_t* camera_buffer) {
|
|||
// queue length.
|
||||
device_buffer.index = 0;
|
||||
// Lock the buffer for writing.
|
||||
int res = mGralloc.lock(camera_buffer, mOutStreamBytesPerLine,
|
||||
int res = mGralloc->lock(camera_buffer, mOutStreamBytesPerLine,
|
||||
&device_buffer);
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
if (ioctlLocked(VIDIOC_QBUF, &device_buffer) < 0) {
|
||||
HAL_LOGE("QBUF (%d) fails: %s", 0, strerror(errno));
|
||||
mGralloc.unlock(&device_buffer);
|
||||
mGralloc->unlock(&device_buffer);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -817,7 +816,7 @@ int V4L2Camera::enqueueBuffer(const camera3_stream_buffer_t* camera_buffer) {
|
|||
// turned off before another call to this function).
|
||||
res = streamOn();
|
||||
if (res) {
|
||||
mGralloc.unlock(&device_buffer);
|
||||
mGralloc->unlock(&device_buffer);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -828,11 +827,11 @@ int V4L2Camera::enqueueBuffer(const camera3_stream_buffer_t* camera_buffer) {
|
|||
v4l2_buffer result_buffer;
|
||||
res = dequeueBuffer(&result_buffer);
|
||||
if (res) {
|
||||
mGralloc.unlock(&result_buffer);
|
||||
mGralloc->unlock(&result_buffer);
|
||||
return res;
|
||||
}
|
||||
// Now that we're done painting the buffer, we can unlock it.
|
||||
res = mGralloc.unlock(&result_buffer);
|
||||
res = mGralloc->unlock(&result_buffer);
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -38,10 +38,17 @@ namespace v4l2_camera_hal {
|
|||
// metadata and logic about that device.
|
||||
class V4L2Camera : public default_camera_hal::Camera {
|
||||
public:
|
||||
V4L2Camera(int id, const std::string path);
|
||||
// Use this method to create V4L2Camera objects. Functionally equivalent
|
||||
// to "new V4L2Camera", except that it may return nullptr in case of failure.
|
||||
static V4L2Camera* NewV4L2Camera(int id, const std::string path);
|
||||
~V4L2Camera();
|
||||
|
||||
private:
|
||||
// Constructor private to allow failing on bad input.
|
||||
// Use NewV4L2Camera instead.
|
||||
V4L2Camera(int id, const std::string path,
|
||||
std::unique_ptr<V4L2Gralloc> gralloc);
|
||||
|
||||
// default_camera_hal::Camera virtual methods.
|
||||
// Connect to the device: open dev nodes, etc.
|
||||
int connect() override;
|
||||
|
@ -86,7 +93,7 @@ private:
|
|||
// The opened device fd.
|
||||
ScopedFd mDeviceFd;
|
||||
// Gralloc helper.
|
||||
V4L2Gralloc mGralloc;
|
||||
std::unique_ptr<V4L2Gralloc> mGralloc;
|
||||
// Lock protecting use of the device.
|
||||
android::Mutex mDeviceLock;
|
||||
// Wrapper around ioctl.
|
||||
|
|
|
@ -95,8 +95,12 @@ V4L2CameraHAL::V4L2CameraHAL() : mCameras(), mCallbacks(NULL) {
|
|||
bus = reinterpret_cast<char*>(cap.bus_info);
|
||||
if (buses.insert(bus).second) {
|
||||
HAL_LOGV("Found unique bus at %s.", node.c_str());
|
||||
std::unique_ptr<V4L2Camera> cam(new V4L2Camera(id++, node));
|
||||
mCameras.push_back(std::move(cam));
|
||||
std::unique_ptr<V4L2Camera> cam(V4L2Camera::NewV4L2Camera(id++, node));
|
||||
if (cam) {
|
||||
mCameras.push_back(std::move(cam));
|
||||
} else {
|
||||
HAL_LOGE("Failed to initialize camera at %s.", node.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
TEMP_FAILURE_RETRY(close(fd));
|
||||
|
|
|
@ -46,6 +46,33 @@ void copyWithPadding(uint8_t* dest, const uint8_t* src, size_t dest_stride,
|
|||
}
|
||||
}
|
||||
|
||||
V4L2Gralloc* V4L2Gralloc::NewV4L2Gralloc() {
|
||||
HAL_LOG_ENTER();
|
||||
|
||||
// Initialize and check the gralloc module.
|
||||
const hw_module_t* module = nullptr;
|
||||
int res = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
|
||||
if (res || !module) {
|
||||
HAL_LOGE("Couldn't get gralloc module.");
|
||||
return nullptr;
|
||||
}
|
||||
const gralloc_module_t* gralloc =
|
||||
reinterpret_cast<const gralloc_module_t*>(module);
|
||||
|
||||
// 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);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new V4L2Gralloc(gralloc);
|
||||
}
|
||||
|
||||
// Private. As checked by above factory, module will be non-null
|
||||
// and a supported version.
|
||||
V4L2Gralloc::V4L2Gralloc(const gralloc_module_t* module)
|
||||
: mModule(module) {
|
||||
HAL_LOG_ENTER();
|
||||
|
@ -65,21 +92,6 @@ V4L2Gralloc::~V4L2Gralloc() {
|
|||
}
|
||||
}
|
||||
|
||||
bool V4L2Gralloc::isValid() {
|
||||
HAL_LOG_ENTER();
|
||||
|
||||
// This helper only supports Gralloc v0, not Gralloc V1.
|
||||
if (mModule->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.",
|
||||
mModule->common.module_api_version,
|
||||
GRALLOC_MODULE_API_VERSION_0_3);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int V4L2Gralloc::lock(const camera3_stream_buffer_t* camera_buffer,
|
||||
uint32_t bytes_per_line,
|
||||
/*out*/ v4l2_buffer* device_buffer) {
|
||||
|
|
|
@ -34,8 +34,10 @@ static constexpr size_t V4L2_MAX_JPEG_SIZE = 3000000;
|
|||
// with some assistive transformations.
|
||||
class V4L2Gralloc {
|
||||
public:
|
||||
V4L2Gralloc(const gralloc_module_t* module = nullptr);
|
||||
~V4L2Gralloc();
|
||||
// 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();
|
||||
virtual ~V4L2Gralloc();
|
||||
|
||||
// Lock a camera buffer. Sets device buffer user pointer and length.
|
||||
int lock(const camera3_stream_buffer_t* camera_buffer,
|
||||
|
@ -45,10 +47,11 @@ public:
|
|||
// based on buffer user pointer, not the specific object).
|
||||
int unlock(const v4l2_buffer* device_buffer);
|
||||
|
||||
// Check that the module passed in to the constructor is supported.
|
||||
bool isValid();
|
||||
|
||||
private:
|
||||
// Constructor is private to allow failing on bad input.
|
||||
// Use NewV4L2Gralloc instead.
|
||||
V4L2Gralloc(const gralloc_module_t* module);
|
||||
|
||||
const gralloc_module_t* mModule;
|
||||
|
||||
struct BufferData {
|
||||
|
|
Loading…
Reference in a new issue