Move mode types and functions to a new object (MR 13)

Rename MPCameraMode to a more generic MPMode and move it along
with related functions to a new object in preparation for using
it in the device object.
This commit is contained in:
Yassine Oudjana
2022-02-23 10:23:02 +04:00
committed by Martijn Braam
parent cd4ecdd964
commit a4c2c1ec1f
13 changed files with 381 additions and 364 deletions

View File

@@ -1,8 +1,10 @@
#include "camera.h"
#include "mode.h"
#include <assert.h>
#include <errno.h>
#include <glib.h>
#include <linux/v4l2-subdev.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
@@ -12,263 +14,6 @@
#define MAX_VIDEO_BUFFERS 20
#define MAX_BG_TASKS 8
static const char *pixel_format_names[MP_PIXEL_FMT_MAX] = {
"unsupported", "BGGR8", "GBRG8", "GRBG8", "RGGB8", "BGGR10P",
"GBRG10P", "GRBG10P", "RGGB10P", "UYVY", "YUYV",
};
const char *
mp_pixel_format_to_str(uint32_t pixel_format)
{
g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, "INVALID");
return pixel_format_names[pixel_format];
}
MPPixelFormat
mp_pixel_format_from_str(const char *name)
{
for (MPPixelFormat i = 0; i < MP_PIXEL_FMT_MAX; ++i) {
if (strcasecmp(pixel_format_names[i], name) == 0) {
return i;
}
}
g_return_val_if_reached(MP_PIXEL_FMT_UNSUPPORTED);
}
static const uint32_t pixel_format_v4l_pixel_formats[MP_PIXEL_FMT_MAX] = {
0,
V4L2_PIX_FMT_SBGGR8,
V4L2_PIX_FMT_SGBRG8,
V4L2_PIX_FMT_SGRBG8,
V4L2_PIX_FMT_SRGGB8,
V4L2_PIX_FMT_SBGGR10P,
V4L2_PIX_FMT_SGBRG10P,
V4L2_PIX_FMT_SGRBG10P,
V4L2_PIX_FMT_SRGGB10P,
V4L2_PIX_FMT_UYVY,
V4L2_PIX_FMT_YUYV,
};
uint32_t
mp_pixel_format_to_v4l_pixel_format(MPPixelFormat pixel_format)
{
g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
return pixel_format_v4l_pixel_formats[pixel_format];
}
MPPixelFormat
mp_pixel_format_from_v4l_pixel_format(uint32_t v4l_pixel_format)
{
for (MPPixelFormat i = 0; i < MP_PIXEL_FMT_MAX; ++i) {
if (pixel_format_v4l_pixel_formats[i] == v4l_pixel_format) {
return i;
}
}
return MP_PIXEL_FMT_UNSUPPORTED;
}
static const uint32_t pixel_format_v4l_bus_codes[MP_PIXEL_FMT_MAX] = {
0,
MEDIA_BUS_FMT_SBGGR8_1X8,
MEDIA_BUS_FMT_SGBRG8_1X8,
MEDIA_BUS_FMT_SGRBG8_1X8,
MEDIA_BUS_FMT_SRGGB8_1X8,
MEDIA_BUS_FMT_SBGGR10_1X10,
MEDIA_BUS_FMT_SGBRG10_1X10,
MEDIA_BUS_FMT_SGRBG10_1X10,
MEDIA_BUS_FMT_SRGGB10_1X10,
MEDIA_BUS_FMT_UYVY8_2X8,
MEDIA_BUS_FMT_YUYV8_2X8,
};
uint32_t
mp_pixel_format_to_v4l_bus_code(MPPixelFormat pixel_format)
{
g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
return pixel_format_v4l_bus_codes[pixel_format];
}
MPPixelFormat
mp_pixel_format_from_v4l_bus_code(uint32_t v4l_bus_code)
{
for (MPPixelFormat i = 0; i < MP_PIXEL_FMT_MAX; ++i) {
if (pixel_format_v4l_bus_codes[i] == v4l_bus_code) {
return i;
}
}
return MP_PIXEL_FMT_UNSUPPORTED;
}
uint32_t
mp_pixel_format_bits_per_pixel(MPPixelFormat pixel_format)
{
g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
switch (pixel_format) {
case MP_PIXEL_FMT_BGGR8:
case MP_PIXEL_FMT_GBRG8:
case MP_PIXEL_FMT_GRBG8:
case MP_PIXEL_FMT_RGGB8:
return 8;
case MP_PIXEL_FMT_BGGR10P:
case MP_PIXEL_FMT_GBRG10P:
case MP_PIXEL_FMT_GRBG10P:
case MP_PIXEL_FMT_RGGB10P:
return 10;
case MP_PIXEL_FMT_UYVY:
case MP_PIXEL_FMT_YUYV:
return 16;
default:
return 0;
}
}
uint32_t
mp_pixel_format_pixel_depth(MPPixelFormat pixel_format)
{
g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
switch (pixel_format) {
case MP_PIXEL_FMT_BGGR8:
case MP_PIXEL_FMT_GBRG8:
case MP_PIXEL_FMT_GRBG8:
case MP_PIXEL_FMT_RGGB8:
case MP_PIXEL_FMT_UYVY:
case MP_PIXEL_FMT_YUYV:
return 8;
case MP_PIXEL_FMT_GBRG10P:
case MP_PIXEL_FMT_GRBG10P:
case MP_PIXEL_FMT_RGGB10P:
case MP_PIXEL_FMT_BGGR10P:
return 10;
default:
return 0;
}
}
const char *
mp_pixel_format_cfa(MPPixelFormat pixel_format)
{
g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
switch (pixel_format) {
case MP_PIXEL_FMT_BGGR8:
case MP_PIXEL_FMT_BGGR10P:
return "BGGR";
break;
case MP_PIXEL_FMT_GBRG8:
case MP_PIXEL_FMT_GBRG10P:
return "GBRG";
break;
case MP_PIXEL_FMT_GRBG8:
case MP_PIXEL_FMT_GRBG10P:
return "GRBG";
break;
case MP_PIXEL_FMT_RGGB8:
case MP_PIXEL_FMT_RGGB10P:
return "RGGB";
break;
case MP_PIXEL_FMT_UYVY:
return "UYUV";
break;
case MP_PIXEL_FMT_YUYV:
return "YUYV";
break;
default:
return "unsupported";
}
}
const char *
mp_pixel_format_cfa_pattern(MPPixelFormat pixel_format)
{
g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
switch (pixel_format) {
case MP_PIXEL_FMT_BGGR8:
case MP_PIXEL_FMT_BGGR10P:
return "\002\001\001\000";
break;
case MP_PIXEL_FMT_GBRG8:
case MP_PIXEL_FMT_GBRG10P:
return "\001\002\000\001";
break;
case MP_PIXEL_FMT_GRBG8:
case MP_PIXEL_FMT_GRBG10P:
return "\001\000\002\001";
break;
case MP_PIXEL_FMT_RGGB8:
case MP_PIXEL_FMT_RGGB10P:
return "\000\001\001\002";
break;
default:
return NULL;
}
}
uint32_t
mp_pixel_format_width_to_bytes(MPPixelFormat pixel_format, uint32_t width)
{
uint32_t bits_per_pixel = mp_pixel_format_bits_per_pixel(pixel_format);
uint64_t bits_per_width = width * (uint64_t)bits_per_pixel;
uint64_t remainder = bits_per_width % 8;
if (remainder == 0)
return bits_per_width / 8;
return (bits_per_width + 8 - remainder) / 8;
}
uint32_t
mp_pixel_format_width_to_colors(MPPixelFormat pixel_format, uint32_t width)
{
g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
switch (pixel_format) {
case MP_PIXEL_FMT_BGGR8:
case MP_PIXEL_FMT_GBRG8:
case MP_PIXEL_FMT_GRBG8:
case MP_PIXEL_FMT_RGGB8:
return width / 2;
case MP_PIXEL_FMT_BGGR10P:
case MP_PIXEL_FMT_GBRG10P:
case MP_PIXEL_FMT_GRBG10P:
case MP_PIXEL_FMT_RGGB10P:
return width / 2 * 5;
case MP_PIXEL_FMT_UYVY:
case MP_PIXEL_FMT_YUYV:
return width;
default:
return 0;
}
}
uint32_t
mp_pixel_format_height_to_colors(MPPixelFormat pixel_format, uint32_t height)
{
g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
switch (pixel_format) {
case MP_PIXEL_FMT_BGGR8:
case MP_PIXEL_FMT_GBRG8:
case MP_PIXEL_FMT_GRBG8:
case MP_PIXEL_FMT_RGGB8:
case MP_PIXEL_FMT_BGGR10P:
case MP_PIXEL_FMT_GBRG10P:
case MP_PIXEL_FMT_GRBG10P:
case MP_PIXEL_FMT_RGGB10P:
return height / 2;
case MP_PIXEL_FMT_UYVY:
case MP_PIXEL_FMT_YUYV:
return height;
default:
return 0;
}
}
bool
mp_camera_mode_is_equivalent(const MPCameraMode *m1, const MPCameraMode *m2)
{
return m1->pixel_format == m2->pixel_format &&
m1->frame_interval.numerator == m2->frame_interval.numerator &&
m1->frame_interval.denominator == m2->frame_interval.denominator &&
m1->width == m2->width && m1->height == m2->height;
}
static void
errno_printerr(const char *s)
{
@@ -296,7 +41,7 @@ struct _MPCamera {
int subdev_fd;
bool has_set_mode;
MPCameraMode current_mode;
MPMode current_mode;
struct video_buffer buffers[MAX_VIDEO_BUFFERS];
uint32_t num_buffers;
@@ -461,7 +206,7 @@ get_buf_type(MPCamera *camera)
}
static bool
camera_mode_impl(MPCamera *camera, int request, MPCameraMode *mode)
camera_mode_impl(MPCamera *camera, int request, MPMode *mode)
{
uint32_t pixfmt = mp_pixel_format_to_v4l_pixel_format(mode->pixel_format);
struct v4l2_format fmt = {};
@@ -499,7 +244,7 @@ camera_mode_impl(MPCamera *camera, int request, MPCameraMode *mode)
}
bool
mp_camera_try_mode(MPCamera *camera, MPCameraMode *mode)
mp_camera_try_mode(MPCamera *camera, MPMode *mode)
{
if (!camera_mode_impl(camera, VIDIOC_TRY_FMT, mode)) {
errno_printerr("VIDIOC_S_FMT");
@@ -508,14 +253,14 @@ mp_camera_try_mode(MPCamera *camera, MPCameraMode *mode)
return true;
}
const MPCameraMode *
const MPMode *
mp_camera_get_mode(const MPCamera *camera)
{
return &camera->current_mode;
}
bool
mp_camera_set_mode(MPCamera *camera, MPCameraMode *mode)
mp_camera_set_mode(MPCamera *camera, MPMode *mode)
{
// Set the mode in the subdev the camera is one
if (mp_camera_is_subdev(camera)) {
@@ -843,15 +588,10 @@ mp_camera_release_buffer(MPCamera *camera, uint32_t buffer_index)
return true;
}
struct _MPCameraModeList {
MPCameraMode mode;
MPCameraModeList *next;
};
static MPCameraModeList *
get_subdev_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
static MPModeList *
get_subdev_modes(MPCamera *camera, bool (*check)(MPCamera *, MPMode *))
{
MPCameraModeList *item = NULL;
MPModeList *item = NULL;
for (uint32_t fmt_index = 0;; ++fmt_index) {
struct v4l2_subdev_mbus_code_enum fmt = {};
@@ -912,7 +652,7 @@ get_subdev_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
break;
}
MPCameraMode mode = {
MPMode mode = {
.pixel_format = format,
.frame_interval = interval.interval,
.width = frame.max_width,
@@ -923,8 +663,7 @@ get_subdev_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
continue;
}
MPCameraModeList *new_item =
malloc(sizeof(MPCameraModeList));
MPModeList *new_item = malloc(sizeof(MPModeList));
new_item->mode = mode;
new_item->next = item;
item = new_item;
@@ -935,12 +674,12 @@ get_subdev_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
return item;
}
static MPCameraModeList *
get_video_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
static MPModeList *
get_video_modes(MPCamera *camera, bool (*check)(MPCamera *, MPMode *))
{
const enum v4l2_buf_type buftype = get_buf_type(camera);
MPCameraModeList *item = NULL;
MPModeList *item = NULL;
for (uint32_t fmt_index = 0;; ++fmt_index) {
struct v4l2_fmtdesc fmt = {};
@@ -999,7 +738,7 @@ get_video_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
break;
}
MPCameraMode mode = {
MPMode mode = {
.pixel_format = format,
.frame_interval = interval.discrete,
.width = frame.discrete.width,
@@ -1010,8 +749,7 @@ get_video_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
continue;
}
MPCameraModeList *new_item =
malloc(sizeof(MPCameraModeList));
MPModeList *new_item = malloc(sizeof(MPModeList));
new_item->mode = mode;
new_item->next = item;
item = new_item;
@@ -1023,20 +761,20 @@ get_video_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
}
static bool
all_modes(MPCamera *camera, MPCameraMode *mode)
all_modes(MPCamera *camera, MPMode *mode)
{
return true;
}
static bool
available_modes(MPCamera *camera, MPCameraMode *mode)
available_modes(MPCamera *camera, MPMode *mode)
{
MPCameraMode attempt = *mode;
MPMode attempt = *mode;
return mp_camera_try_mode(camera, &attempt) &&
mp_camera_mode_is_equivalent(mode, &attempt);
mp_mode_is_equivalent(mode, &attempt);
}
MPCameraModeList *
MPModeList *
mp_camera_list_supported_modes(MPCamera *camera)
{
if (mp_camera_is_subdev(camera)) {
@@ -1046,7 +784,7 @@ mp_camera_list_supported_modes(MPCamera *camera)
}
}
MPCameraModeList *
MPModeList *
mp_camera_list_available_modes(MPCamera *camera)
{
if (mp_camera_is_subdev(camera)) {
@@ -1056,25 +794,25 @@ mp_camera_list_available_modes(MPCamera *camera)
}
}
MPCameraMode *
mp_camera_mode_list_get(MPCameraModeList *list)
MPMode *
mp_camera_mode_list_get(MPModeList *list)
{
g_return_val_if_fail(list, NULL);
return &list->mode;
}
MPCameraModeList *
mp_camera_mode_list_next(MPCameraModeList *list)
MPModeList *
mp_camera_mode_list_next(MPModeList *list)
{
g_return_val_if_fail(list, NULL);
return list->next;
}
void
mp_camera_mode_list_free(MPCameraModeList *list)
mp_camera_mode_list_free(MPModeList *list)
{
while (list) {
MPCameraModeList *tmp = list;
MPModeList *tmp = list;
list = tmp->next;
free(tmp);
}