62#define MOD_NAME "[vcompress] "
72struct compress_state_real {
74 compress_state_real(
struct module *
parent,
const char *config_string);
78 thread asynch_consumer_thread;
80 static compress_state_real *create(
struct module *
parent,
const char *config_string,
82 compress_state_real *s =
new compress_state_real(
parent, config_string);
86 ~compress_state_real();
88 vector<struct module *>
state;
89 string compress_options;
90 volatile bool discard_frames;
102 struct compress_state_real *
ptr;
108 shared_ptr<video_frame>
frame);
113 printf(
"Possible compression modules (see '-c <module>:help' for options):\n");
121 for(
size_t i = 0; i < s->state.size(); i++){
142 for(
unsigned int i = 0; i < proxy->
ptr->state.size(); ++i) {
158 struct compress_state_real *new_state;
163 new_state = compress_state_real::create(&proxy->
mod, config, proxy);
170 struct compress_state_real *old = proxy->
ptr;
172 old->discard_frames =
true;
175 proxy->
ptr = new_state;
202 proxy->
ptr = compress_state_real::create(&proxy->
mod, config_string, proxy);
221compress_state_real::compress_state_real(
struct module *
parent,
const char *config_string) :
222 funcs(nullptr), discard_frames(false)
224 string compress_name;
229 if (strcmp(config_string,
"help") == 0 || strcmp(config_string,
"fullhelp") == 0) {
234 char *tmp = strdup(config_string);
235 if (strchr(tmp,
':')) {
236 char *opts = strchr(tmp,
':') + 1;
237 *strchr(tmp,
':') =
'\0';
238 compress_options = opts;
246 <<
MOD_NAME "Unknown or unavailable compression: "
247 << config_string <<
"\n";
253 if (funcs->init_func) {
255 state[0] = funcs->init_func(
parent, compress_options.c_str());
258 <<
MOD_NAME "Compression initialization failed: "
259 << config_string <<
"\n";
273 asynch_consumer_thread = thread(&compress_state_real::async_consumer,
this, proxy);
275 asynch_consumer_thread = thread(&compress_state_real::async_tile_consumer,
this, proxy);
289 struct compress_state_real *s = proxy->
ptr;
291 if(tile_count != s->state.size()) {
292 size_t old_size = s->state.size();
293 s->state.resize(tile_count);
294 for (
unsigned int i = old_size; i < s->state.size(); ++i) {
295 s->state[i] = s->funcs->
init_func(&proxy->
mod, s->compress_options.c_str());
298 "Compression initialization failed\n";
328 struct compress_state_real *s = proxy->
ptr;
355 for(
unsigned i = 0; i < separate_tiles.size(); i++){
363 proxy->
queue.
push(shared_ptr<video_frame>());
367 shared_ptr<video_frame> sync_api_frame;
374 assert(!
"No eligible compress API found");
379 if (!sync_api_frame) {
401 shared_ptr<video_frame>
ret;
425 shared_ptr<video_frame>
frame)
427 struct compress_state_real *s = proxy->
ptr;
428 const int tile_cnt = (int) proxy->
ptr->state.size();
429 vector<shared_ptr<video_frame>> separate_tiles;
436 separate_tiles.resize(tile_cnt);
442 vector<task_result_handle_t> task_handle(tile_cnt);
444 vector <compress_worker_data> data_tile(tile_cnt);
445 for (
int i = 0; i < tile_cnt; ++i) {
447 data->
state = s->state[i];
448 data->
frame = separate_tiles[i];
454 vector<shared_ptr<video_frame>> compressed_tiles(separate_tiles.size());
457 for(
unsigned int i = 0; i < separate_tiles.size(); ++i) {
465 compressed_tiles[i] = data->
ret;
485 if (proxy ==
nullptr) {
489 struct compress_state_real *s = proxy->
ptr;
499compress_state_real::~compress_state_real()
501 if (asynch_consumer_thread.joinable()) {
502 asynch_consumer_thread.join();
505 for(
unsigned int i = 0; i <
state.size(); ++i) {
511void compress_state_real::async_tile_consumer(
struct compress_state *s)
514 vector<shared_ptr<video_frame>> compressed_tiles;
515 unsigned expected_seq = 0;
518 for(
unsigned i = 0; i <
state.size(); i++){
519 std::shared_ptr<video_frame> ret =
nullptr;
523 }
while(ret && ret->seq < expected_seq);
531 if(ret->seq > expected_seq){
533 "Expected sequence number %u but got %u!\n",
538 expected_seq = ret->seq;
540 expected_seq = ret->seq + 1;
547 compressed_tiles.resize(
state.size(),
nullptr);
548 compressed_tiles[i] = std::move(ret);
554 if (!discard_frames) {
558 if(expected_seq > 0) expected_seq++;
567 if (!discard_frames) {
593 MSG(
DEBUG,
"Compressed frame size: %8u; duration: %7.3f ms\n",
struct video_frame * frame
simple blocking synchronized queue
T pop(bool nonblocking=false)
void push(T const &message)
static void new_message(struct module *m)
void log_msg(int level, const char *format,...)
#define LOG_LEVEL_ERROR
general errors
void module_init_default(struct module *module_data)
void module_register(struct module *module_data, struct module *parent)
void module_done(struct module *module_data)
#define VIDEO_COMPRESS_ABI_VERSION
void show_compress_help(bool full)
Displays list of available compressions.
shared_ptr< video_frame > compress_pop(struct compress_state *proxy)
void compress_frame(struct compress_state *proxy, shared_ptr< video_frame > frame)
int compress_init(struct module *parent, const char *config_string, struct compress_state **state)
This function initializes video compression.
std::shared_ptr< video_frame >(* compress_tile_t)(struct module *state, std::shared_ptr< video_frame > in_frame)
Compresses tile of a video frame.
void compress_done(struct compress_state *proxy)
Video compression cleanup function.
void list_modules(enum library_class cls, int abi_version, bool full)
const void * load_library(const char *name, enum library_class cls, int abi_version)
@ LIBRARY_CLASS_VIDEO_COMPRESS
void free_message(struct message *msg, struct response *r)
struct response * new_response(int status, const char *text)
struct response * send_message_to_receiver(struct module *receiver, struct message *msg)
struct message * check_message(struct module *mod)
void free_response(struct response *r)
#define RESPONSE_INT_SERV_ERR
struct module mod
compress module data
synchronized_queue< shared_ptr< video_frame >, 1 > queue
struct compress_state_real * ptr
pointer to real compress state
Auxiliary structure passed to worker thread.
shared_ptr< video_frame > frame
uncompressed tile to be compressed
shared_ptr< video_frame > ret
OUT - returned compressed tile, NULL if failed.
struct module * state
compress driver status
compress_tile_t callback
tile compress callback
enum compress_change_type what
compress_tile_async_push_t compress_tile_async_push_func
Async tile API.
compress_frame_async_pop_t compress_frame_async_pop_func
Async API.
compress_init_t init_func
compress driver initialization function
compress_frame_async_push_t compress_frame_async_push_func
Async API.
compress_frame_t compress_frame_func
compress function for Frame API
compress_tile_t compress_tile_func
compress function for Tile API
compress_tile_async_pop_t compress_tile_async_pop_func
Async tile API.
int64_t compress_start
in ns from epoch
void set_thread_name(const char *name)
static time_ns_t get_time_in_ns()
shared_ptr< video_frame > vf_merge_tiles(std::vector< shared_ptr< video_frame > > const &tiles)
vector< shared_ptr< video_frame > > vf_separate_tiles(shared_ptr< video_frame > frame)
This is an umbrella header for video functions.
static bool check_state_count(unsigned tile_count, struct compress_state *proxy)
static shared_ptr< video_frame > compress_frame_tiles(struct compress_state *proxy, shared_ptr< video_frame > frame)
static void * compress_tile_callback(void *arg)
This function is callback passed to a "thread pool".
static void async_poison(struct compress_state_real *s)
static void compress_process_message(struct compress_state *proxy, struct msg_change_compress_data *data)
Processes message.
API for video compress drivers.
unsigned int vf_get_data_len(struct video_frame *f)
void * wait_task(task_result_handle_t handle)
task_result_handle_t task_run_async(runnable_t task, void *data)
Runs task asynchronously.