Remove video_buffer callbacks
Now that screen is both the owner and the listener of the video buffer, execute the code directly without callbacks.
This commit is contained in:
parent
e91acdb0c4
commit
2a94a2b119
3 changed files with 27 additions and 73 deletions
|
@ -193,27 +193,6 @@ screen_update_content_rect(struct screen *screen) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
on_frame_available(struct video_buffer *vb, void *userdata) {
|
|
||||||
(void) vb;
|
|
||||||
(void) userdata;
|
|
||||||
|
|
||||||
static SDL_Event new_frame_event = {
|
|
||||||
.type = EVENT_NEW_FRAME,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Post the event on the UI thread
|
|
||||||
SDL_PushEvent(&new_frame_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_frame_skipped(struct video_buffer *vb, void *userdata) {
|
|
||||||
(void) vb;
|
|
||||||
|
|
||||||
struct screen *screen = userdata;
|
|
||||||
fps_counter_add_skipped_frame(screen->fps_counter);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline SDL_Texture *
|
static inline SDL_Texture *
|
||||||
create_texture(struct screen *screen) {
|
create_texture(struct screen *screen) {
|
||||||
SDL_Renderer *renderer = screen->renderer;
|
SDL_Renderer *renderer = screen->renderer;
|
||||||
|
@ -284,7 +263,27 @@ screen_frame_sink_close(struct sc_frame_sink *sink) {
|
||||||
static bool
|
static bool
|
||||||
screen_frame_sink_push(struct sc_frame_sink *sink, const AVFrame *frame) {
|
screen_frame_sink_push(struct sc_frame_sink *sink, const AVFrame *frame) {
|
||||||
struct screen *screen = DOWNCAST(sink);
|
struct screen *screen = DOWNCAST(sink);
|
||||||
return video_buffer_push(&screen->vb, frame);
|
|
||||||
|
bool previous_frame_skipped;
|
||||||
|
bool ok = video_buffer_push(&screen->vb, frame, &previous_frame_skipped);
|
||||||
|
if (!ok) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previous_frame_skipped) {
|
||||||
|
fps_counter_add_skipped_frame(screen->fps_counter);
|
||||||
|
// The EVENT_NEW_FRAME triggered for the previous frame will consume
|
||||||
|
// this new frame instead
|
||||||
|
} else {
|
||||||
|
static SDL_Event new_frame_event = {
|
||||||
|
.type = EVENT_NEW_FRAME,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Post the event on the UI thread
|
||||||
|
SDL_PushEvent(&new_frame_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -303,12 +302,6 @@ screen_init(struct screen *screen, struct fps_counter *fps_counter,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct video_buffer_callbacks cbs = {
|
|
||||||
.on_frame_available = on_frame_available,
|
|
||||||
.on_frame_skipped = on_frame_skipped,
|
|
||||||
};
|
|
||||||
video_buffer_set_consumer_callbacks(&screen->vb, &cbs, screen);
|
|
||||||
|
|
||||||
screen->frame_size = params->frame_size;
|
screen->frame_size = params->frame_size;
|
||||||
screen->rotation = params->rotation;
|
screen->rotation = params->rotation;
|
||||||
if (screen->rotation) {
|
if (screen->rotation) {
|
||||||
|
|
|
@ -29,10 +29,6 @@ video_buffer_init(struct video_buffer *vb) {
|
||||||
// there is initially no frame, so consider it has already been consumed
|
// there is initially no frame, so consider it has already been consumed
|
||||||
vb->pending_frame_consumed = true;
|
vb->pending_frame_consumed = true;
|
||||||
|
|
||||||
// The callbacks must be set by the consumer via
|
|
||||||
// video_buffer_set_consumer_callbacks()
|
|
||||||
vb->cbs = NULL;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,21 +46,9 @@ swap_frames(AVFrame **lhs, AVFrame **rhs) {
|
||||||
*rhs = tmp;
|
*rhs = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
video_buffer_set_consumer_callbacks(struct video_buffer *vb,
|
|
||||||
const struct video_buffer_callbacks *cbs,
|
|
||||||
void *cbs_userdata) {
|
|
||||||
assert(!vb->cbs); // must be set only once
|
|
||||||
assert(cbs);
|
|
||||||
assert(cbs->on_frame_available);
|
|
||||||
vb->cbs = cbs;
|
|
||||||
vb->cbs_userdata = cbs_userdata;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
video_buffer_push(struct video_buffer *vb, const AVFrame *frame) {
|
video_buffer_push(struct video_buffer *vb, const AVFrame *frame,
|
||||||
assert(vb->cbs);
|
bool *previous_frame_skipped) {
|
||||||
|
|
||||||
sc_mutex_lock(&vb->mutex);
|
sc_mutex_lock(&vb->mutex);
|
||||||
|
|
||||||
// Use a temporary frame to preserve pending_frame in case of error.
|
// Use a temporary frame to preserve pending_frame in case of error.
|
||||||
|
@ -80,18 +64,13 @@ video_buffer_push(struct video_buffer *vb, const AVFrame *frame) {
|
||||||
swap_frames(&vb->pending_frame, &vb->tmp_frame);
|
swap_frames(&vb->pending_frame, &vb->tmp_frame);
|
||||||
av_frame_unref(vb->tmp_frame);
|
av_frame_unref(vb->tmp_frame);
|
||||||
|
|
||||||
bool skipped = !vb->pending_frame_consumed;
|
if (previous_frame_skipped) {
|
||||||
|
*previous_frame_skipped = !vb->pending_frame_consumed;
|
||||||
|
}
|
||||||
vb->pending_frame_consumed = false;
|
vb->pending_frame_consumed = false;
|
||||||
|
|
||||||
sc_mutex_unlock(&vb->mutex);
|
sc_mutex_unlock(&vb->mutex);
|
||||||
|
|
||||||
if (skipped) {
|
|
||||||
if (vb->cbs->on_frame_skipped)
|
|
||||||
vb->cbs->on_frame_skipped(vb, vb->cbs_userdata);
|
|
||||||
} else {
|
|
||||||
vb->cbs->on_frame_available(vb, vb->cbs_userdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,19 +33,6 @@ struct video_buffer {
|
||||||
sc_mutex mutex;
|
sc_mutex mutex;
|
||||||
|
|
||||||
bool pending_frame_consumed;
|
bool pending_frame_consumed;
|
||||||
|
|
||||||
const struct video_buffer_callbacks *cbs;
|
|
||||||
void *cbs_userdata;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct video_buffer_callbacks {
|
|
||||||
// Called when a new frame can be consumed.
|
|
||||||
// This callback is mandatory (it must not be NULL).
|
|
||||||
void (*on_frame_available)(struct video_buffer *vb, void *userdata);
|
|
||||||
|
|
||||||
// Called when a pending frame has been overwritten by the producer.
|
|
||||||
// This callback is optional (it may be NULL).
|
|
||||||
void (*on_frame_skipped)(struct video_buffer *vb, void *userdata);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -54,13 +41,8 @@ video_buffer_init(struct video_buffer *vb);
|
||||||
void
|
void
|
||||||
video_buffer_destroy(struct video_buffer *vb);
|
video_buffer_destroy(struct video_buffer *vb);
|
||||||
|
|
||||||
void
|
|
||||||
video_buffer_set_consumer_callbacks(struct video_buffer *vb,
|
|
||||||
const struct video_buffer_callbacks *cbs,
|
|
||||||
void *cbs_userdata);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
video_buffer_push(struct video_buffer *vb, const AVFrame *frame);
|
video_buffer_push(struct video_buffer *vb, const AVFrame *frame, bool *skipped);
|
||||||
|
|
||||||
void
|
void
|
||||||
video_buffer_consume(struct video_buffer *vb, AVFrame *dst);
|
video_buffer_consume(struct video_buffer *vb, AVFrame *dst);
|
||||||
|
|
Loading…
Reference in a new issue