diff --git a/src/video_compress.cpp b/src/video_compress.cpp index 2c49052d2..10b519fd5 100644 --- a/src/video_compress.cpp +++ b/src/video_compress.cpp @@ -74,6 +74,7 @@ private: compress_state_real(struct module *parent, const char *config_string); void start(struct compress_state *proxy); void async_consumer(struct compress_state *s); + void async_tile_consumer(struct compress_state *s); thread asynch_consumer_thread; public: static compress_state_real *create(struct module *parent, const char *config_string, @@ -121,8 +122,10 @@ void show_compress_help() static void async_poison(struct compress_state_real *s){ if (s->funcs->compress_frame_async_push_func) { + s->funcs->compress_frame_async_push_func(s->state[0], {}); // poison + } else if (s->funcs->compress_tile_async_push_func){ for(size_t i = 0; i < s->state.size(); i++){ - s->funcs->compress_frame_async_push_func(s->state[i], {}); // poison + s->funcs->compress_tile_async_push_func(s->state[i], {}); // poison } } } @@ -272,6 +275,8 @@ void compress_state_real::start(struct compress_state *proxy) { if (funcs->compress_frame_async_push_func) { asynch_consumer_thread = thread(&compress_state_real::async_consumer, this, proxy); + } else if (funcs->compress_tile_async_push_func){ + asynch_consumer_thread = thread(&compress_state_real::async_tile_consumer, this, proxy); } } @@ -338,6 +343,12 @@ void compress_frame(struct compress_state *proxy, shared_ptr frame) if (s->funcs->compress_frame_async_push_func) { assert(s->funcs->compress_frame_async_pop_func); + if (frame) { + frame->compress_start = t0; + } + s->funcs->compress_frame_async_push_func(s->state[0], frame); + } else if (s->funcs->compress_tile_async_push_func) { + assert(s->funcs->compress_tile_async_pop_func); if (!frame) { async_poison(s); return; @@ -354,7 +365,7 @@ void compress_frame(struct compress_state *proxy, shared_ptr frame) frame = NULL; for(unsigned i = 0; i < separate_tiles.size(); i++){ - s->funcs->compress_frame_async_push_func(s->state[i], separate_tiles[i]); + s->funcs->compress_tile_async_push_func(s->state[i], separate_tiles[i]); } } else { @@ -488,7 +499,7 @@ static void compress_done(struct module *mod) compress_state_real::~compress_state_real() { - if (funcs->compress_frame_async_push_func) { + if (asynch_consumer_thread.joinable()) { asynch_consumer_thread.join(); } @@ -498,7 +509,7 @@ compress_state_real::~compress_state_real() } namespace { -void compress_state_real::async_consumer(struct compress_state *s) +void compress_state_real::async_tile_consumer(struct compress_state *s) { vector> compressed_tiles; unsigned expected_seq = 0; @@ -508,7 +519,7 @@ void compress_state_real::async_consumer(struct compress_state *s) std::shared_ptr ret = nullptr; //discard frames with seq lower than expected do { - ret = funcs->compress_frame_async_pop_func(state[i]); + ret = funcs->compress_tile_async_pop_func(state[i]); } while(ret && ret->seq < expected_seq); if (!ret) { @@ -547,6 +558,23 @@ void compress_state_real::async_consumer(struct compress_state *s) if(expected_seq > 0) expected_seq++; } } + +void compress_state_real::async_consumer(struct compress_state *s) +{ + while (true) { + auto frame = funcs->compress_frame_async_pop_func(state[0]); + if (!discard_frames) { + s->queue.push(frame); + + } + if (!frame) { + return; + + } + + } + +} } // end of anonymous namespace shared_ptr compress_pop(struct compress_state *proxy) diff --git a/src/video_compress.h b/src/video_compress.h index 1e616086f..ec0562430 100644 --- a/src/video_compress.h +++ b/src/video_compress.h @@ -121,6 +121,25 @@ typedef void (*compress_frame_async_push_t)(struct module *state, std::shared_pt */ typedef std::shared_ptr (*compress_frame_async_pop_t)(struct module *state); +/** + * @brief Passes tile to compress module for async processing. + * + * compress_frame_async_pop_t() should be called thereafter to fetch compressed frame. + * + * @param[in] state driver internal state + * @param[in] in_frame uncompressed frame or empty shared_ptr to pass a poisoned pile + */ +typedef void (*compress_tile_async_push_t)(struct module *state, std::shared_ptr in_frame); + +/** + * @brief Fetches compressed tile passed with compress_tile_async_push() + * + * @param[in] state driver internal state + * @return compressed frame, empty shared_ptr corresponding with poisoned + * pill can be also returned + */ +typedef std::shared_ptr (*compress_tile_async_pop_t)(struct module *state); + void compress_frame(struct compress_state *, std::shared_ptr); struct compress_preset { @@ -138,13 +157,14 @@ struct compress_preset { }; /** - * There are 3 possible APIs for video compress modules. Each module may choose + * There are 4 possible APIs for video compress modules. Each module may choose * which one to implement, however, only one should be implemented (there is no * "smart" heuristics to pick one if more APIs are implemented). Available options * are: * 1. Frame API - compress entire frame (all tiles) * 2. Tile API - compress one tile * 3. Async API - compress a frame asynchronously + * 4. Async tile API - compress a tile asynchronously */ struct video_compress_info { const char * name; ///< compress (unique) name @@ -153,6 +173,8 @@ struct video_compress_info { compress_tile_t compress_tile_func; ///< compress function for Tile API compress_frame_async_push_t compress_frame_async_push_func; ///< Async API compress_frame_async_pop_t compress_frame_async_pop_func; ///< Async API + compress_tile_async_push_t compress_tile_async_push_func; ///< Async tile API + compress_tile_async_pop_t compress_tile_async_pop_func; ///< Async tile API std::list (*get_presets)(); ///< list of available presets }; diff --git a/src/video_compress/cineform.cpp b/src/video_compress/cineform.cpp index 6a2fac79d..f5c63409b 100644 --- a/src/video_compress/cineform.cpp +++ b/src/video_compress/cineform.cpp @@ -513,6 +513,8 @@ const struct video_compress_info cineform_info = { cineform_compress_init, NULL, NULL, + NULL, + NULL, cineform_compress_push, cineform_compress_pop, get_cineform_presets, diff --git a/src/video_compress/cmpto_j2k.cpp b/src/video_compress/cmpto_j2k.cpp index 40346ebcc..50c63340b 100644 --- a/src/video_compress/cmpto_j2k.cpp +++ b/src/video_compress/cmpto_j2k.cpp @@ -384,6 +384,8 @@ static struct video_compress_info j2k_compress_info = { j2k_compress_init, NULL, NULL, + NULL, + NULL, j2k_compress_push, j2k_compress_pop, [] { return list{}; } diff --git a/src/video_compress/cuda_dxt.cpp b/src/video_compress/cuda_dxt.cpp index 783a4cf76..cd59e0efb 100644 --- a/src/video_compress/cuda_dxt.cpp +++ b/src/video_compress/cuda_dxt.cpp @@ -289,6 +289,8 @@ const struct video_compress_info cuda_dxt_info = { cuda_dxt_compress_tile, NULL, NULL, + NULL, + NULL, [] { return list{}; } }; diff --git a/src/video_compress/dxt_glsl.cpp b/src/video_compress/dxt_glsl.cpp index 56beffbe7..c033ffe7b 100644 --- a/src/video_compress/dxt_glsl.cpp +++ b/src/video_compress/dxt_glsl.cpp @@ -330,6 +330,8 @@ const struct video_compress_info rtdxt_info = { NULL, NULL, NULL, + NULL, + NULL, [] { return dxt_is_supported() ? list{ { "DXT1", 35, [](const struct video_desc *d){return (long)(d->width * d->height * d->fps * 4.0);}, diff --git a/src/video_compress/jpeg.cpp b/src/video_compress/jpeg.cpp index 7528dc5c1..713432ce4 100644 --- a/src/video_compress/jpeg.cpp +++ b/src/video_compress/jpeg.cpp @@ -588,6 +588,8 @@ const struct video_compress_info jpeg_info = { [](struct module *mod) { return static_cast(mod->priv_data)->pop(); }, + NULL, + NULL, [] { return gpujpeg_init_device(cuda_devices[0], TRUE) == 0 ? list{ { "60", 60, [](const struct video_desc *d){return (long)(d->width * d->height * d->fps * 0.68);}, diff --git a/src/video_compress/libavcodec.cpp b/src/video_compress/libavcodec.cpp index c3b4ab500..2fd9c34ed 100644 --- a/src/video_compress/libavcodec.cpp +++ b/src/video_compress/libavcodec.cpp @@ -1782,6 +1782,8 @@ const struct video_compress_info libavcodec_info = { libavcodec_compress_tile, NULL, NULL, + NULL, + NULL, get_libavcodec_presets, }; diff --git a/src/video_compress/none.cpp b/src/video_compress/none.cpp index d1fca86f3..ec57ea115 100644 --- a/src/video_compress/none.cpp +++ b/src/video_compress/none.cpp @@ -113,6 +113,8 @@ const struct video_compress_info none_info = { NULL, NULL, NULL, + NULL, + NULL, [] { return std::list{ { "", 100, [](const struct video_desc *d){return (long)(d->width * d->height * d->fps * get_bpp(d->color_spec) * 8.0);}, diff --git a/src/video_compress/uyvy.cpp b/src/video_compress/uyvy.cpp index eac0a6805..50b424372 100644 --- a/src/video_compress/uyvy.cpp +++ b/src/video_compress/uyvy.cpp @@ -306,6 +306,8 @@ const struct video_compress_info uyvy_info = { NULL, NULL, NULL, + NULL, + NULL, [] {return list{}; } };