mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 22:40:30 +00:00
Compress sync tile API: fetch additional frames
Modified the API in order to fetch additional frames from compression
with iterative passing NULL pointer (similarly as for audio).
This is particularly usefull when inter-frame compression outputs 2
frames at once, which can occur when B-frames would be enabled. It,
however sometimes happen even when B-frames are disbled, eg. with
h264/hevc_mf HW encoder on AMD (AMDh265Encoder; see commit d70e2fb3c).
Please note that semantic of passing NUL frame is different in this API
to that in async API, where it works as a poison pill.
This commit is contained in:
@@ -371,20 +371,23 @@ void compress_frame(struct compress_state *proxy, shared_ptr<video_frame> 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<video_frame>());
|
||||
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<video_frame>());
|
||||
return;
|
||||
}
|
||||
|
||||
shared_ptr<video_frame> sync_api_frame;
|
||||
shared_ptr<video_frame> 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<video_frame> 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<video_frame> compress_frame_tiles(struct compress_state *proxy
|
||||
shared_ptr<video_frame> 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<shared_ptr<video_frame>> 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<shared_ptr<video_frame>> separate_tiles = vf_separate_tiles(frame);
|
||||
// frame pointer may no longer be valid
|
||||
frame = NULL;
|
||||
|
||||
vector<task_result_handle_t> task_handle(separate_tiles.size());
|
||||
vector<task_result_handle_t> task_handle(tile_cnt);
|
||||
|
||||
vector <compress_worker_data> data_tile(separate_tiles.size());
|
||||
for(unsigned int i = 0; i < separate_tiles.size(); ++i) {
|
||||
vector <compress_worker_data> 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];
|
||||
|
||||
@@ -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<video_frame> (*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<video_frame> (*compress_tile_t)(struct module *state, std::shared_ptr<video_frame> in_frame);
|
||||
|
||||
@@ -189,6 +189,10 @@ static bool configure_with(struct state_video_compress_cuda_dxt *s, struct video
|
||||
|
||||
shared_ptr<video_frame> cuda_dxt_compress_tile(struct module *mod, shared_ptr<video_frame> tx)
|
||||
{
|
||||
if (!tx) {
|
||||
return {};
|
||||
}
|
||||
|
||||
struct state_video_compress_cuda_dxt *s =
|
||||
(struct state_video_compress_cuda_dxt *) mod->priv_data;
|
||||
|
||||
|
||||
@@ -1210,6 +1210,10 @@ restore_metadata(state_video_compress_libav *s, struct video_frame *out,
|
||||
|
||||
static shared_ptr<video_frame> libavcodec_compress_tile(struct module *mod, shared_ptr<video_frame> tx)
|
||||
{
|
||||
if (!tx) {
|
||||
return {};
|
||||
}
|
||||
|
||||
struct state_video_compress_libav *s = (struct state_video_compress_libav *) mod->priv_data;
|
||||
shared_ptr<video_frame> out{};
|
||||
list<shared_ptr<void>> cleanup_callbacks; // at function exit handlers
|
||||
|
||||
Reference in New Issue
Block a user