[libcamera-devel] [PATCH 4/4] v4l2: camera_proxy: Create format info array
Kieran Bingham
kieran.bingham at ideasonboard.com
Mon Jan 6 17:59:56 CET 2020
Hi Laurent,
On 06/01/2020 16:53, Laurent Pinchart wrote:
> Hi Kieran,
>
> On Mon, Jan 06, 2020 at 04:48:42PM +0000, Kieran Bingham wrote:
>> On 06/01/2020 16:14, Laurent Pinchart wrote:
>>> Create a PixelFormatInfo structure to store information about a format,
>>> and add a global array of format info for all the formats currently
>>> supported. Move the format helpers to use the information from the
>>> array.
>>>
>>> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
>>> ---
>>> src/v4l2/v4l2_camera_proxy.cpp | 180 +++++++++++++--------------------
>>> 1 file changed, 70 insertions(+), 110 deletions(-)
>>>
>>> diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
>>> index 6a222d702e13..b8c1a53af1c2 100644
>>> --- a/src/v4l2/v4l2_camera_proxy.cpp
>>> +++ b/src/v4l2/v4l2_camera_proxy.cpp
>>> @@ -509,134 +509,94 @@ int V4L2CameraProxy::ioctl(unsigned long request, void *arg)
>>> return ret;
>>> }
>>>
>>> +struct PixelFormatPlaneInfo {
>>> + unsigned int bitsPerPixel;
>>> + unsigned int hSubSampling;
>>> + unsigned int vSubSampling;
>>> +};
>>> +
>>> +struct PixelFormatInfo {
>>> + PixelFormat format;
>>> + uint32_t v4l2Format;
>>> + unsigned int numPlanes;
>>> + std::array<PixelFormatPlaneInfo, 3> planes;
>>> +};
>>> +
>>> +namespace {
>>> +
>>> +constexpr std::array<PixelFormatInfo, 13> pixelFormatInfo = {{
>>> + /* RGB formats. */
>>> + { DRM_FORMAT_RGB888, V4L2_PIX_FMT_BGR24, 1, {{ { 24, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} },
>>> + { DRM_FORMAT_BGR888, V4L2_PIX_FMT_RGB24, 1, {{ { 24, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} },
>>> + { DRM_FORMAT_BGRA8888, V4L2_PIX_FMT_ARGB32, 1, {{ { 32, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} },
>>> + /* YUV packed formats. */
>>> + { DRM_FORMAT_UYVY, V4L2_PIX_FMT_UYVY, 1, {{ { 16, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} },
>>> + { DRM_FORMAT_VYUY, V4L2_PIX_FMT_VYUY, 1, {{ { 16, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} },
>>> + { DRM_FORMAT_YUYV, V4L2_PIX_FMT_YUYV, 1, {{ { 16, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} },
>>> + { DRM_FORMAT_YVYU, V4L2_PIX_FMT_YVYU, 1, {{ { 16, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} },
>>> + /* YUY planar formats. */
>>> + { DRM_FORMAT_NV12, V4L2_PIX_FMT_NV12, 2, {{ { 8, 1, 1 }, { 16, 2, 2 }, { 0, 0, 0 } }} },
>>> + { DRM_FORMAT_NV21, V4L2_PIX_FMT_NV21, 2, {{ { 8, 1, 1 }, { 16, 2, 2 }, { 0, 0, 0 } }} },
>>> + { DRM_FORMAT_NV16, V4L2_PIX_FMT_NV16, 2, {{ { 8, 1, 1 }, { 16, 2, 1 }, { 0, 0, 0 } }} },
>>> + { DRM_FORMAT_NV61, V4L2_PIX_FMT_NV61, 2, {{ { 8, 1, 1 }, { 16, 2, 1 }, { 0, 0, 0 } }} },
>>> + { DRM_FORMAT_NV24, V4L2_PIX_FMT_NV24, 2, {{ { 8, 1, 1 }, { 16, 2, 1 }, { 0, 0, 0 } }} },
>>> + { DRM_FORMAT_NV42, V4L2_PIX_FMT_NV42, 2, {{ { 8, 1, 1 }, { 16, 1, 1 }, { 0, 0, 0 } }} },
>>> +}};
>>> +
>>> +} /* namespace */
>>
>> I think this table will be easier to manage, but is there anyway we can
>> keep a common table shared between the v4l2 library and libcamera?
>>
>> Actually - before that - Do we need this information in libcamera :D
>>
>> We need to identify mappings between DRM formats and V4L2 formats, but
>> perhaps we don't actually need the pixel specific data ....?
>
> We may not need all the information in libcamera, but I think it could
> still be potentially useful for pipeline handlers, depending on their
> individual needs. In any case, I believe we should move this array to
> libcamera and export it for the V4L2 compatibility layer. We should also
> create a set of helper functions to look up entries and perform
> calculations. All this isn't part of this series, but it still paves the
> way in that direction.
Sure, fine by me :-D
--
Kieran
>
>>> +
>>> /* \todo make libcamera export these */
>>> unsigned int V4L2CameraProxy::bplMultiplier(uint32_t format)
>>> {
>>> - switch (format) {
>>> - case V4L2_PIX_FMT_NV12:
>>> - case V4L2_PIX_FMT_NV21:
>>> - case V4L2_PIX_FMT_NV16:
>>> - case V4L2_PIX_FMT_NV61:
>>> - case V4L2_PIX_FMT_NV24:
>>> - case V4L2_PIX_FMT_NV42:
>>> - return 1;
>>> - case V4L2_PIX_FMT_BGR24:
>>> - case V4L2_PIX_FMT_RGB24:
>>> - return 3;
>>> - case V4L2_PIX_FMT_ARGB32:
>>> - return 4;
>>> - case V4L2_PIX_FMT_VYUY:
>>> - case V4L2_PIX_FMT_YVYU:
>>> - case V4L2_PIX_FMT_UYVY:
>>> - case V4L2_PIX_FMT_YUYV:
>>> - return 2;
>>> - default:
>>> + auto info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(),
>>> + [format](const PixelFormatInfo &info) {
>>> + return info.v4l2Format == format;
>>> + });
>>> + if (info == pixelFormatInfo.end())
>>> return 0;
>>> - };
>>> +
>>> + return info->planes[0].bitsPerPixel / 8;
>>> }
>>>
>>> unsigned int V4L2CameraProxy::imageSize(uint32_t format, unsigned int width,
>>> unsigned int height)
>>> {
>>> - switch (format) {
>>> - case V4L2_PIX_FMT_NV12:
>>> - case V4L2_PIX_FMT_NV21:
>>> - return width * height * 3 / 2;
>>> - case V4L2_PIX_FMT_NV16:
>>> - case V4L2_PIX_FMT_NV61:
>>> - return width * height * 2;
>>> - case V4L2_PIX_FMT_NV24:
>>> - case V4L2_PIX_FMT_NV42:
>>> - return width * height * 3;
>>> - case V4L2_PIX_FMT_BGR24:
>>> - case V4L2_PIX_FMT_RGB24:
>>> - return width * height * 3;
>>> - case V4L2_PIX_FMT_ARGB32:
>>> - return width * height * 4;
>>> - case V4L2_PIX_FMT_VYUY:
>>> - case V4L2_PIX_FMT_YVYU:
>>> - case V4L2_PIX_FMT_UYVY:
>>> - case V4L2_PIX_FMT_YUYV:
>>> - return width * height * 2;
>>> - default:
>>> + auto info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(),
>>> + [format](const PixelFormatInfo &info) {
>>> + return info.v4l2Format == format;
>>> + });
>>> + if (info == pixelFormatInfo.end())
>>> return 0;
>>> - };
>>> +
>>> + unsigned int multiplier = 0;
>>> + for (unsigned int i = 0; i < info->numPlanes; ++i)
>>> + multiplier += info->planes[i].bitsPerPixel
>>> + / info->planes[i].hSubSampling
>>> + / info->planes[i].vSubSampling;
>>> +
>>> + return width * height * multiplier / 8;
>>> }
>>>
>>> PixelFormat V4L2CameraProxy::v4l2ToDrm(uint32_t format)
>>> {
>>> - switch (format) {
>>> - /* RGB formats. */
>>> - case V4L2_PIX_FMT_RGB24:
>>> - return DRM_FORMAT_BGR888;
>>> - case V4L2_PIX_FMT_BGR24:
>>> - return DRM_FORMAT_RGB888;
>>> - case V4L2_PIX_FMT_ARGB32:
>>> - return DRM_FORMAT_BGRA8888;
>>> -
>>> - /* YUV packed formats. */
>>> - case V4L2_PIX_FMT_YUYV:
>>> - return DRM_FORMAT_YUYV;
>>> - case V4L2_PIX_FMT_YVYU:
>>> - return DRM_FORMAT_YVYU;
>>> - case V4L2_PIX_FMT_UYVY:
>>> - return DRM_FORMAT_UYVY;
>>> - case V4L2_PIX_FMT_VYUY:
>>> - return DRM_FORMAT_VYUY;
>>> -
>>> - /* YUY planar formats. */
>>> - case V4L2_PIX_FMT_NV16:
>>> - return DRM_FORMAT_NV16;
>>> - case V4L2_PIX_FMT_NV61:
>>> - return DRM_FORMAT_NV61;
>>> - case V4L2_PIX_FMT_NV12:
>>> - return DRM_FORMAT_NV12;
>>> - case V4L2_PIX_FMT_NV21:
>>> - return DRM_FORMAT_NV21;
>>> - case V4L2_PIX_FMT_NV24:
>>> - return DRM_FORMAT_NV24;
>>> - case V4L2_PIX_FMT_NV42:
>>> - return DRM_FORMAT_NV42;
>>> - default:
>>> + auto info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(),
>>> + [format](const PixelFormatInfo &info) {
>>> + return info.v4l2Format == format;
>>> + });
>>> + if (info == pixelFormatInfo.end())
>>> return format;
>>> - };
>>> +
>>> + return info->format;
>>> }
>>>
>>> uint32_t V4L2CameraProxy::drmToV4L2(PixelFormat format)
>>> {
>>> - switch (format) {
>>> - /* RGB formats. */
>>> - case DRM_FORMAT_BGR888:
>>> - return V4L2_PIX_FMT_RGB24;
>>> - case DRM_FORMAT_RGB888:
>>> - return V4L2_PIX_FMT_BGR24;
>>> - case DRM_FORMAT_BGRA8888:
>>> - return V4L2_PIX_FMT_ARGB32;
>>> -
>>> - /* YUV packed formats. */
>>> - case DRM_FORMAT_YUYV:
>>> - return V4L2_PIX_FMT_YUYV;
>>> - case DRM_FORMAT_YVYU:
>>> - return V4L2_PIX_FMT_YVYU;
>>> - case DRM_FORMAT_UYVY:
>>> - return V4L2_PIX_FMT_UYVY;
>>> - case DRM_FORMAT_VYUY:
>>> - return V4L2_PIX_FMT_VYUY;
>>> -
>>> - /* YUY planar formats. */
>>> - case DRM_FORMAT_NV16:
>>> - return V4L2_PIX_FMT_NV16;
>>> - case DRM_FORMAT_NV61:
>>> - return V4L2_PIX_FMT_NV61;
>>> - case DRM_FORMAT_NV12:
>>> - return V4L2_PIX_FMT_NV12;
>>> - case DRM_FORMAT_NV21:
>>> - return V4L2_PIX_FMT_NV21;
>>> - case DRM_FORMAT_NV24:
>>> - return V4L2_PIX_FMT_NV24;
>>> - case DRM_FORMAT_NV42:
>>> - return V4L2_PIX_FMT_NV42;
>>> - default:
>>> + auto info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(),
>>> + [format](const PixelFormatInfo &info) {
>>> + return info.format == format;
>>> + });
>>> + if (info == pixelFormatInfo.end())
>>> return format;
>>> - }
>>> +
>>> + return info->v4l2Format;
>>> }
>>>
>
--
Regards
--
Kieran
More information about the libcamera-devel
mailing list