mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-03-10 09:33:43 +00:00
captured -> stream
This commit is contained in:
38
src/http.c
38
src/http.c
@@ -14,7 +14,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "capture.h"
|
#include "stream.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -28,16 +28,16 @@ static void _http_update_exposed(struct http_server_t *server);
|
|||||||
static void _http_add_header(struct evhttp_request *request, const char *key, const char *value);
|
static void _http_add_header(struct evhttp_request *request, const char *key, const char *value);
|
||||||
|
|
||||||
|
|
||||||
struct http_server_t *http_server_init(struct captured_picture_t *captured) {
|
struct http_server_t *http_server_init(struct stream_t *stream) {
|
||||||
struct captured_picture_t *exposed;
|
struct stream_t *exposed;
|
||||||
struct http_server_runtime_t *run;
|
struct http_server_runtime_t *run;
|
||||||
struct http_server_t *server;
|
struct http_server_t *server;
|
||||||
|
|
||||||
exposed = captured_picture_init();
|
exposed = stream_init();
|
||||||
|
|
||||||
A_CALLOC(run, 1, sizeof(*run));
|
A_CALLOC(run, 1, sizeof(*run));
|
||||||
MEMSET_ZERO_PTR(run);
|
MEMSET_ZERO_PTR(run);
|
||||||
run->captured = captured;
|
run->stream = stream;
|
||||||
run->exposed = exposed;
|
run->exposed = exposed;
|
||||||
|
|
||||||
A_CALLOC(server, 1, sizeof(*server));
|
A_CALLOC(server, 1, sizeof(*server));
|
||||||
@@ -61,7 +61,7 @@ void http_server_destroy(struct http_server_t *server) {
|
|||||||
evhttp_free(server->run->http);
|
evhttp_free(server->run->http);
|
||||||
event_base_free(server->run->base);
|
event_base_free(server->run->base);
|
||||||
free(server->run->exposed->picture.data);
|
free(server->run->exposed->picture.data);
|
||||||
captured_picture_destroy(server->run->exposed);
|
stream_destroy(server->run->exposed);
|
||||||
free(server->run);
|
free(server->run);
|
||||||
free(server);
|
free(server);
|
||||||
libevent_global_shutdown();
|
libevent_global_shutdown();
|
||||||
@@ -151,26 +151,26 @@ static void _http_callback_stream_snapshot(struct evhttp_request *request, void
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void _http_update_exposed(struct http_server_t *server) {
|
static void _http_update_exposed(struct http_server_t *server) {
|
||||||
if (server->run->captured->updated) {
|
if (server->run->stream->updated) {
|
||||||
A_PTHREAD_M_LOCK(&server->run->captured->mutex);
|
A_PTHREAD_M_LOCK(&server->run->stream->mutex);
|
||||||
if (server->run->captured->picture.allocated > server->run->exposed->picture.allocated) {
|
if (server->run->stream->picture.allocated > server->run->exposed->picture.allocated) {
|
||||||
A_REALLOC(
|
A_REALLOC(
|
||||||
server->run->exposed->picture.data,
|
server->run->exposed->picture.data,
|
||||||
server->run->captured->picture.allocated * sizeof(*server->run->exposed->picture.data)
|
server->run->stream->picture.allocated * sizeof(*server->run->exposed->picture.data)
|
||||||
);
|
);
|
||||||
server->run->exposed->picture.allocated = server->run->captured->picture.allocated;
|
server->run->exposed->picture.allocated = server->run->stream->picture.allocated;
|
||||||
}
|
}
|
||||||
memcpy(
|
memcpy(
|
||||||
server->run->exposed->picture.data,
|
server->run->exposed->picture.data,
|
||||||
server->run->captured->picture.data,
|
server->run->stream->picture.data,
|
||||||
server->run->captured->picture.size * sizeof(*server->run->exposed->picture.data)
|
server->run->stream->picture.size * sizeof(*server->run->exposed->picture.data)
|
||||||
);
|
);
|
||||||
server->run->exposed->picture.size = server->run->captured->picture.size;
|
server->run->exposed->picture.size = server->run->stream->picture.size;
|
||||||
server->run->exposed->width = server->run->captured->width;
|
server->run->exposed->width = server->run->stream->width;
|
||||||
server->run->exposed->height = server->run->captured->height;
|
server->run->exposed->height = server->run->stream->height;
|
||||||
server->run->exposed->online = server->run->captured->online;
|
server->run->exposed->online = server->run->stream->online;
|
||||||
server->run->captured->updated = false;
|
server->run->stream->updated = false;
|
||||||
A_PTHREAD_M_UNLOCK(&server->run->captured->mutex);
|
A_PTHREAD_M_UNLOCK(&server->run->stream->mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
src/http.h
12
src/http.h
@@ -3,14 +3,14 @@
|
|||||||
#include <event2/http.h>
|
#include <event2/http.h>
|
||||||
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "capture.h"
|
#include "stream.h"
|
||||||
|
|
||||||
|
|
||||||
struct http_server_runtime_t {
|
struct http_server_runtime_t {
|
||||||
struct event_base *base;
|
struct event_base *base;
|
||||||
struct evhttp *http;
|
struct evhttp *http;
|
||||||
struct captured_picture_t *captured;
|
struct stream_t *stream;
|
||||||
struct captured_picture_t *exposed; // updated and mutex are not used
|
struct stream_t *exposed; // updated and mutex are not used
|
||||||
};
|
};
|
||||||
|
|
||||||
struct http_server_t {
|
struct http_server_t {
|
||||||
@@ -21,7 +21,7 @@ struct http_server_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct http_server_t *http_server_init(struct captured_picture_t *captured);
|
struct http_server_t *http_server_init(struct stream_t *stream);
|
||||||
void http_server_destroy(struct http_server_t *server);
|
void http_server_destroy(struct http_server_t *server);
|
||||||
|
|
||||||
int http_server_listen(struct http_server_t *server);
|
int http_server_listen(struct http_server_t *server);
|
||||||
|
|||||||
30
src/main.c
30
src/main.c
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "capture.h"
|
#include "stream.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -104,9 +104,9 @@ static int _parse_options(int argc, char *argv[], struct device_t *dev, struct h
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct main_context_t {
|
struct main_context_t {
|
||||||
struct device_t *dev;
|
struct device_t *dev;
|
||||||
struct captured_picture_t *captured;
|
struct stream_t *stream;
|
||||||
struct http_server_t *server;
|
struct http_server_t *server;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct main_context_t *_ctx;
|
static struct main_context_t *_ctx;
|
||||||
@@ -119,9 +119,9 @@ static void _block_thread_signals() {
|
|||||||
assert(!pthread_sigmask(SIG_BLOCK, &mask, NULL));
|
assert(!pthread_sigmask(SIG_BLOCK, &mask, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *_capture_loop_thread(UNUSED void *_) {
|
static void *_stream_loop_thread(UNUSED void *_) {
|
||||||
_block_thread_signals();
|
_block_thread_signals();
|
||||||
capture_loop(_ctx->dev, _ctx->captured);
|
stream_loop(_ctx->dev, _ctx->stream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ static void *_server_loop_thread(UNUSED void *_) {
|
|||||||
|
|
||||||
static void _signal_handler(int signum) {
|
static void _signal_handler(int signum) {
|
||||||
LOG_INFO("===== Stopping by %s =====", strsignal(signum));
|
LOG_INFO("===== Stopping by %s =====", strsignal(signum));
|
||||||
capture_loop_break(_ctx->dev);
|
stream_loop_break(_ctx->dev);
|
||||||
http_server_loop_break(_ctx->server);
|
http_server_loop_break(_ctx->server);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,36 +158,36 @@ static void _install_signal_handlers() {
|
|||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
struct device_t *dev;
|
struct device_t *dev;
|
||||||
struct captured_picture_t *captured;
|
struct stream_t *stream;
|
||||||
struct http_server_t *server;
|
struct http_server_t *server;
|
||||||
int exit_code = 0;
|
int exit_code = 0;
|
||||||
|
|
||||||
dev = device_init();
|
dev = device_init();
|
||||||
captured = captured_picture_init();
|
stream = stream_init();
|
||||||
server = http_server_init(captured);
|
server = http_server_init(stream);
|
||||||
|
|
||||||
if ((exit_code = _parse_options(argc, argv, dev, server)) == 0) {
|
if ((exit_code = _parse_options(argc, argv, dev, server)) == 0) {
|
||||||
_install_signal_handlers();
|
_install_signal_handlers();
|
||||||
|
|
||||||
pthread_t capture_loop_tid;
|
pthread_t stream_loop_tid;
|
||||||
pthread_t server_loop_tid;
|
pthread_t server_loop_tid;
|
||||||
struct main_context_t ctx;
|
struct main_context_t ctx;
|
||||||
|
|
||||||
ctx.dev = dev;
|
ctx.dev = dev;
|
||||||
ctx.captured = captured;
|
ctx.stream = stream;
|
||||||
ctx.server = server;
|
ctx.server = server;
|
||||||
_ctx = &ctx;
|
_ctx = &ctx;
|
||||||
|
|
||||||
if ((exit_code = http_server_listen(server)) == 0) {
|
if ((exit_code = http_server_listen(server)) == 0) {
|
||||||
A_PTHREAD_CREATE(&capture_loop_tid, _capture_loop_thread, NULL);
|
A_PTHREAD_CREATE(&stream_loop_tid, _stream_loop_thread, NULL);
|
||||||
A_PTHREAD_CREATE(&server_loop_tid, _server_loop_thread, NULL);
|
A_PTHREAD_CREATE(&server_loop_tid, _server_loop_thread, NULL);
|
||||||
A_PTHREAD_JOIN(capture_loop_tid);
|
A_PTHREAD_JOIN(stream_loop_tid);
|
||||||
A_PTHREAD_JOIN(server_loop_tid);
|
A_PTHREAD_JOIN(server_loop_tid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
http_server_destroy(server);
|
http_server_destroy(server);
|
||||||
captured_picture_destroy(captured);
|
stream_destroy(stream);
|
||||||
device_destroy(dev);
|
device_destroy(dev);
|
||||||
return abs(exit_code);
|
return abs(exit_code);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
#ifdef DUMP_CAPTURED_JPEGS
|
#ifdef DUMP_STREAM_JPEGS
|
||||||
# warning Enabled DUMP_CAPTURED_JPEGS
|
# warning Enabled DUMP_STREAM_JPEGS
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
# include <sys/stat.h>
|
# include <sys/stat.h>
|
||||||
@@ -17,58 +17,58 @@
|
|||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "jpeg.h"
|
#include "jpeg.h"
|
||||||
#include "capture.h"
|
#include "stream.h"
|
||||||
|
|
||||||
|
|
||||||
static long double _capture_get_fluency_delay(struct device_t *dev, struct workers_pool_t *pool);
|
static long double _stream_get_fluency_delay(struct device_t *dev, struct workers_pool_t *pool);
|
||||||
static int _capture_init_loop(struct device_t *dev, struct workers_pool_t *pool);
|
static int _stream_init_loop(struct device_t *dev, struct workers_pool_t *pool);
|
||||||
static int _capture_init(struct device_t *dev, struct workers_pool_t *pool);
|
static int _stream_init(struct device_t *dev, struct workers_pool_t *pool);
|
||||||
static void _capture_init_workers(struct device_t *dev, struct workers_pool_t *pool);
|
static void _stream_init_workers(struct device_t *dev, struct workers_pool_t *pool);
|
||||||
static void *_capture_worker_thread(void *v_ctx);
|
static void *_stream_worker_thread(void *v_ctx);
|
||||||
static void _capture_destroy_workers(struct device_t *dev, struct workers_pool_t *pool);
|
static void _stream_destroy_workers(struct device_t *dev, struct workers_pool_t *pool);
|
||||||
static int _capture_control(struct device_t *dev, const bool enable);
|
static int _stream_control(struct device_t *dev, const bool enable);
|
||||||
static int _capture_grab_buffer(struct device_t *dev, struct v4l2_buffer *buf_info);
|
static int _stream_grab_buffer(struct device_t *dev, struct v4l2_buffer *buf_info);
|
||||||
static int _capture_release_buffer(struct device_t *dev, struct v4l2_buffer *buf_info);
|
static int _stream_release_buffer(struct device_t *dev, struct v4l2_buffer *buf_info);
|
||||||
static int _capture_handle_event(struct device_t *dev);
|
static int _stream_handle_event(struct device_t *dev);
|
||||||
|
|
||||||
|
|
||||||
struct captured_picture_t *captured_picture_init() {
|
struct stream_t *stream_init() {
|
||||||
struct captured_picture_t *captured;
|
struct stream_t *stream;
|
||||||
|
|
||||||
A_CALLOC(captured, 1, sizeof(*captured));
|
A_CALLOC(stream, 1, sizeof(*stream));
|
||||||
MEMSET_ZERO_PTR(captured);
|
MEMSET_ZERO_PTR(stream);
|
||||||
|
|
||||||
A_PTHREAD_M_INIT(&captured->mutex);
|
A_PTHREAD_M_INIT(&stream->mutex);
|
||||||
return captured;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void captured_picture_destroy(struct captured_picture_t *captured) {
|
void stream_destroy(struct stream_t *stream) {
|
||||||
A_PTHREAD_M_DESTROY(&captured->mutex);
|
A_PTHREAD_M_DESTROY(&stream->mutex);
|
||||||
free(captured);
|
free(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DUMP_CAPTURED_JPEGS
|
#ifdef DUMP_STREAM_JPEGS
|
||||||
static void _capture_dump(struct captured_picture_t *captured) {
|
static void _stream_dump(struct stream_t *stream) {
|
||||||
static unsigned count = 0;
|
static unsigned count = 0;
|
||||||
char path[1024];
|
char path[1024];
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
mkdir("captured", 0777);
|
mkdir("stream", 0777);
|
||||||
assert(errno == 0 || errno == EEXIST);
|
assert(errno == 0 || errno == EEXIST);
|
||||||
|
|
||||||
sprintf(path, "captured/img_%06u.jpg", count);
|
sprintf(path, "stream/img_%06u.jpg", count);
|
||||||
int fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, 0644);
|
int fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, 0644);
|
||||||
assert(fd);
|
assert(fd);
|
||||||
assert(write(fd, captured->picture.data, captured->picture.size) == (ssize_t)captured->picture.size);
|
assert(write(fd, stream->picture.data, stream->picture.size) == (ssize_t)stream->picture.size);
|
||||||
assert(!close(fd));
|
assert(!close(fd));
|
||||||
|
|
||||||
LOG_INFO("-DDUMP_CAPTURED_JPEGS dumped %s", path);
|
LOG_INFO("-DDUMP_STREAM_JPEGS dumped %s", path);
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void capture_loop(struct device_t *dev, struct captured_picture_t *captured) {
|
void stream_loop(struct device_t *dev, struct stream_t *stream) {
|
||||||
struct workers_pool_t pool;
|
struct workers_pool_t pool;
|
||||||
bool workers_stop;
|
bool workers_stop;
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ void capture_loop(struct device_t *dev, struct captured_picture_t *captured) {
|
|||||||
LOG_INFO("Using V4L2 device: %s", dev->path);
|
LOG_INFO("Using V4L2 device: %s", dev->path);
|
||||||
LOG_INFO("Using JPEG quality: %d%%", dev->jpeg_quality);
|
LOG_INFO("Using JPEG quality: %d%%", dev->jpeg_quality);
|
||||||
|
|
||||||
while (_capture_init_loop(dev, &pool) == 0) {
|
while (_stream_init_loop(dev, &pool) == 0) {
|
||||||
struct worker_t *last_worker = NULL;
|
struct worker_t *last_worker = NULL;
|
||||||
unsigned frames_count = 0;
|
unsigned frames_count = 0;
|
||||||
long double grab_after = 0;
|
long double grab_after = 0;
|
||||||
@@ -86,14 +86,14 @@ void capture_loop(struct device_t *dev, struct captured_picture_t *captured) {
|
|||||||
unsigned fps = 0;
|
unsigned fps = 0;
|
||||||
long long fps_second = 0;
|
long long fps_second = 0;
|
||||||
|
|
||||||
LOG_DEBUG("Allocation memory for captured (result) picture ...");
|
LOG_DEBUG("Allocation memory for stream picture ...");
|
||||||
A_CALLOC(captured->picture.data, dev->run->max_picture_size, sizeof(*captured->picture.data));
|
A_CALLOC(stream->picture.data, dev->run->max_picture_size, sizeof(*stream->picture.data));
|
||||||
|
|
||||||
A_PTHREAD_M_LOCK(&captured->mutex);
|
A_PTHREAD_M_LOCK(&stream->mutex);
|
||||||
captured->width = dev->run->width;
|
stream->width = dev->run->width;
|
||||||
captured->height = dev->run->height;
|
stream->height = dev->run->height;
|
||||||
captured->online = true;
|
stream->online = true;
|
||||||
A_PTHREAD_M_UNLOCK(&captured->mutex);
|
A_PTHREAD_M_UNLOCK(&stream->mutex);
|
||||||
|
|
||||||
while (!dev->stop) {
|
while (!dev->stop) {
|
||||||
SEP_DEBUG('-');
|
SEP_DEBUG('-');
|
||||||
@@ -104,21 +104,21 @@ void capture_loop(struct device_t *dev, struct captured_picture_t *captured) {
|
|||||||
A_PTHREAD_M_UNLOCK(&pool.has_free_workers_mutex);
|
A_PTHREAD_M_UNLOCK(&pool.has_free_workers_mutex);
|
||||||
|
|
||||||
if (last_worker && !last_worker->has_job && dev->run->pictures[last_worker->ctx.index].data) {
|
if (last_worker && !last_worker->has_job && dev->run->pictures[last_worker->ctx.index].data) {
|
||||||
A_PTHREAD_M_LOCK(&captured->mutex);
|
A_PTHREAD_M_LOCK(&stream->mutex);
|
||||||
captured->picture.size = dev->run->pictures[last_worker->ctx.index].size;
|
stream->picture.size = dev->run->pictures[last_worker->ctx.index].size;
|
||||||
captured->picture.allocated = dev->run->pictures[last_worker->ctx.index].allocated;
|
stream->picture.allocated = dev->run->pictures[last_worker->ctx.index].allocated;
|
||||||
memcpy(
|
memcpy(
|
||||||
captured->picture.data,
|
stream->picture.data,
|
||||||
dev->run->pictures[last_worker->ctx.index].data,
|
dev->run->pictures[last_worker->ctx.index].data,
|
||||||
captured->picture.size * sizeof(*captured->picture.data)
|
stream->picture.size * sizeof(*stream->picture.data)
|
||||||
);
|
);
|
||||||
captured->updated = true;
|
stream->updated = true;
|
||||||
A_PTHREAD_M_UNLOCK(&captured->mutex);
|
A_PTHREAD_M_UNLOCK(&stream->mutex);
|
||||||
|
|
||||||
last_worker = last_worker->order_next;
|
last_worker = last_worker->order_next;
|
||||||
|
|
||||||
# ifdef DUMP_CAPTURED_JPEGS
|
# ifdef DUMP_STREAM_JPEGS
|
||||||
_capture_dump(captured);
|
_stream_dump(stream);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ void capture_loop(struct device_t *dev, struct captured_picture_t *captured) {
|
|||||||
|
|
||||||
struct v4l2_buffer buf_info;
|
struct v4l2_buffer buf_info;
|
||||||
|
|
||||||
if (_capture_grab_buffer(dev, &buf_info) < 0) {
|
if (_stream_grab_buffer(dev, &buf_info) < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ void capture_loop(struct device_t *dev, struct captured_picture_t *captured) {
|
|||||||
++fps;
|
++fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
long double delay = _capture_get_fluency_delay(dev, &pool);
|
long double delay = _stream_get_fluency_delay(dev, &pool);
|
||||||
grab_after = now + delay;
|
grab_after = now + delay;
|
||||||
LOG_PERF("Fluency delay=%.03Lf; grab_after=%.03Lf", delay, grab_after);
|
LOG_PERF("Fluency delay=%.03Lf; grab_after=%.03Lf", delay, grab_after);
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ void capture_loop(struct device_t *dev, struct captured_picture_t *captured) {
|
|||||||
|
|
||||||
pass_frame:
|
pass_frame:
|
||||||
|
|
||||||
if (_capture_release_buffer(dev, &buf_info) < 0) {
|
if (_stream_release_buffer(dev, &buf_info) < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,30 +236,30 @@ void capture_loop(struct device_t *dev, struct captured_picture_t *captured) {
|
|||||||
|
|
||||||
if (FD_ISSET(dev->run->fd, &error_fds)) {
|
if (FD_ISSET(dev->run->fd, &error_fds)) {
|
||||||
LOG_INFO("Got V4L2 event");
|
LOG_INFO("Got V4L2 event");
|
||||||
if (_capture_handle_event(dev) < 0) {
|
if (_stream_handle_event(dev) < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
A_PTHREAD_M_LOCK(&captured->mutex);
|
A_PTHREAD_M_LOCK(&stream->mutex);
|
||||||
captured->picture.size = 0;
|
stream->picture.size = 0;
|
||||||
free(captured->picture.data);
|
free(stream->picture.data);
|
||||||
captured->online = false;
|
stream->online = false;
|
||||||
A_PTHREAD_M_UNLOCK(&captured->mutex);
|
A_PTHREAD_M_UNLOCK(&stream->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
_capture_destroy_workers(dev, &pool);
|
_stream_destroy_workers(dev, &pool);
|
||||||
_capture_control(dev, false);
|
_stream_control(dev, false);
|
||||||
device_close(dev);
|
device_close(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void capture_loop_break(struct device_t *dev) {
|
void stream_loop_break(struct device_t *dev) {
|
||||||
dev->stop = 1;
|
dev->stop = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long double _capture_get_fluency_delay(struct device_t *dev, struct workers_pool_t *pool) {
|
static long double _stream_get_fluency_delay(struct device_t *dev, struct workers_pool_t *pool) {
|
||||||
long double delay = 0;
|
long double delay = 0;
|
||||||
|
|
||||||
for (unsigned index = 0; index < dev->run->n_buffers; ++index) {
|
for (unsigned index = 0; index < dev->run->n_buffers; ++index) {
|
||||||
@@ -273,13 +273,13 @@ static long double _capture_get_fluency_delay(struct device_t *dev, struct worke
|
|||||||
return delay / dev->run->n_buffers / dev->run->n_buffers;
|
return delay / dev->run->n_buffers / dev->run->n_buffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _capture_init_loop(struct device_t *dev, struct workers_pool_t *pool) {
|
static int _stream_init_loop(struct device_t *dev, struct workers_pool_t *pool) {
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
||||||
LOG_DEBUG("%s: *dev->stop = %d", __FUNCTION__, dev->stop);
|
LOG_DEBUG("%s: *dev->stop = %d", __FUNCTION__, dev->stop);
|
||||||
while (!dev->stop) {
|
while (!dev->stop) {
|
||||||
if ((retval = _capture_init(dev, pool)) < 0) {
|
if ((retval = _stream_init(dev, pool)) < 0) {
|
||||||
LOG_INFO("Sleeping %d seconds before new capture init ...", dev->error_timeout);
|
LOG_INFO("Sleeping %d seconds before new stream init ...", dev->error_timeout);
|
||||||
sleep(dev->error_timeout);
|
sleep(dev->error_timeout);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@@ -288,20 +288,20 @@ static int _capture_init_loop(struct device_t *dev, struct workers_pool_t *pool)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _capture_init(struct device_t *dev, struct workers_pool_t *pool) {
|
static int _stream_init(struct device_t *dev, struct workers_pool_t *pool) {
|
||||||
SEP_INFO('=');
|
SEP_INFO('=');
|
||||||
|
|
||||||
_capture_destroy_workers(dev, pool);
|
_stream_destroy_workers(dev, pool);
|
||||||
_capture_control(dev, false);
|
_stream_control(dev, false);
|
||||||
device_close(dev);
|
device_close(dev);
|
||||||
|
|
||||||
if (device_open(dev) < 0) {
|
if (device_open(dev) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (_capture_control(dev, true) < 0) {
|
if (_stream_control(dev, true) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
_capture_init_workers(dev, pool);
|
_stream_init_workers(dev, pool);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -310,7 +310,7 @@ static int _capture_init(struct device_t *dev, struct workers_pool_t *pool) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _capture_init_workers(struct device_t *dev, struct workers_pool_t *pool) {
|
static void _stream_init_workers(struct device_t *dev, struct workers_pool_t *pool) {
|
||||||
LOG_DEBUG("Spawning %d workers ...", dev->run->n_buffers);
|
LOG_DEBUG("Spawning %d workers ...", dev->run->n_buffers);
|
||||||
|
|
||||||
*pool->workers_stop = false;
|
*pool->workers_stop = false;
|
||||||
@@ -339,11 +339,11 @@ static void _capture_init_workers(struct device_t *dev, struct workers_pool_t *p
|
|||||||
pool->workers[index].ctx.has_free_workers = &pool->has_free_workers;
|
pool->workers[index].ctx.has_free_workers = &pool->has_free_workers;
|
||||||
pool->workers[index].ctx.has_free_workers_cond = &pool->has_free_workers_cond;
|
pool->workers[index].ctx.has_free_workers_cond = &pool->has_free_workers_cond;
|
||||||
|
|
||||||
A_PTHREAD_CREATE(&pool->workers[index].tid, _capture_worker_thread, (void *)&pool->workers[index].ctx);
|
A_PTHREAD_CREATE(&pool->workers[index].tid, _stream_worker_thread, (void *)&pool->workers[index].ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *_capture_worker_thread(void *v_ctx) {
|
static void *_stream_worker_thread(void *v_ctx) {
|
||||||
struct worker_context_t *ctx = (struct worker_context_t *)v_ctx;
|
struct worker_context_t *ctx = (struct worker_context_t *)v_ctx;
|
||||||
|
|
||||||
LOG_DEBUG("Hello! I am a worker #%d ^_^", ctx->index);
|
LOG_DEBUG("Hello! I am a worker #%d ^_^", ctx->index);
|
||||||
@@ -373,7 +373,7 @@ static void *_capture_worker_thread(void *v_ctx) {
|
|||||||
|
|
||||||
compressed = jpeg_compress_buffer(ctx->dev, ctx->index);
|
compressed = jpeg_compress_buffer(ctx->dev, ctx->index);
|
||||||
|
|
||||||
assert(!_capture_release_buffer(ctx->dev, &ctx->buf_info)); // FIXME
|
assert(!_stream_release_buffer(ctx->dev, &ctx->buf_info)); // FIXME
|
||||||
*ctx->has_job = false;
|
*ctx->has_job = false;
|
||||||
|
|
||||||
now_ms(&stop_sec, &stop_msec);
|
now_ms(&stop_sec, &stop_msec);
|
||||||
@@ -395,7 +395,7 @@ static void *_capture_worker_thread(void *v_ctx) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _capture_destroy_workers(struct device_t *dev, struct workers_pool_t *pool) {
|
static void _stream_destroy_workers(struct device_t *dev, struct workers_pool_t *pool) {
|
||||||
if (pool->workers) {
|
if (pool->workers) {
|
||||||
LOG_INFO("Destroying workers ...");
|
LOG_INFO("Destroying workers ...");
|
||||||
|
|
||||||
@@ -419,7 +419,7 @@ static void _capture_destroy_workers(struct device_t *dev, struct workers_pool_t
|
|||||||
pool->workers = NULL;
|
pool->workers = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _capture_control(struct device_t *dev, const bool enable) {
|
static int _stream_control(struct device_t *dev, const bool enable) {
|
||||||
if (enable != dev->run->capturing) {
|
if (enable != dev->run->capturing) {
|
||||||
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
|
|
||||||
@@ -437,7 +437,7 @@ static int _capture_control(struct device_t *dev, const bool enable) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _capture_grab_buffer(struct device_t *dev, struct v4l2_buffer *buf_info) {
|
static int _stream_grab_buffer(struct device_t *dev, struct v4l2_buffer *buf_info) {
|
||||||
MEMSET_ZERO_PTR(buf_info);
|
MEMSET_ZERO_PTR(buf_info);
|
||||||
buf_info->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
buf_info->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
buf_info->memory = V4L2_MEMORY_MMAP;
|
buf_info->memory = V4L2_MEMORY_MMAP;
|
||||||
@@ -456,7 +456,7 @@ static int _capture_grab_buffer(struct device_t *dev, struct v4l2_buffer *buf_in
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _capture_release_buffer(struct device_t *dev, struct v4l2_buffer *buf_info) {
|
static int _stream_release_buffer(struct device_t *dev, struct v4l2_buffer *buf_info) {
|
||||||
LOG_DEBUG("Calling ioctl(VIDIOC_QBUF) ...");
|
LOG_DEBUG("Calling ioctl(VIDIOC_QBUF) ...");
|
||||||
if (xioctl(dev->run->fd, VIDIOC_QBUF, buf_info) < 0) {
|
if (xioctl(dev->run->fd, VIDIOC_QBUF, buf_info) < 0) {
|
||||||
LOG_PERROR("Unable to requeue buffer");
|
LOG_PERROR("Unable to requeue buffer");
|
||||||
@@ -465,7 +465,7 @@ static int _capture_release_buffer(struct device_t *dev, struct v4l2_buffer *buf
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _capture_handle_event(struct device_t *dev) {
|
static int _stream_handle_event(struct device_t *dev) {
|
||||||
struct v4l2_event event;
|
struct v4l2_event event;
|
||||||
|
|
||||||
LOG_DEBUG("Calling ioctl(VIDIOC_DQEVENT) ...");
|
LOG_DEBUG("Calling ioctl(VIDIOC_DQEVENT) ...");
|
||||||
@@ -51,7 +51,7 @@ struct workers_pool_t {
|
|||||||
pthread_cond_t has_free_workers_cond;
|
pthread_cond_t has_free_workers_cond;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct captured_picture_t {
|
struct stream_t {
|
||||||
struct picture_t picture;
|
struct picture_t picture;
|
||||||
unsigned width;
|
unsigned width;
|
||||||
unsigned height;
|
unsigned height;
|
||||||
@@ -61,8 +61,8 @@ struct captured_picture_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct captured_picture_t *captured_picture_init();
|
struct stream_t *stream_init();
|
||||||
void captured_picture_destroy(struct captured_picture_t *captured);
|
void stream_destroy(struct stream_t *stream);
|
||||||
|
|
||||||
void capture_loop(struct device_t *dev, struct captured_picture_t *capture);
|
void stream_loop(struct device_t *dev, struct stream_t *stream);
|
||||||
void capture_loop_break(struct device_t *dev);
|
void stream_loop_break(struct device_t *dev);
|
||||||
Reference in New Issue
Block a user