[libcamera-devel,00/12] android: Support memory backends
mbox series

Message ID 20210226132932.165484-1-jacopo@jmondi.org
Headers show
Series
  • android: Support memory backends
Related show

Message

Jacopo Mondi Feb. 26, 2021, 1:29 p.m. UTC
The Android Camera HAL need deals with frame buffers in two different ways:

- When it receives a buffer already exported as dmabuf handle that can be
  imported in the video device it wraps it in a libcamera::FrameBuffer instance
  in CameraDevice::createFrameBuffer and associates it to a libcamera::Stream
  in a libcamera::Request

- When it receives a buffer that needs to be mapped to a CPU accessible
  address for, in example, software post-processing it currently wraps it in
  a CameraDevice::MappedCamera3Buffer instance, where the buffer's dmabuf handle
  is mmapp-ed and the buffer size gets computed using lseek.

Relying on mmap and lseek to map the buffer and be able to access its content
for writing is unfortunately not enough, as the Android camera framework
allocates memory from the graphic stack and the DRM/KMS primitives have to be
used to be able to access the buffer at the right location and calculate the
size of its plane properly.

In regular Android platforms access to the buffers allocated in the graphic
stack is usually mediated by the Gralloc API which implement platform
specific support sometimes through custom API extensions (afaiu).

In ChromeOS the CameraBufferManager class implements the Gralloc API
and provide a system-wide component to be able to map/unmap memory buffers.

This series implements a CameraBuffer interface thought the PIMPL design patter
which provide a single interface towards the camera HAL with different
compile-time selected back-ends which depend on the platform in use.

The first patch introduces a combo option that allows to select the memory
backend in use. Then the MappedCamera3Buffer class is moved outside of
CameraDevice and renamed it in CameraBuffer. The PIMPL design pattern is
introduced by implementing a 'generic android' memory backend which implements
the current mmap+lseek. At the end of the series a ChromeOS specific backend
implementation 'cros_cbm' is introduced, which uses the
cros::CameraBufferManager class to register and map the frame buffers.

Currently the memory backend is only used for post-processing. It is not clear
to me yet if it should be used for intermediate buffer allocation, image
format translation and other operations.

Tested by

- JPEG capture with CCA on ChromeOS
  - Works with the generic backend as it used to
  - Works with the cbm backend

- CTS android.hardware.camera2.cts.ImageReaderTest with cbm backend making sure
  the calculated buffer size is correct ( aka < maxJpegBufferSize)

- Picture capture with OpenCamera which results in a well formed picture

To be defined: the memory backend selection option can be merged with Paul's
cros=true in-review option.

Thanks
   j

Jacopo Mondi (12):
  meson: options: Add an option to select Android memory backend
  android: Introduce CameraBuffer interface
  android: Rename MappedCamera3Buffer to CameraBuffer
  android: camera_buffer: Drop 'const' from buffer_handle_t
  android: camera_device: Rename buffer fields
  android: Move buffer mapping to CameraStream
  android: camera_buffer: Implement PIMPL pattern
  android: post_processor: Use CameraBuffer API
  android: jpeg: Use maxJpegBufferSize() for compatibility
  meson: options: Introduce 'cros_cbm' memory backend
  android: Introduce cros_cbm_buffer
  android: mm: Provide helper macro for PIMPL

 meson_options.txt                         |   6 +
 src/android/camera_buffer.h               |  64 +++++++++++
 src/android/camera_device.cpp             |  51 +--------
 src/android/camera_device.h               |   6 -
 src/android/camera_stream.cpp             |  16 ++-
 src/android/camera_stream.h               |   2 +-
 src/android/jpeg/encoder.h                |   4 +-
 src/android/jpeg/encoder_libjpeg.cpp      |  19 ++--
 src/android/jpeg/encoder_libjpeg.h        |   4 +-
 src/android/jpeg/post_processor_jpeg.cpp  |  34 +++---
 src/android/jpeg/post_processor_jpeg.h    |   2 +-
 src/android/meson.build                   |   2 +
 src/android/mm/android_generic_buffer.cpp |  92 +++++++++++++++
 src/android/mm/cros_cbm.cpp               | 133 ++++++++++++++++++++++
 src/android/mm/meson.build                |   9 ++
 src/android/post_processor.h              |   4 +-
 src/android/yuv/post_processor_yuv.cpp    |  20 ++--
 src/android/yuv/post_processor_yuv.h      |   4 +-
 18 files changed, 373 insertions(+), 99 deletions(-)
 create mode 100644 src/android/camera_buffer.h
 create mode 100644 src/android/mm/android_generic_buffer.cpp
 create mode 100644 src/android/mm/cros_cbm.cpp
 create mode 100644 src/android/mm/meson.build

--
2.30.0