summaryrefslogtreecommitdiffstats
path: root/video/out/vo_opengl_cb.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/vo_opengl_cb.c')
-rw-r--r--video/out/vo_opengl_cb.c104
1 files changed, 47 insertions, 57 deletions
diff --git a/video/out/vo_opengl_cb.c b/video/out/vo_opengl_cb.c
index 96a312f98c..c1a8748f4e 100644
--- a/video/out/vo_opengl_cb.c
+++ b/video/out/vo_opengl_cb.c
@@ -64,9 +64,10 @@ struct mpv_opengl_cb_context {
bool initialized;
mpv_opengl_cb_update_fn update_cb;
void *update_cb_ctx;
- struct mp_image *waiting_frame;
- struct mp_image **frame_queue;
+ struct vo_frame *waiting_frame;
+ struct vo_frame **frame_queue;
int queued_frames;
+ struct vo_frame *cur_frame;
struct mp_image_params img_params;
bool reconfigured;
int vp_w, vp_h;
@@ -81,7 +82,6 @@ struct mpv_opengl_cb_context {
struct mp_csp_equalizer eq;
int64_t recent_flip;
int64_t approx_vsync;
- int64_t cur_pts;
bool vsync_timed;
// --- All of these can only be accessed from the thread where the host
@@ -103,11 +103,11 @@ static void update(struct vo_priv *p);
// all queue manipulation functions shold be called under locked state
-static struct mp_image *frame_queue_pop(struct mpv_opengl_cb_context *ctx)
+static struct vo_frame *frame_queue_pop(struct mpv_opengl_cb_context *ctx)
{
if (ctx->queued_frames == 0)
return NULL;
- struct mp_image *ret = ctx->frame_queue[0];
+ struct vo_frame *ret = ctx->frame_queue[0];
MP_TARRAY_REMOVE_AT(ctx->frame_queue, ctx->queued_frames, 0);
pthread_cond_broadcast(&ctx->wakeup);
return ret;
@@ -115,9 +115,9 @@ static struct mp_image *frame_queue_pop(struct mpv_opengl_cb_context *ctx)
static void frame_queue_drop(struct mpv_opengl_cb_context *ctx)
{
- struct mp_image *mpi = frame_queue_pop(ctx);
- if (mpi) {
- talloc_free(mpi);
+ struct vo_frame *frame = frame_queue_pop(ctx);
+ if (frame) {
+ talloc_free(frame);
if (ctx->active)
vo_increment_drop_count(ctx->active, 1);
pthread_cond_broadcast(&ctx->wakeup);
@@ -143,9 +143,10 @@ static void frame_queue_drop_all(struct mpv_opengl_cb_context *ctx)
pthread_cond_broadcast(&ctx->wakeup);
}
-static void frame_queue_push(struct mpv_opengl_cb_context *ctx, struct mp_image *mpi)
+static void frame_queue_push(struct mpv_opengl_cb_context *ctx,
+ struct vo_frame *frame)
{
- MP_TARRAY_APPEND(ctx, ctx->frame_queue, ctx->queued_frames, mpi);
+ MP_TARRAY_APPEND(ctx, ctx->frame_queue, ctx->queued_frames, frame);
pthread_cond_broadcast(&ctx->wakeup);
}
@@ -156,11 +157,16 @@ static void frame_queue_shrink(struct mpv_opengl_cb_context *ctx, int size)
frame_queue_drop(ctx);
}
-static void forget_frames(struct mpv_opengl_cb_context *ctx)
+static void forget_frames(struct mpv_opengl_cb_context *ctx, bool all)
{
pthread_cond_broadcast(&ctx->wakeup);
frame_queue_clear(ctx);
- mp_image_unrefp(&ctx->waiting_frame);
+ talloc_free(ctx->waiting_frame);
+ ctx->waiting_frame = NULL;
+ if (all) {
+ talloc_free(ctx->cur_frame);
+ ctx->cur_frame = NULL;
+ }
}
static void free_ctx(void *ptr)
@@ -261,7 +267,7 @@ int mpv_opengl_cb_uninit_gl(struct mpv_opengl_cb_context *ctx)
// context. Setting initialized=false guarantees it can't come back.
pthread_mutex_lock(&ctx->lock);
- forget_frames(ctx);
+ forget_frames(ctx, true);
ctx->initialized = false;
pthread_mutex_unlock(&ctx->lock);
@@ -352,30 +358,31 @@ int mpv_opengl_cb_draw(mpv_opengl_cb_context *ctx, int fbo, int vp_w, int vp_h)
ctx->eq_changed = false;
ctx->eq = *eq;
- struct mp_image *mpi = frame_queue_pop(ctx);
- if (mpi) {
- struct frame_timing *t = mpi->priv; // set by draw_image_timed
- if (t)
- ctx->cur_pts = t->pts;
+ struct vo_frame *frame = frame_queue_pop(ctx);
+ if (frame) {
+ talloc_free(ctx->cur_frame);
+ ctx->cur_frame = vo_frame_ref(frame);
+ } else {
+ frame = vo_frame_ref(ctx->cur_frame);
}
+ struct vo_frame dummy = {0};
+ if (!frame)
+ frame = &dummy;
- struct frame_timing timing = {
- .pts = ctx->cur_pts,
- };
if (ctx->approx_vsync > 0) {
- timing.prev_vsync = prev_sync(ctx, mp_time_us());
- timing.next_vsync = timing.prev_vsync + ctx->approx_vsync;
+ frame->prev_vsync = prev_sync(ctx, mp_time_us());
+ frame->next_vsync = frame->prev_vsync + ctx->approx_vsync;
}
pthread_mutex_unlock(&ctx->lock);
- if (mpi)
- gl_video_set_image(ctx->renderer, mpi);
-
- gl_video_render_frame(ctx->renderer, mpi, fbo, timing.pts ? &timing : NULL);
+ gl_video_render_frame(ctx->renderer, frame, fbo);
gl_video_unset_gl_state(ctx->renderer);
+ if (frame != &dummy)
+ talloc_free(frame);
+
pthread_mutex_lock(&ctx->lock);
const int left = ctx->queued_frames;
if (vo && (left > 0 || ctx->vsync_timed))
@@ -397,27 +404,6 @@ int mpv_opengl_cb_report_flip(mpv_opengl_cb_context *ctx, int64_t time)
return 0;
}
-static void draw_image_timed(struct vo *vo, mp_image_t *mpi,
- struct frame_timing *t)
-{
- struct vo_priv *p = vo->priv;
-
- pthread_mutex_lock(&p->ctx->lock);
- mp_image_setrefp(&p->ctx->waiting_frame, mpi);
- if (p->ctx->waiting_frame) {
- p->ctx->waiting_frame->priv =
- t ? talloc_memdup(p->ctx->waiting_frame, t, sizeof(*t))
- : NULL;
- }
- talloc_free(mpi);
- pthread_mutex_unlock(&p->ctx->lock);
-}
-
-static void draw_image(struct vo *vo, mp_image_t *mpi)
-{
- draw_image_timed(vo, mpi, NULL);
-}
-
// Called locked.
static void update(struct vo_priv *p)
{
@@ -425,6 +411,16 @@ static void update(struct vo_priv *p)
p->ctx->update_cb(p->ctx->update_cb_ctx);
}
+static void draw_frame(struct vo *vo, struct vo_frame *frame)
+{
+ struct vo_priv *p = vo->priv;
+
+ pthread_mutex_lock(&p->ctx->lock);
+ talloc_free(p->ctx->waiting_frame);
+ p->ctx->waiting_frame = vo_frame_ref(frame);
+ pthread_mutex_unlock(&p->ctx->lock);
+}
+
static void flip_page(struct vo *vo)
{
struct vo_priv *p = vo->priv;
@@ -468,7 +464,7 @@ static int reconfig(struct vo *vo, struct mp_image_params *params, int flags)
struct vo_priv *p = vo->priv;
pthread_mutex_lock(&p->ctx->lock);
- forget_frames(p->ctx);
+ forget_frames(p->ctx, true);
p->ctx->img_params = *params;
p->ctx->reconfigured = true;
pthread_mutex_unlock(&p->ctx->lock);
@@ -541,11 +537,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
pthread_mutex_unlock(&p->ctx->lock);
return r ? VO_TRUE : VO_NOTIMPL;
}
- case VOCTRL_REDRAW_FRAME:
- pthread_mutex_lock(&p->ctx->lock);
- update(p);
- pthread_mutex_unlock(&p->ctx->lock);
- return VO_TRUE;
case VOCTRL_SET_PANSCAN:
pthread_mutex_lock(&p->ctx->lock);
copy_vo_opts(vo);
@@ -582,7 +573,7 @@ static void uninit(struct vo *vo)
struct vo_priv *p = vo->priv;
pthread_mutex_lock(&p->ctx->lock);
- forget_frames(p->ctx);
+ forget_frames(p->ctx, true);
p->ctx->img_params = (struct mp_image_params){0};
p->ctx->reconfigured = true;
p->ctx->active = NULL;
@@ -635,8 +626,7 @@ const struct vo_driver video_out_opengl_cb = {
.query_format = query_format,
.reconfig = reconfig,
.control = control,
- .draw_image = draw_image,
- .draw_image_timed = draw_image_timed,
+ .draw_frame = draw_frame,
.flip_page = flip_page,
.uninit = uninit,
.priv_size = sizeof(struct vo_priv),