mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-02-19 08:16:31 +00:00
simplified
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user