diff options
Diffstat (limited to 'video/out/vo_opengl_cb.c')
-rw-r--r-- | video/out/vo_opengl_cb.c | 104 |
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), |