mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 15:40:21 +00:00
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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user