diff --git a/src/video_compress.cpp b/src/video_compress.cpp index c375ada28..7a4c9d2c8 100644 --- a/src/video_compress.cpp +++ b/src/video_compress.cpp @@ -371,20 +371,23 @@ void compress_frame(struct compress_state *proxy, shared_ptr frame) for(unsigned i = 0; i < separate_tiles.size(); i++){ s->funcs->compress_tile_async_push_func(s->state[i], separate_tiles[i]); } + return; + } - } else { - if (!frame) { // pass poisoned pill - proxy->queue.push(shared_ptr()); - return; - } + // sync APIs - pass poisoned pill to the queue but not to compressions, + if (!frame) { // which doesn't need that but use NULL frame differently + proxy->queue.push(shared_ptr()); + return; + } - shared_ptr sync_api_frame; + shared_ptr sync_api_frame; + do { if (s->funcs->compress_frame_func) { sync_api_frame = s->funcs->compress_frame_func(s->state[0], frame); } else if(s->funcs->compress_tile_func) { sync_api_frame = compress_frame_tiles(proxy, frame); } else { - assert(!"No egliable compress API found"); + assert(!"No eligible compress API found"); } // empty return value here represents error, but we don't want to pass it to queue, since it would @@ -392,11 +395,10 @@ void compress_frame(struct compress_state *proxy, shared_ptr frame) if (!sync_api_frame) { return; } - sync_api_frame->compress_end = get_time_in_ns(); - proxy->queue.push(sync_api_frame); - } + frame = nullptr; + } while (s->funcs->compress_tile_func != nullptr); } /** @@ -439,19 +441,24 @@ static shared_ptr compress_frame_tiles(struct compress_state *proxy shared_ptr frame) { struct compress_state_real *s = proxy->ptr; - - if(!check_state_count(frame->tile_count, proxy)){ - return NULL; + const int tile_cnt = (int) proxy->ptr->state.size(); + vector> separate_tiles; + if (frame) { + if (!check_state_count(frame->tile_count, proxy)) { + return nullptr; + } + separate_tiles = vf_separate_tiles(frame); + } else { + separate_tiles.resize(tile_cnt); } - vector> separate_tiles = vf_separate_tiles(frame); // frame pointer may no longer be valid frame = NULL; - vector task_handle(separate_tiles.size()); + vector task_handle(tile_cnt); - vector data_tile(separate_tiles.size()); - for(unsigned int i = 0; i < separate_tiles.size(); ++i) { + vector data_tile(tile_cnt); + for (int i = 0; i < tile_cnt; ++i) { struct compress_worker_data *data = &data_tile[i]; data->state = s->state[i]; data->frame = separate_tiles[i]; diff --git a/src/video_compress.h b/src/video_compress.h index 2c59c7f62..e971e38c6 100644 --- a/src/video_compress.h +++ b/src/video_compress.h @@ -68,7 +68,7 @@ #include "types.h" -#define VIDEO_COMPRESS_ABI_VERSION 10 +#define VIDEO_COMPRESS_ABI_VERSION 11 #ifdef __cplusplus extern "C" { @@ -125,7 +125,8 @@ typedef std::shared_ptr (*compress_frame_t)(struct module *state, * @brief Compresses tile of a video frame * * @param[in] state driver internal state - * @param[in] in_frame uncompressed frame containing exactly one tile + * @param[in] in_frame uncompressed frame containing exactly one tile; + * empty shared_ptr to flush remaining tiles * @return compressed frame with one tile, may be NULL if compression failed */ typedef std::shared_ptr (*compress_tile_t)(struct module *state, std::shared_ptr in_frame); diff --git a/src/video_compress/cuda_dxt.cpp b/src/video_compress/cuda_dxt.cpp index c2df710ec..1a6cd9342 100644 --- a/src/video_compress/cuda_dxt.cpp +++ b/src/video_compress/cuda_dxt.cpp @@ -189,6 +189,10 @@ static bool configure_with(struct state_video_compress_cuda_dxt *s, struct video shared_ptr cuda_dxt_compress_tile(struct module *mod, shared_ptr tx) { + if (!tx) { + return {}; + } + struct state_video_compress_cuda_dxt *s = (struct state_video_compress_cuda_dxt *) mod->priv_data; diff --git a/src/video_compress/libavcodec.cpp b/src/video_compress/libavcodec.cpp index dffc0d57e..45d24b6f9 100644 --- a/src/video_compress/libavcodec.cpp +++ b/src/video_compress/libavcodec.cpp @@ -1210,6 +1210,10 @@ restore_metadata(state_video_compress_libav *s, struct video_frame *out, static shared_ptr libavcodec_compress_tile(struct module *mod, shared_ptr tx) { + if (!tx) { + return {}; + } + struct state_video_compress_libav *s = (struct state_video_compress_libav *) mod->priv_data; shared_ptr out{}; list> cleanup_callbacks; // at function exit handlers