|
@@ -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);
|
|
|
}
|