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:

committed by
Martijn Braam

parent
cd4ecdd964
commit
a4c2c1ec1f
@@ -44,6 +44,7 @@ executable('megapixels',
|
|||||||
'src/io_pipeline.c',
|
'src/io_pipeline.c',
|
||||||
'src/main.c',
|
'src/main.c',
|
||||||
'src/matrix.c',
|
'src/matrix.c',
|
||||||
|
'src/mode.c',
|
||||||
'src/pipeline.c',
|
'src/pipeline.c',
|
||||||
'src/process_pipeline.c',
|
'src/process_pipeline.c',
|
||||||
'src/zbar_pipeline.c',
|
'src/zbar_pipeline.c',
|
||||||
@@ -66,6 +67,7 @@ install_data(
|
|||||||
executable('megapixels-list-devices',
|
executable('megapixels-list-devices',
|
||||||
'tools/list_devices.c',
|
'tools/list_devices.c',
|
||||||
'src/device.c',
|
'src/device.c',
|
||||||
|
'src/mode.c',
|
||||||
include_directories: 'src/',
|
include_directories: 'src/',
|
||||||
dependencies: [gtkdep],
|
dependencies: [gtkdep],
|
||||||
install: true)
|
install: true)
|
||||||
@@ -74,6 +76,7 @@ executable('megapixels-camera-test',
|
|||||||
'tools/camera_test.c',
|
'tools/camera_test.c',
|
||||||
'src/camera.c',
|
'src/camera.c',
|
||||||
'src/device.c',
|
'src/device.c',
|
||||||
|
'src/mode.c',
|
||||||
include_directories: 'src/',
|
include_directories: 'src/',
|
||||||
dependencies: [gtkdep],
|
dependencies: [gtkdep],
|
||||||
install: true)
|
install: true)
|
||||||
@@ -106,6 +109,8 @@ if clang_format.found()
|
|||||||
'src/main.h',
|
'src/main.h',
|
||||||
'src/matrix.c',
|
'src/matrix.c',
|
||||||
'src/matrix.h',
|
'src/matrix.h',
|
||||||
|
'src/mode.c',
|
||||||
|
'src/mode.h',
|
||||||
'src/pipeline.c',
|
'src/pipeline.c',
|
||||||
'src/pipeline.h',
|
'src/pipeline.h',
|
||||||
'src/process_pipeline.c',
|
'src/process_pipeline.c',
|
||||||
|
320
src/camera.c
320
src/camera.c
@@ -1,8 +1,10 @@
|
|||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
#include "mode.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <linux/v4l2-subdev.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
@@ -12,263 +14,6 @@
|
|||||||
#define MAX_VIDEO_BUFFERS 20
|
#define MAX_VIDEO_BUFFERS 20
|
||||||
#define MAX_BG_TASKS 8
|
#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
|
static void
|
||||||
errno_printerr(const char *s)
|
errno_printerr(const char *s)
|
||||||
{
|
{
|
||||||
@@ -296,7 +41,7 @@ struct _MPCamera {
|
|||||||
int subdev_fd;
|
int subdev_fd;
|
||||||
|
|
||||||
bool has_set_mode;
|
bool has_set_mode;
|
||||||
MPCameraMode current_mode;
|
MPMode current_mode;
|
||||||
|
|
||||||
struct video_buffer buffers[MAX_VIDEO_BUFFERS];
|
struct video_buffer buffers[MAX_VIDEO_BUFFERS];
|
||||||
uint32_t num_buffers;
|
uint32_t num_buffers;
|
||||||
@@ -461,7 +206,7 @@ get_buf_type(MPCamera *camera)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
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);
|
uint32_t pixfmt = mp_pixel_format_to_v4l_pixel_format(mode->pixel_format);
|
||||||
struct v4l2_format fmt = {};
|
struct v4l2_format fmt = {};
|
||||||
@@ -499,7 +244,7 @@ camera_mode_impl(MPCamera *camera, int request, MPCameraMode *mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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)) {
|
if (!camera_mode_impl(camera, VIDIOC_TRY_FMT, mode)) {
|
||||||
errno_printerr("VIDIOC_S_FMT");
|
errno_printerr("VIDIOC_S_FMT");
|
||||||
@@ -508,14 +253,14 @@ mp_camera_try_mode(MPCamera *camera, MPCameraMode *mode)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MPCameraMode *
|
const MPMode *
|
||||||
mp_camera_get_mode(const MPCamera *camera)
|
mp_camera_get_mode(const MPCamera *camera)
|
||||||
{
|
{
|
||||||
return &camera->current_mode;
|
return &camera->current_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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
|
// Set the mode in the subdev the camera is one
|
||||||
if (mp_camera_is_subdev(camera)) {
|
if (mp_camera_is_subdev(camera)) {
|
||||||
@@ -843,15 +588,10 @@ mp_camera_release_buffer(MPCamera *camera, uint32_t buffer_index)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _MPCameraModeList {
|
static MPModeList *
|
||||||
MPCameraMode mode;
|
get_subdev_modes(MPCamera *camera, bool (*check)(MPCamera *, MPMode *))
|
||||||
MPCameraModeList *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
static MPCameraModeList *
|
|
||||||
get_subdev_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
|
|
||||||
{
|
{
|
||||||
MPCameraModeList *item = NULL;
|
MPModeList *item = NULL;
|
||||||
|
|
||||||
for (uint32_t fmt_index = 0;; ++fmt_index) {
|
for (uint32_t fmt_index = 0;; ++fmt_index) {
|
||||||
struct v4l2_subdev_mbus_code_enum fmt = {};
|
struct v4l2_subdev_mbus_code_enum fmt = {};
|
||||||
@@ -912,7 +652,7 @@ get_subdev_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MPCameraMode mode = {
|
MPMode mode = {
|
||||||
.pixel_format = format,
|
.pixel_format = format,
|
||||||
.frame_interval = interval.interval,
|
.frame_interval = interval.interval,
|
||||||
.width = frame.max_width,
|
.width = frame.max_width,
|
||||||
@@ -923,8 +663,7 @@ get_subdev_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MPCameraModeList *new_item =
|
MPModeList *new_item = malloc(sizeof(MPModeList));
|
||||||
malloc(sizeof(MPCameraModeList));
|
|
||||||
new_item->mode = mode;
|
new_item->mode = mode;
|
||||||
new_item->next = item;
|
new_item->next = item;
|
||||||
item = new_item;
|
item = new_item;
|
||||||
@@ -935,12 +674,12 @@ get_subdev_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MPCameraModeList *
|
static MPModeList *
|
||||||
get_video_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
|
get_video_modes(MPCamera *camera, bool (*check)(MPCamera *, MPMode *))
|
||||||
{
|
{
|
||||||
const enum v4l2_buf_type buftype = get_buf_type(camera);
|
const enum v4l2_buf_type buftype = get_buf_type(camera);
|
||||||
|
|
||||||
MPCameraModeList *item = NULL;
|
MPModeList *item = NULL;
|
||||||
|
|
||||||
for (uint32_t fmt_index = 0;; ++fmt_index) {
|
for (uint32_t fmt_index = 0;; ++fmt_index) {
|
||||||
struct v4l2_fmtdesc fmt = {};
|
struct v4l2_fmtdesc fmt = {};
|
||||||
@@ -999,7 +738,7 @@ get_video_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MPCameraMode mode = {
|
MPMode mode = {
|
||||||
.pixel_format = format,
|
.pixel_format = format,
|
||||||
.frame_interval = interval.discrete,
|
.frame_interval = interval.discrete,
|
||||||
.width = frame.discrete.width,
|
.width = frame.discrete.width,
|
||||||
@@ -1010,8 +749,7 @@ get_video_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MPCameraModeList *new_item =
|
MPModeList *new_item = malloc(sizeof(MPModeList));
|
||||||
malloc(sizeof(MPCameraModeList));
|
|
||||||
new_item->mode = mode;
|
new_item->mode = mode;
|
||||||
new_item->next = item;
|
new_item->next = item;
|
||||||
item = new_item;
|
item = new_item;
|
||||||
@@ -1023,20 +761,20 @@ get_video_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
all_modes(MPCamera *camera, MPCameraMode *mode)
|
all_modes(MPCamera *camera, MPMode *mode)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
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) &&
|
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)
|
mp_camera_list_supported_modes(MPCamera *camera)
|
||||||
{
|
{
|
||||||
if (mp_camera_is_subdev(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)
|
mp_camera_list_available_modes(MPCamera *camera)
|
||||||
{
|
{
|
||||||
if (mp_camera_is_subdev(camera)) {
|
if (mp_camera_is_subdev(camera)) {
|
||||||
@@ -1056,25 +794,25 @@ mp_camera_list_available_modes(MPCamera *camera)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MPCameraMode *
|
MPMode *
|
||||||
mp_camera_mode_list_get(MPCameraModeList *list)
|
mp_camera_mode_list_get(MPModeList *list)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(list, NULL);
|
g_return_val_if_fail(list, NULL);
|
||||||
return &list->mode;
|
return &list->mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
MPCameraModeList *
|
MPModeList *
|
||||||
mp_camera_mode_list_next(MPCameraModeList *list)
|
mp_camera_mode_list_next(MPModeList *list)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(list, NULL);
|
g_return_val_if_fail(list, NULL);
|
||||||
return list->next;
|
return list->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mp_camera_mode_list_free(MPCameraModeList *list)
|
mp_camera_mode_list_free(MPModeList *list)
|
||||||
{
|
{
|
||||||
while (list) {
|
while (list) {
|
||||||
MPCameraModeList *tmp = list;
|
MPModeList *tmp = list;
|
||||||
list = tmp->next;
|
list = tmp->next;
|
||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
64
src/camera.h
64
src/camera.h
@@ -1,53 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <linux/v4l2-subdev.h>
|
#include "mode.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
MP_PIXEL_FMT_UNSUPPORTED,
|
|
||||||
MP_PIXEL_FMT_BGGR8,
|
|
||||||
MP_PIXEL_FMT_GBRG8,
|
|
||||||
MP_PIXEL_FMT_GRBG8,
|
|
||||||
MP_PIXEL_FMT_RGGB8,
|
|
||||||
MP_PIXEL_FMT_BGGR10P,
|
|
||||||
MP_PIXEL_FMT_GBRG10P,
|
|
||||||
MP_PIXEL_FMT_GRBG10P,
|
|
||||||
MP_PIXEL_FMT_RGGB10P,
|
|
||||||
MP_PIXEL_FMT_UYVY,
|
|
||||||
MP_PIXEL_FMT_YUYV,
|
|
||||||
|
|
||||||
MP_PIXEL_FMT_MAX,
|
|
||||||
} MPPixelFormat;
|
|
||||||
|
|
||||||
const char *mp_pixel_format_to_str(MPPixelFormat pixel_format);
|
|
||||||
MPPixelFormat mp_pixel_format_from_str(const char *str);
|
|
||||||
|
|
||||||
MPPixelFormat mp_pixel_format_from_v4l_pixel_format(uint32_t v4l_pixel_format);
|
|
||||||
MPPixelFormat mp_pixel_format_from_v4l_bus_code(uint32_t v4l_bus_code);
|
|
||||||
uint32_t mp_pixel_format_to_v4l_pixel_format(MPPixelFormat pixel_format);
|
|
||||||
uint32_t mp_pixel_format_to_v4l_bus_code(MPPixelFormat pixel_format);
|
|
||||||
|
|
||||||
uint32_t mp_pixel_format_bits_per_pixel(MPPixelFormat pixel_format);
|
|
||||||
uint32_t mp_pixel_format_pixel_depth(MPPixelFormat pixel_format);
|
|
||||||
const char *mp_pixel_format_cfa(MPPixelFormat pixel_format);
|
|
||||||
const char *mp_pixel_format_cfa_pattern(MPPixelFormat pixel_format);
|
|
||||||
uint32_t mp_pixel_format_width_to_bytes(MPPixelFormat pixel_format, uint32_t width);
|
|
||||||
uint32_t mp_pixel_format_width_to_colors(MPPixelFormat pixel_format, uint32_t width);
|
|
||||||
uint32_t mp_pixel_format_height_to_colors(MPPixelFormat pixel_format,
|
|
||||||
uint32_t height);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
MPPixelFormat pixel_format;
|
|
||||||
|
|
||||||
struct v4l2_fract frame_interval;
|
|
||||||
uint32_t width;
|
|
||||||
uint32_t height;
|
|
||||||
} MPCameraMode;
|
|
||||||
|
|
||||||
bool mp_camera_mode_is_equivalent(const MPCameraMode *m1, const MPCameraMode *m2);
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
|
|
||||||
@@ -68,23 +26,21 @@ bool mp_camera_is_subdev(MPCamera *camera);
|
|||||||
int mp_camera_get_video_fd(MPCamera *camera);
|
int mp_camera_get_video_fd(MPCamera *camera);
|
||||||
int mp_camera_get_subdev_fd(MPCamera *camera);
|
int mp_camera_get_subdev_fd(MPCamera *camera);
|
||||||
|
|
||||||
const MPCameraMode *mp_camera_get_mode(const MPCamera *camera);
|
const MPMode *mp_camera_get_mode(const MPCamera *camera);
|
||||||
bool mp_camera_try_mode(MPCamera *camera, MPCameraMode *mode);
|
bool mp_camera_try_mode(MPCamera *camera, MPMode *mode);
|
||||||
|
|
||||||
bool mp_camera_set_mode(MPCamera *camera, MPCameraMode *mode);
|
bool mp_camera_set_mode(MPCamera *camera, MPMode *mode);
|
||||||
bool mp_camera_start_capture(MPCamera *camera);
|
bool mp_camera_start_capture(MPCamera *camera);
|
||||||
bool mp_camera_stop_capture(MPCamera *camera);
|
bool mp_camera_stop_capture(MPCamera *camera);
|
||||||
bool mp_camera_is_capturing(MPCamera *camera);
|
bool mp_camera_is_capturing(MPCamera *camera);
|
||||||
bool mp_camera_capture_buffer(MPCamera *camera, MPBuffer *buffer);
|
bool mp_camera_capture_buffer(MPCamera *camera, MPBuffer *buffer);
|
||||||
bool mp_camera_release_buffer(MPCamera *camera, uint32_t buffer_index);
|
bool mp_camera_release_buffer(MPCamera *camera, uint32_t buffer_index);
|
||||||
|
|
||||||
typedef struct _MPCameraModeList MPCameraModeList;
|
MPModeList *mp_camera_list_supported_modes(MPCamera *camera);
|
||||||
|
MPModeList *mp_camera_list_available_modes(MPCamera *camera);
|
||||||
MPCameraModeList *mp_camera_list_supported_modes(MPCamera *camera);
|
MPMode *mp_camera_mode_list_get(MPModeList *list);
|
||||||
MPCameraModeList *mp_camera_list_available_modes(MPCamera *camera);
|
MPModeList *mp_camera_mode_list_next(MPModeList *list);
|
||||||
MPCameraMode *mp_camera_mode_list_get(MPCameraModeList *list);
|
void mp_camera_mode_list_free(MPModeList *list);
|
||||||
MPCameraModeList *mp_camera_mode_list_next(MPCameraModeList *list);
|
|
||||||
void mp_camera_mode_list_free(MPCameraModeList *list);
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
@@ -83,7 +83,7 @@ strtoint(const char *nptr, char **endptr, int base)
|
|||||||
|
|
||||||
static bool
|
static bool
|
||||||
config_handle_camera_mode(const char *prefix,
|
config_handle_camera_mode(const char *prefix,
|
||||||
MPCameraMode *mode,
|
MPMode *mode,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *value)
|
const char *value)
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "camera.h"
|
#include "mode.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@@ -22,8 +22,8 @@ struct mp_camera_config {
|
|||||||
char dev_name[260];
|
char dev_name[260];
|
||||||
char media_dev_name[260];
|
char media_dev_name[260];
|
||||||
|
|
||||||
MPCameraMode capture_mode;
|
MPMode capture_mode;
|
||||||
MPCameraMode preview_mode;
|
MPMode preview_mode;
|
||||||
int rotate;
|
int rotate;
|
||||||
bool mirrored;
|
bool mirrored;
|
||||||
|
|
||||||
|
@@ -68,7 +68,7 @@ static struct device_info devices[MP_MAX_CAMERAS];
|
|||||||
static size_t num_devices = 0;
|
static size_t num_devices = 0;
|
||||||
|
|
||||||
static const struct mp_camera_config *camera = NULL;
|
static const struct mp_camera_config *camera = NULL;
|
||||||
static MPCameraMode mode;
|
static MPMode mode;
|
||||||
|
|
||||||
static bool just_switched_mode = false;
|
static bool just_switched_mode = false;
|
||||||
static int blank_frame_count = 0;
|
static int blank_frame_count = 0;
|
||||||
@@ -204,7 +204,7 @@ setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
|
|||||||
// Start with the capture format, this works around a bug with
|
// Start with the capture format, this works around a bug with
|
||||||
// the ov5640 driver where it won't allow setting the preview
|
// the ov5640 driver where it won't allow setting the preview
|
||||||
// format initially.
|
// format initially.
|
||||||
MPCameraMode mode = config->capture_mode;
|
MPMode mode = config->capture_mode;
|
||||||
mp_camera_set_mode(info->camera, &mode);
|
mp_camera_set_mode(info->camera, &mode);
|
||||||
|
|
||||||
// Trigger continuous auto focus if the sensor supports it
|
// Trigger continuous auto focus if the sensor supports it
|
||||||
|
@@ -36,7 +36,7 @@ enum user_control { USER_CONTROL_ISO, USER_CONTROL_SHUTTER };
|
|||||||
|
|
||||||
static bool camera_is_initialized = false;
|
static bool camera_is_initialized = false;
|
||||||
static const struct mp_camera_config *camera = NULL;
|
static const struct mp_camera_config *camera = NULL;
|
||||||
static MPCameraMode mode;
|
static MPMode mode;
|
||||||
|
|
||||||
static int preview_width = -1;
|
static int preview_width = -1;
|
||||||
static int preview_height = -1;
|
static int preview_height = -1;
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
struct mp_main_state {
|
struct mp_main_state {
|
||||||
const struct mp_camera_config *camera;
|
const struct mp_camera_config *camera;
|
||||||
MPCameraMode mode;
|
MPMode mode;
|
||||||
|
|
||||||
int image_width;
|
int image_width;
|
||||||
int image_height;
|
int image_height;
|
||||||
|
263
src/mode.c
Normal file
263
src/mode.c
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
#include "mode.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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_mode_is_equivalent(const MPMode *m1, const MPMode *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;
|
||||||
|
}
|
55
src/mode.h
Normal file
55
src/mode.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <linux/v4l2-subdev.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MP_PIXEL_FMT_UNSUPPORTED,
|
||||||
|
MP_PIXEL_FMT_BGGR8,
|
||||||
|
MP_PIXEL_FMT_GBRG8,
|
||||||
|
MP_PIXEL_FMT_GRBG8,
|
||||||
|
MP_PIXEL_FMT_RGGB8,
|
||||||
|
MP_PIXEL_FMT_BGGR10P,
|
||||||
|
MP_PIXEL_FMT_GBRG10P,
|
||||||
|
MP_PIXEL_FMT_GRBG10P,
|
||||||
|
MP_PIXEL_FMT_RGGB10P,
|
||||||
|
MP_PIXEL_FMT_UYVY,
|
||||||
|
MP_PIXEL_FMT_YUYV,
|
||||||
|
|
||||||
|
MP_PIXEL_FMT_MAX,
|
||||||
|
} MPPixelFormat;
|
||||||
|
|
||||||
|
const char *mp_pixel_format_to_str(MPPixelFormat pixel_format);
|
||||||
|
MPPixelFormat mp_pixel_format_from_str(const char *str);
|
||||||
|
|
||||||
|
MPPixelFormat mp_pixel_format_from_v4l_pixel_format(uint32_t v4l_pixel_format);
|
||||||
|
MPPixelFormat mp_pixel_format_from_v4l_bus_code(uint32_t v4l_bus_code);
|
||||||
|
uint32_t mp_pixel_format_to_v4l_pixel_format(MPPixelFormat pixel_format);
|
||||||
|
uint32_t mp_pixel_format_to_v4l_bus_code(MPPixelFormat pixel_format);
|
||||||
|
|
||||||
|
uint32_t mp_pixel_format_bits_per_pixel(MPPixelFormat pixel_format);
|
||||||
|
uint32_t mp_pixel_format_pixel_depth(MPPixelFormat pixel_format);
|
||||||
|
const char *mp_pixel_format_cfa(MPPixelFormat pixel_format);
|
||||||
|
const char *mp_pixel_format_cfa_pattern(MPPixelFormat pixel_format);
|
||||||
|
uint32_t mp_pixel_format_width_to_bytes(MPPixelFormat pixel_format, uint32_t width);
|
||||||
|
uint32_t mp_pixel_format_width_to_colors(MPPixelFormat pixel_format, uint32_t width);
|
||||||
|
uint32_t mp_pixel_format_height_to_colors(MPPixelFormat pixel_format,
|
||||||
|
uint32_t height);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MPPixelFormat pixel_format;
|
||||||
|
|
||||||
|
struct v4l2_fract frame_interval;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
} MPMode;
|
||||||
|
|
||||||
|
bool mp_mode_is_equivalent(const MPMode *m1, const MPMode *m2);
|
||||||
|
|
||||||
|
typedef struct _MPModeList MPModeList;
|
||||||
|
|
||||||
|
struct _MPModeList {
|
||||||
|
MPMode mode;
|
||||||
|
MPModeList *next;
|
||||||
|
};
|
@@ -31,7 +31,7 @@ static volatile int frames_received = 0;
|
|||||||
static const struct mp_camera_config *camera;
|
static const struct mp_camera_config *camera;
|
||||||
static int camera_rotation;
|
static int camera_rotation;
|
||||||
|
|
||||||
static MPCameraMode mode;
|
static MPMode mode;
|
||||||
|
|
||||||
static int burst_length;
|
static int burst_length;
|
||||||
static int captures_remaining = 0;
|
static int captures_remaining = 0;
|
||||||
@@ -834,11 +834,10 @@ mod(int a, int b)
|
|||||||
static void
|
static void
|
||||||
update_state(MPPipeline *pipeline, const struct mp_process_pipeline_state *state)
|
update_state(MPPipeline *pipeline, const struct mp_process_pipeline_state *state)
|
||||||
{
|
{
|
||||||
const bool output_changed =
|
const bool output_changed = !mp_mode_is_equivalent(&mode, &state->mode) ||
|
||||||
!mp_camera_mode_is_equivalent(&mode, &state->mode) ||
|
preview_width != state->preview_width ||
|
||||||
preview_width != state->preview_width ||
|
preview_height != state->preview_height ||
|
||||||
preview_height != state->preview_height ||
|
device_rotation != state->device_rotation;
|
||||||
device_rotation != state->device_rotation;
|
|
||||||
|
|
||||||
const bool format_changed = mode.pixel_format != state->mode.pixel_format;
|
const bool format_changed = mode.pixel_format != state->mode.pixel_format;
|
||||||
|
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "camera.h"
|
||||||
#include "camera_config.h"
|
#include "camera_config.h"
|
||||||
|
|
||||||
typedef struct _GdkSurface GdkSurface;
|
typedef struct _GdkSurface GdkSurface;
|
||||||
|
|
||||||
struct mp_process_pipeline_state {
|
struct mp_process_pipeline_state {
|
||||||
const struct mp_camera_config *camera;
|
const struct mp_camera_config *camera;
|
||||||
MPCameraMode mode;
|
MPMode mode;
|
||||||
|
|
||||||
int burst_length;
|
int burst_length;
|
||||||
|
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
#include "mode.h"
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -143,15 +144,14 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
double mode_list_begin = get_time();
|
double mode_list_begin = get_time();
|
||||||
|
|
||||||
MPCameraModeList *modes = mp_camera_list_available_modes(camera);
|
MPModeList *modes = mp_camera_list_available_modes(camera);
|
||||||
|
|
||||||
double mode_list_end = get_time();
|
double mode_list_end = get_time();
|
||||||
|
|
||||||
printf("Available modes: (took %fms)\n",
|
printf("Available modes: (took %fms)\n",
|
||||||
(mode_list_end - mode_list_begin) * 1000);
|
(mode_list_end - mode_list_begin) * 1000);
|
||||||
for (MPCameraModeList *list = modes; list;
|
for (MPModeList *list = modes; list; list = mp_camera_mode_list_next(list)) {
|
||||||
list = mp_camera_mode_list_next(list)) {
|
MPMode *m = mp_camera_mode_list_get(list);
|
||||||
MPCameraMode *m = mp_camera_mode_list_get(list);
|
|
||||||
printf(" %dx%d interval:%d/%d fmt:%s\n",
|
printf(" %dx%d interval:%d/%d fmt:%s\n",
|
||||||
m->width,
|
m->width,
|
||||||
m->height,
|
m->height,
|
||||||
|
Reference in New Issue
Block a user