video display: updated putf api - use timeout

Replace blocking/nonblock/discard flags with numerical timeout for
fine-grainer control of latency.

The original flags are kept as convenience macros so the API changes is
only small as long as non-block (default) or blocking is used.
This commit is contained in:
Martin Pulec
2022-10-04 16:04:37 +02:00
parent e1dcefc9d2
commit 00801fa3d4
26 changed files with 45 additions and 44 deletions

View File

@@ -75,7 +75,7 @@ __declspec(dllimport) int display_aja_reconfigure(void *state, struct video_desc
__declspec(dllimport) void *display_aja_init(struct module * /* parent */, const char *fmt, unsigned int flags);
__declspec(dllimport) void display_aja_done(void *state);
__declspec(dllimport) struct video_frame *display_aja_getf(void *state);
__declspec(dllimport) int display_aja_putf(void *state, struct video_frame *frame, int nonblock);
__declspec(dllimport) int display_aja_putf(void *state, struct video_frame *frame, long long nonblock);
__declspec(dllimport) void display_aja_put_audio_frame(void *state, const struct audio_frame *frame);
__declspec(dllimport) int display_aja_reconfigure_audio(void *state, int quant_samples, int channels,
int sample_rate);

View File

@@ -357,16 +357,17 @@ struct video_frame *display_get_frame(struct display *d)
* @param d display to be putted frame to
* @param frame frame that has been obtained from display_get_frame() and has not yet been put.
* Should not be NULL unless we want to quit display mainloop.
* @param flags specifies blocking behavior (@ref display_put_frame_flags)
* @param timeout_ns specifies timeout that should be waited (@sa putf_flags).
* displays may ignore the value and act like PUTF_NONBLOCK if blocking is not requested.
* @retval 0 if displayed succesfully (or discarded if flag=PUTF_DISCARD)
* @retval 1 if not displayed when flag=PUTF_NONBLOCK and it would block
*/
int display_put_frame(struct display *d, struct video_frame *frame, int flag)
int display_put_frame(struct display *d, struct video_frame *frame, long long timeout_ns)
{
assert(d->magic == DISPLAY_MAGIC);
if (!frame) {
return d->funcs->putf(d->state, frame, flag);
return d->funcs->putf(d->state, frame, timeout_ns);
}
if (d->postprocess) {
@@ -383,11 +384,11 @@ int display_put_frame(struct display *d, struct video_frame *frame, int flag)
return 1;
}
display_ret = d->funcs->putf(d->state, display_frame, flag);
display_ret = d->funcs->putf(d->state, display_frame, timeout_ns);
}
return display_ret;
}
int ret = d->funcs->putf(d->state, frame, flag);
int ret = d->funcs->putf(d->state, frame, timeout_ns);
if (ret != 0 || !d->funcs->generic_fps_indicator_prefix) {
return ret;
}

View File

@@ -141,7 +141,7 @@ enum display_prop_vid_mode {
};
/// @}
#define VIDEO_DISPLAY_ABI_VERSION 15
#define VIDEO_DISPLAY_ABI_VERSION 16
typedef bool (*display_needs_mainloop_t)(void *);
#define DISPLAY_DOESNT_NEED_MAINLOOP ((display_needs_mainloop_t) 0x00)
@@ -155,7 +155,7 @@ struct video_display_info {
void (*run) (void *state); ///< may be NULL
void (*done) (void *state);
struct video_frame *(*getf) (void *state);
int (*putf) (void *state, struct video_frame *frame, int nonblock); ///< @copydoc display_put_frame
int (*putf) (void *state, struct video_frame *frame, long long timeout_ns); ///< @copydoc display_put_frame
int (*reconfigure_video)(void *state, struct video_desc desc);
int (*ctl_property)(void *state, int property, void *val, size_t *len);
void (*put_audio_frame) (void *state, const struct audio_frame *frame); ///< may be NULL
@@ -185,15 +185,15 @@ void display_join(struct display *d);
void display_done(struct display *d);
struct video_frame *display_get_frame(struct display *d);
/** @brief putf flags */
enum display_put_frame_flags {
PUTF_BLOCKING = 0, ///< Block until frame can be displayed.
PUTF_NONBLOCK = 1, ///< Do not block.
PUTF_DISCARD = 2,
};
/** @ancor putf_flags
* { */
#define PUTF_DISCARD (-1LL)
#define PUTF_NONBLOCK 0LL
#define PUTF_BLOCKING LLONG_MAX
/// }
// documented at definition
int display_put_frame(struct display *d, struct video_frame *frame, int flag);
int display_put_frame(struct display *d, struct video_frame *frame, long long timeout_ns);
int display_reconfigure(struct display *d, struct video_desc desc, enum video_mode mode);
/** @brief Get/set property (similar to ioctl)
* @retval TRUE if succeeds

View File

@@ -211,7 +211,7 @@ static struct video_frame *display_aggregate_getf(void *state)
return s->frame;
}
static int display_aggregate_putf(void *state, struct video_frame *frame, int nonblock)
static int display_aggregate_putf(void *state, struct video_frame *frame, long long nonblock)
{
unsigned int i;
struct display_aggregate_state *s = (struct display_aggregate_state *)state;

View File

@@ -201,7 +201,7 @@ public:
AJAStatus SetUpVideo();
AJAStatus SetUpAudio();
void RouteOutputSignal();
int Putf(struct video_frame *frame, int nonblock);
int Putf(struct video_frame *frame, long long nonblock);
static NTV2FrameRate getFrameRate(double fps);
void print_stats();
@@ -686,7 +686,7 @@ void display::process_frames()
}
}
int display::Putf(struct video_frame *frame, int flags) {
int display::Putf(struct video_frame *frame, long long flags) {
if (frame == nullptr) {
return 1;
}
@@ -1012,7 +1012,7 @@ LINK_SPEC struct video_frame *display_aja_getf(void *state)
return vf_alloc_desc_data(s->desc);
}
LINK_SPEC int display_aja_putf(void *state, struct video_frame *frame, int nonblock)
LINK_SPEC int display_aja_putf(void *state, struct video_frame *frame, long long nonblock)
{
auto s = static_cast<struct aja::display *>(state);

View File

@@ -336,7 +336,7 @@ static struct video_frame *display_blend_getf(void *state)
return vf_alloc_desc_data(s->desc);
}
static int display_blend_putf(void *state, struct video_frame *frame, int flags)
static int display_blend_putf(void *state, struct video_frame *frame, long long flags)
{
shared_ptr<struct state_blend_common> s = ((struct state_blend *)state)->common;

View File

@@ -889,7 +889,7 @@ display_bluefish444_getf(void *state)
return frame;
}
static int display_bluefish444_putf(void *state, struct video_frame *frame, int nonblock)
static int display_bluefish444_putf(void *state, struct video_frame *frame, long long nonblock)
{
UNUSED(nonblock);
display_bluefish444_state *s =

View File

@@ -703,7 +703,7 @@ static struct video_frame *display_conference_getf(void *state)
return vf_alloc_desc_data(s->desc);
}
static int display_conference_putf(void *state, struct video_frame *frame, int flags)
static int display_conference_putf(void *state, struct video_frame *frame, long long flags)
{
auto s = static_cast<state_conference *>(state)->common;

View File

@@ -106,7 +106,7 @@ using namespace std;
using rang::fg;
using rang::style;
static int display_decklink_putf(void *state, struct video_frame *frame, int nonblock);
static int display_decklink_putf(void *state, struct video_frame *frame, long long nonblock);
namespace {
class PlaybackDelegate : public IDeckLinkVideoOutputCallback // , public IDeckLinkAudioOutputCallback
@@ -116,7 +116,7 @@ private:
uint64_t frames_flushed = 0;
uint64_t frames_late = 0;
friend int ::display_decklink_putf(void *state, struct video_frame *frame, int nonblock);
friend int ::display_decklink_putf(void *state, struct video_frame *frame, long long nonblock);
public:
virtual ~PlaybackDelegate() = default;
// IUnknown needs only a dummy implementation
@@ -576,7 +576,7 @@ static void update_timecode(DeckLinkTimecode *tc, double fps)
tc->SetBCD(bcd);
}
static int display_decklink_putf(void *state, struct video_frame *frame, int flag)
static int display_decklink_putf(void *state, struct video_frame *frame, long long flag)
{
struct state_decklink *s = (struct state_decklink *)state;

View File

@@ -123,7 +123,7 @@ display_deltacast_getf(void *state)
return s->frame;
}
static int display_deltacast_putf(void *state, struct video_frame *frame, int nonblock)
static int display_deltacast_putf(void *state, struct video_frame *frame, long long nonblock)
{
struct state_deltacast *s = (struct state_deltacast *)state;
struct timeval tv;

View File

@@ -154,7 +154,7 @@ static void dump_buf(unsigned char *buf, size_t len, int block_size) {
printf("\n");
}
static int display_dummy_putf(void *state, struct video_frame *frame, int flags)
static int display_dummy_putf(void *state, struct video_frame *frame, long long flags)
{
if (flags == PUTF_DISCARD || frame == nullptr) {
return 0;

View File

@@ -112,7 +112,7 @@ static struct video_frame *display_dump_getf(void *state)
return s->f;
}
static int display_dump_putf(void *state, struct video_frame *frame, int flags)
static int display_dump_putf(void *state, struct video_frame *frame, long long flags)
{
struct dump_display_state *s = state;
if (frame == NULL || flags == PUTF_DISCARD) {

View File

@@ -493,7 +493,7 @@ display_dvs_getf(void *state)
return s->frame;
}
static int display_dvs_putf(void *state, struct video_frame *frame, int flags)
static int display_dvs_putf(void *state, struct video_frame *frame, long long flags)
{
struct state_hdsp *s = (struct state_hdsp *)state;

View File

@@ -396,7 +396,7 @@ static constexpr array gl_supp_codecs = {
/* Prototyping */
static bool display_gl_init_opengl(struct state_gl *s);
static int display_gl_putf(void *state, struct video_frame *frame, int nonblock);
static int display_gl_putf(void *state, struct video_frame *frame, long long timeout);
static bool display_gl_process_key(struct state_gl *s, long long int key);
static int display_gl_reconfigure(void *state, struct video_desc desc);
@@ -1808,7 +1808,7 @@ static struct video_frame * display_gl_getf(void *state)
return buffer;
}
static int display_gl_putf(void *state, struct video_frame *frame, int nonblock)
static int display_gl_putf(void *state, struct video_frame *frame, long long nonblock)
{
struct state_gl *s = (struct state_gl *) state;

View File

@@ -228,7 +228,7 @@ static struct video_frame *display_multiplier_getf(void *state)
return vf_alloc_desc_data(s->desc);
}
static int display_multiplier_putf(void *state, struct video_frame *frame, int flags)
static int display_multiplier_putf(void *state, struct video_frame *frame, long long flags)
{
shared_ptr<struct state_multiplier_common> s = ((struct state_multiplier *)state)->common;

View File

@@ -318,7 +318,7 @@ static void ndi_disp_convert_Y416_to_PA16(const struct video_frame *f, char *out
/**
* flag = PUTF_NONBLOCK is not implemented
*/
static int display_ndi_putf(void *state, struct video_frame *frame, int flag)
static int display_ndi_putf(void *state, struct video_frame *frame, long long flag)
{
struct display_ndi *s = (struct display_ndi *) state;

View File

@@ -97,7 +97,7 @@ static struct video_frame *display_null_getf(void *state)
return NULL;
}
static int display_null_putf(void *state, struct video_frame *frame, int nonblock)
static int display_null_putf(void *state, struct video_frame *frame, long long nonblock)
{
struct state_null *s = (struct state_null *)state;
assert(s->magic == MAGIC_NULL);

View File

@@ -1020,7 +1020,7 @@ static struct video_frame * display_xrgl_getf(void *state) {
}
}
static int display_xrgl_putf(void *state, struct video_frame *frame, int nonblock) {
static int display_xrgl_putf(void *state, struct video_frame *frame, long long nonblock) {
struct state_xrgl *s = static_cast<state_xrgl *>(state);
std::unique_lock<std::mutex> lk(s->lock);

View File

@@ -273,7 +273,7 @@ static struct video_frame * display_panogl_getf(void *state) {
return vf_alloc_desc_data(s->current_desc);
}
static int display_panogl_putf(void *state, struct video_frame *frame, int nonblock) {
static int display_panogl_putf(void *state, struct video_frame *frame, long long nonblock) {
PROFILE_FUNC;
struct state_vr *s = static_cast<state_vr *>(state);

View File

@@ -184,7 +184,7 @@ static struct audio_frame * display_pipe_get_audio(struct state_pipe *s)
return out;
}
static int display_pipe_putf(void *state, struct video_frame *frame, int flags)
static int display_pipe_putf(void *state, struct video_frame *frame, long long flags)
{
struct state_pipe *s = (struct state_pipe *) state;

View File

@@ -497,7 +497,7 @@ static struct video_frame *display_rpi4_getf(void *state) {
return new_frame;
}
static int display_rpi4_putf(void *state, struct video_frame *frame, int flags)
static int display_rpi4_putf(void *state, struct video_frame *frame, long long flags)
{
auto *s = static_cast<rpi4_display_state *>(state);

View File

@@ -330,7 +330,7 @@ static struct video_frame *display_sage_getf(void *state)
return s->frame;
}
static int display_sage_putf(void *state, struct video_frame *frame, int nonblock)
static int display_sage_putf(void *state, struct video_frame *frame, long long nonblock)
{
int tmp;
struct state_sage *s = (struct state_sage *)state;

View File

@@ -142,7 +142,7 @@ struct state_sdl {
static void loadSplashscreen(struct state_sdl *s);
static void show_help(void);
static int display_sdl_putf(void *state, struct video_frame *frame, int nonblock);
static int display_sdl_putf(void *state, struct video_frame *frame, long long nonblock);
static int display_sdl_reconfigure(void *state, struct video_desc desc);
static int display_sdl_reconfigure_real(void *state, struct video_desc desc);

View File

@@ -98,7 +98,7 @@ using namespace std::chrono;
static void show_help(void);
static void display_sdl2_new_message(struct module *);
static int display_sdl2_putf(void *state, struct video_frame *frame, int nonblock);
static int display_sdl2_putf(void *state, struct video_frame *frame, long long nonblock);
static int display_sdl2_reconfigure(void *state, struct video_desc desc);
static int display_sdl2_reconfigure_real(void *state, struct video_desc desc);
@@ -701,7 +701,7 @@ static struct video_frame *display_sdl2_getf(void *state)
return vf_alloc_desc_data(s->current_desc);
}
static int display_sdl2_putf(void *state, struct video_frame *frame, int nonblock)
static int display_sdl2_putf(void *state, struct video_frame *frame, long long nonblock)
{
struct state_sdl2 *s = (struct state_sdl2 *)state;

View File

@@ -244,7 +244,7 @@ static struct video_frame *display_unix_sock_getf(void *state)
return vf_alloc_desc_data(s->desc);
}
static int display_unix_sock_putf(void *state, struct video_frame *frame, int flags)
static int display_unix_sock_putf(void *state, struct video_frame *frame, long long flags)
{
auto s = static_cast<state_unix_sock *>(state);
auto f = unique_frame(frame);

View File

@@ -220,7 +220,7 @@ static struct video_frame *display_v4l2_getf(void *state)
return s->f;
}
static int display_v4l2_putf(void *state, struct video_frame *frame, int nonblock)
static int display_v4l2_putf(void *state, struct video_frame *frame, long long nonblock)
{
UNUSED(nonblock);
struct display_v4l2_state *s = state;