mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 23:40:26 +00:00
Separate async frame and async tile APIs
This commit is contained in:
@@ -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<video_frame> 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<video_frame> 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<shared_ptr<video_frame>> compressed_tiles;
|
||||
unsigned expected_seq = 0;
|
||||
@@ -508,7 +519,7 @@ void compress_state_real::async_consumer(struct compress_state *s)
|
||||
std::shared_ptr<video_frame> 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<video_frame> compress_pop(struct compress_state *proxy)
|
||||
|
||||
@@ -121,6 +121,25 @@ typedef void (*compress_frame_async_push_t)(struct module *state, std::shared_pt
|
||||
*/
|
||||
typedef std::shared_ptr<video_frame> (*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<video_frame> 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<video_frame> (*compress_tile_async_pop_t)(struct module *state);
|
||||
|
||||
void compress_frame(struct compress_state *, std::shared_ptr<video_frame>);
|
||||
|
||||
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<compress_preset> (*get_presets)(); ///< list of available presets
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<compress_preset>{}; }
|
||||
|
||||
@@ -289,6 +289,8 @@ const struct video_compress_info cuda_dxt_info = {
|
||||
cuda_dxt_compress_tile,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
[] { return list<compress_preset>{}; }
|
||||
};
|
||||
|
||||
|
||||
@@ -330,6 +330,8 @@ const struct video_compress_info rtdxt_info = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
[] {
|
||||
return dxt_is_supported() ? list<compress_preset>{
|
||||
{ "DXT1", 35, [](const struct video_desc *d){return (long)(d->width * d->height * d->fps * 4.0);},
|
||||
|
||||
@@ -588,6 +588,8 @@ const struct video_compress_info jpeg_info = {
|
||||
[](struct module *mod) {
|
||||
return static_cast<struct state_video_compress_jpeg *>(mod->priv_data)->pop();
|
||||
},
|
||||
NULL,
|
||||
NULL,
|
||||
[] {
|
||||
return gpujpeg_init_device(cuda_devices[0], TRUE) == 0 ? list<compress_preset>{
|
||||
{ "60", 60, [](const struct video_desc *d){return (long)(d->width * d->height * d->fps * 0.68);},
|
||||
|
||||
@@ -1782,6 +1782,8 @@ const struct video_compress_info libavcodec_info = {
|
||||
libavcodec_compress_tile,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
get_libavcodec_presets,
|
||||
};
|
||||
|
||||
|
||||
@@ -113,6 +113,8 @@ const struct video_compress_info none_info = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
[] {
|
||||
return std::list<compress_preset>{
|
||||
{ "", 100, [](const struct video_desc *d){return (long)(d->width * d->height * d->fps * get_bpp(d->color_spec) * 8.0);},
|
||||
|
||||
@@ -306,6 +306,8 @@ const struct video_compress_info uyvy_info = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
[] {return list<compress_preset>{}; }
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user