summaryrefslogtreecommitdiffstats
path: root/video/out/vo_opengl_cb.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-07-01 19:24:28 +0200
committerwm4 <wm4@nowhere>2015-07-01 22:38:02 +0200
commit0739cfc20934ac7772ab71dbae7ecba4ba10fda4 (patch)
tree939c829441af634577d71fbdf99a60314aa3ab42 /video/out/vo_opengl_cb.c
parentf166d1298545154618ee2d046bb3c433469469c2 (diff)
downloadmpv-0739cfc20934ac7772ab71dbae7ecba4ba10fda4.tar.bz2
mpv-0739cfc20934ac7772ab71dbae7ecba4ba10fda4.tar.xz
vo: change internal API for drawing frames
draw_image_timed is renamed to draw_frame. struct frame_timing is renamed to vo_frame. flip_page_timed is merged into draw_frame (the additional parameters are part of struct vo_frame). draw_frame also deprecates VOCTRL_REDRAW_FRAME, and replaces it with a method that works for both VOs which can cache the current frame, and VOs which need to redraw it anyway. This is preparation to making the interpolation and (work in progress) display sync code saner. Lots of other refactoring, and also some simplifications.
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),