137 lines
3.7 KiB
C
137 lines
3.7 KiB
C
#include "camera.h"
|
|
|
|
#include "device/hw/device.h"
|
|
#include "device/hw/buffer_list.h"
|
|
#include "device/hw/links.h"
|
|
#include "device/hw/v4l2.h"
|
|
|
|
void camera_init(camera_t *camera)
|
|
{
|
|
memset(camera, 0, sizeof(*camera));
|
|
camera->name = "CAMERA";
|
|
}
|
|
|
|
void camera_close(camera_t *camera)
|
|
{
|
|
if (!camera)
|
|
return;
|
|
|
|
for (int i = MAX_DEVICES; i-- > 0; ) {
|
|
if (camera->devices[i]) {
|
|
device_close(camera->devices[i]);
|
|
camera->devices[i] = NULL;
|
|
}
|
|
}
|
|
|
|
for (int i = MAX_DEVICES; i-- > 0; ) {
|
|
if (camera->links[i].callbacks.on_buffer) {
|
|
camera->links[i].callbacks.on_buffer = NULL;
|
|
}
|
|
}
|
|
|
|
memset(camera->links, 0, sizeof(camera->links));
|
|
free(camera);
|
|
}
|
|
|
|
camera_t *camera_open(camera_options_t *options)
|
|
{
|
|
camera_t *camera = calloc(1, sizeof(camera_t));
|
|
camera->name = "CAMERA";
|
|
camera->options = *options;
|
|
|
|
camera->camera = device_open(camera->name, camera->options.path);
|
|
if (!camera->camera) {
|
|
goto error;
|
|
}
|
|
|
|
camera->camera->allow_dma = camera->options.allow_dma;
|
|
|
|
if (strstr(camera->camera->v4l2_cap.bus_info, "usb")) {
|
|
E_LOG_INFO(camera, "Disabling DMA since device uses USB (which is likely not working properly).");
|
|
camera->camera->allow_dma = false;
|
|
}
|
|
|
|
device_set_pad_format(camera->camera, camera->options.width, camera->options.height, 0);
|
|
|
|
if (device_open_buffer_list(camera->camera, true, camera->options.width, camera->options.height, camera->options.format, 0, camera->options.nbufs, true) < 0) {
|
|
goto error;
|
|
}
|
|
camera->camera->capture_list->do_timestamps = true;
|
|
|
|
if (camera->options.fps > 0) {
|
|
camera->camera->capture_list->fmt_interval_us = 1000 * 1000 / camera->options.fps;
|
|
}
|
|
|
|
switch (camera->camera->capture_list->fmt_format) {
|
|
case V4L2_PIX_FMT_YUYV:
|
|
if (camera_configure_direct(camera) < 0) {
|
|
goto error;
|
|
}
|
|
break;
|
|
|
|
case V4L2_PIX_FMT_MJPEG:
|
|
case V4L2_PIX_FMT_H264:
|
|
if (camera_configure_decoder(camera) < 0) {
|
|
goto error;
|
|
}
|
|
break;
|
|
|
|
case V4L2_PIX_FMT_SRGGB10P:
|
|
#if 1
|
|
if (camera_configure_isp(camera, camera->options.high_res_factor, camera->options.low_res_factor) < 0) {
|
|
goto error;
|
|
}
|
|
#else
|
|
if (camera_configure_legacy_isp(camera, camera->options.high_res_factor) < 0) {
|
|
goto error;
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
default:
|
|
E_LOG_ERROR(camera, "Unsupported camera format=%s", fourcc_to_string(camera->options.format).buf);
|
|
break;
|
|
}
|
|
|
|
if (camera_set_params(camera) < 0) {
|
|
goto error;
|
|
}
|
|
|
|
return camera;
|
|
|
|
error:
|
|
camera_close(camera);
|
|
return NULL;
|
|
}
|
|
|
|
int camera_set_params(camera_t *camera)
|
|
{
|
|
device_set_fps(camera->camera, camera->options.fps);
|
|
device_set_option_list(camera->camera, camera->options.options);
|
|
|
|
// DEVICE_SET_OPTION(camera->camera, EXPOSURE, 2684);
|
|
// DEVICE_SET_OPTION(camera->camera, ANALOGUE_GAIN, 938);
|
|
// DEVICE_SET_OPTION(camera->camera, DIGITAL_GAIN, 512);
|
|
// DEVICE_SET_OPTION(camera->camera, VBLANK, 1636);
|
|
// DEVICE_SET_OPTION(camera->camera, HBLANK, 6906);
|
|
|
|
// DEVICE_SET_OPTION(camera->isp_srgb, RED_BALANCE, 2120);
|
|
// DEVICE_SET_OPTION(camera->isp_srgb, BLUE_BALANCE, 1472);
|
|
// DEVICE_SET_OPTION(camera->isp_srgb, DIGITAL_GAIN, 1007);
|
|
|
|
DEVICE_SET_OPTION2(camera->codec_jpeg, JPEG, COMPRESSION_QUALITY, 80);
|
|
|
|
DEVICE_SET_OPTION2(camera->codec_h264, MPEG_VIDEO, BITRATE, 5000 * 1000);
|
|
DEVICE_SET_OPTION2(camera->codec_h264, MPEG_VIDEO, H264_I_PERIOD, 30);
|
|
DEVICE_SET_OPTION2(camera->codec_h264, MPEG_VIDEO, H264_LEVEL, V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
|
|
DEVICE_SET_OPTION2(camera->codec_h264, MPEG_VIDEO, REPEAT_SEQ_HEADER, 1);
|
|
DEVICE_SET_OPTION2(camera->codec_h264, MPEG_VIDEO, H264_MIN_QP, 16);
|
|
DEVICE_SET_OPTION2(camera->codec_h264, MPEG_VIDEO, H264_MIN_QP, 32);
|
|
return 0;
|
|
}
|
|
|
|
int camera_run(camera_t *camera)
|
|
{
|
|
bool running = false;
|
|
return links_loop(camera->links, &running);
|
|
} |