simplified

This commit is contained in:
Maxim Devaev
2024-02-29 00:42:31 +02:00
parent 4b6f65881d
commit 32165e97ed
4 changed files with 67 additions and 92 deletions

View File

@@ -93,6 +93,7 @@ static int _device_open_io_method(us_device_s *dev);
static int _device_open_io_method_mmap(us_device_s *dev);
static int _device_open_io_method_userptr(us_device_s *dev);
static int _device_open_queue_buffers(us_device_s *dev);
static int _device_open_export_to_dma(us_device_s *dev);
static int _device_apply_resolution(us_device_s *dev, uint width, uint height, float hz);
static void _device_apply_controls(us_device_s *dev);
@@ -176,8 +177,6 @@ int us_device_open(us_device_s *dev) {
_D_LOG_PERROR("Can't open device");
goto error;
}
_D_LOG_INFO("Device fd=%d opened", run->fd);
if (_device_open_check_cap(dev) < 0) {
goto error;
}
@@ -195,9 +194,21 @@ int us_device_open(us_device_s *dev) {
if (_device_open_queue_buffers(dev) < 0) {
goto error;
}
if (dev->dma_export) {
run->dma = !_device_open_export_to_dma(dev);
if (!run->dma && dev->dma_required) {
goto error;
}
}
_device_apply_controls(dev);
_D_LOG_DEBUG("Device fd=%d initialized", run->fd);
enum v4l2_buf_type type = run->capture_type;
if (us_xioctl(run->fd, VIDIOC_STREAMON, &type) < 0) {
_D_LOG_PERROR("Can't start capturing");
goto error;
}
run->streamon = true;
_D_LOG_INFO("Capturing started");
return 0;
error:
@@ -208,7 +219,14 @@ error:
void us_device_close(us_device_s *dev) {
us_device_runtime_s *const run = dev->run;
run->persistent_timeout_reported = false;
if (run->streamon) {
enum v4l2_buf_type type = run->capture_type;
if (us_xioctl(run->fd, VIDIOC_STREAMOFF, &type) < 0) {
_D_LOG_PERROR("Can't stop capturing");
}
run->streamon = false;
_D_LOG_INFO("Capturing stopped");
}
if (run->hw_bufs != NULL) {
_D_LOG_DEBUG("Releasing device buffers ...");
@@ -235,58 +253,8 @@ void us_device_close(us_device_s *dev) {
run->n_bufs = 0;
}
if (run->fd >= 0) {
_D_LOG_DEBUG("Closing device ...");
if (close(run->fd) < 0) {
_D_LOG_PERROR("Can't close device fd=%d", run->fd);
} else {
_D_LOG_INFO("Device fd=%d closed", run->fd);
}
run->fd = -1;
}
}
int us_device_export_to_dma(us_device_s *dev) {
us_device_runtime_s *const run = dev->run;
for (uint index = 0; index < run->n_bufs; ++index) {
struct v4l2_exportbuffer exp = {
.type = run->capture_type,
.index = index,
};
_D_LOG_DEBUG("Exporting device buffer=%u to DMA ...", index);
if (us_xioctl(run->fd, VIDIOC_EXPBUF, &exp) < 0) {
_D_LOG_PERROR("Can't export device buffer=%u to DMA", index);
goto error;
}
run->hw_bufs[index].dma_fd = exp.fd;
}
return 0;
error:
for (uint index = 0; index < run->n_bufs; ++index) {
US_CLOSE_FD(run->hw_bufs[index].dma_fd, close);
}
return -1;
}
int us_device_switch_capturing(us_device_s *dev, bool enable) {
us_device_runtime_s *const run = dev->run;
if (enable != run->capturing) {
enum v4l2_buf_type type = run->capture_type;
_D_LOG_DEBUG("%s device capturing ...", (enable ? "Starting" : "Stopping"));
if (us_xioctl(run->fd, (enable ? VIDIOC_STREAMON : VIDIOC_STREAMOFF), &type) < 0) {
_D_LOG_PERROR("Can't %s capturing", (enable ? "start" : "stop"));
if (enable) {
return -1;
}
}
run->capturing = enable;
_D_LOG_INFO("Capturing %s", (enable ? "started" : "stopped"));
}
return 0;
US_CLOSE_FD(run->fd, close);
run->persistent_timeout_reported = false;
}
int us_device_select(us_device_s *dev, bool *has_read, bool *has_error) {
@@ -316,7 +284,7 @@ int us_device_select(us_device_s *dev, bool *has_read, bool *has_error) {
*has_read = false;
*has_error = false;
}
_D_LOG_DEBUG("Device select() --> %d", retval);
_D_LOG_DEBUG("Device select() --> %d; has_read=%d, has_error=%d", retval, *has_read, *has_error);
if (retval > 0) {
run->persistent_timeout_reported = false;
@@ -452,7 +420,7 @@ int us_device_release_buffer(us_device_s *dev, us_hw_buffer_s *hw) {
int us_device_consume_event(us_device_s *dev) {
struct v4l2_event event;
_D_LOG_DEBUG("Consuming V4L2 event ...");
_D_LOG_INFO("Consuming V4L2 event ...");
if (us_xioctl(dev->run->fd, VIDIOC_DQEVENT, &event) == 0) {
switch (event.type) {
case V4L2_EVENT_SOURCE_CHANGE:
@@ -932,6 +900,30 @@ static int _device_open_queue_buffers(us_device_s *dev) {
return 0;
}
static int _device_open_export_to_dma(us_device_s *dev) {
us_device_runtime_s *const run = dev->run;
for (uint index = 0; index < run->n_bufs; ++index) {
struct v4l2_exportbuffer exp = {
.type = run->capture_type,
.index = index,
};
_D_LOG_DEBUG("Exporting device buffer=%u to DMA ...", index);
if (us_xioctl(run->fd, VIDIOC_EXPBUF, &exp) < 0) {
_D_LOG_PERROR("Can't export device buffer=%u to DMA", index);
goto error;
}
run->hw_bufs[index].dma_fd = exp.fd;
}
return 0;
error:
for (uint index = 0; index < run->n_bufs; ++index) {
US_CLOSE_FD(run->hw_bufs[index].dma_fd, close);
}
return -1;
}
static int _device_apply_resolution(us_device_s *dev, uint width, uint height, float hz) {
// Тут VIDEO_MIN_* не используются из-за странностей минимального разрешения при отсутствии сигнала
// у некоторых устройств, например TC358743

View File

@@ -65,9 +65,10 @@ typedef struct {
uz raw_size;
uint n_bufs;
us_hw_buffer_s *hw_bufs;
bool dma;
enum v4l2_buf_type capture_type;
bool capture_mplane;
bool capturing;
bool streamon;
bool persistent_timeout_reported;
} us_device_runtime_s;
@@ -110,6 +111,8 @@ typedef struct {
enum v4l2_memory io_method;
bool dv_timings;
uint n_bufs;
bool dma_export;
bool dma_required;
uint desired_fps;
uz min_frame_size;
bool persistent;
@@ -129,8 +132,6 @@ int us_device_parse_io_method(const char *str);
int us_device_open(us_device_s *dev);
void us_device_close(us_device_s *dev);
int us_device_export_to_dma(us_device_s *dev);
int us_device_switch_capturing(us_device_s *dev, bool enable);
int us_device_select(us_device_s *dev, bool *has_read, bool *has_error);
int us_device_grab_buffer(us_device_s *dev, us_hw_buffer_s **hw);
int us_device_release_buffer(us_device_s *dev, us_hw_buffer_s *hw);

View File

@@ -150,8 +150,6 @@ void us_stream_loop(us_stream_s *stream) {
# endif
} else {
if (has_read) {
US_LOG_DEBUG("Frame is ready");
# ifdef WITH_GPIO
us_gpio_set_stream_online(true);
# endif
@@ -197,17 +195,13 @@ void us_stream_loop(us_stream_s *stream) {
}
}
if (has_error) {
US_LOG_INFO("Got V4L2 event");
if (us_device_consume_event(stream->dev) < 0) {
break;
}
if (has_error && us_device_consume_event(stream->dev) < 0) {
break;
}
}
}
us_workers_pool_destroy(pool);
us_device_switch_capturing(stream->dev, false);
us_device_close(stream->dev);
# ifdef WITH_GPIO
@@ -266,17 +260,12 @@ static us_workers_pool_s *_stream_init_loop(us_stream_s *stream) {
}
static us_workers_pool_s *_stream_init_one(us_stream_s *stream) {
if (us_device_open(stream->dev) < 0) {
goto error;
}
if (
stream->dev->dma_export = (
stream->enc->type == US_ENCODER_TYPE_M2M_VIDEO
|| stream->enc->type == US_ENCODER_TYPE_M2M_IMAGE
|| (_RUN(h264) && !us_is_jpeg(stream->dev->run->format))
) {
us_device_export_to_dma(stream->dev);
}
if (us_device_switch_capturing(stream->dev, true) < 0) {
);
if (us_device_open(stream->dev) < 0) {
goto error;
}
return us_encoder_workers_pool_init(stream->enc, stream->dev);

View File

@@ -194,7 +194,7 @@ static void _main_loop(void) {
if (us_drm_wait_for_vsync(drm) == 0) {
us_drm_expose(drm, US_DRM_EXPOSE_BUSY, NULL, 0);
}
if (dev->run->capturing) {
if (dev->run->fd >= 0) {
goto close;
} else {
_slowdown();
@@ -205,9 +205,6 @@ static void _main_loop(void) {
if (us_device_open(dev) < 0) {
goto close;
}
if (us_device_switch_capturing(dev, true) < 0) {
goto close;
}
while (!atomic_load(&_g_stop)) {
if (atomic_load(&_g_ustreamer_online)) {
@@ -235,32 +232,28 @@ static void _main_loop(void) {
}
} else {
if (has_read) {
US_LOG_DEBUG("Frame is ready");
us_hw_buffer_s *hw;
const int buf_index = us_device_grab_buffer(dev, &hw);
if (buf_index >= 0) {
if (us_drm_expose(drm, US_DRM_EXPOSE_FRAME, &hw->raw, dev->run->hz) < 0) {
_slowdown();
continue;
}
const int exposed = us_drm_expose(drm, US_DRM_EXPOSE_FRAME, &hw->raw, dev->run->hz);
if (us_device_release_buffer(dev, hw) < 0) {
goto close;
}
if (exposed < 0) {
_slowdown();
continue;
}
} else if (buf_index == -2) {
goto close;
}
}
if (has_error) {
US_LOG_INFO("Got V4L2 event");
if (us_device_consume_event(dev) < 0) {
goto close;
}
if (has_error && us_device_consume_event(dev) < 0) {
goto close;
}
}
}
close:
us_device_switch_capturing(dev, false);
us_device_close(dev);
_slowdown();
}