summaryrefslogtreecommitdiffstats
path: root/video/out/vo.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-01-24 22:56:02 +0100
committerwm4 <wm4@nowhere>2015-01-24 23:16:27 +0100
commit28582322207bb962553505f0c25268f4b786287d (patch)
tree8c9611a9161f48338701fc506646aaedd8c1a491 /video/out/vo.c
parent047788e3b1354562f99ce8dacdba1972ad990d03 (diff)
downloadmpv-28582322207bb962553505f0c25268f4b786287d.tar.bz2
mpv-28582322207bb962553505f0c25268f4b786287d.tar.xz
vo: simplify VOs by adding generic screenshot support
At the time screenshot support was added, images weren't refcounted yet, so screenshots required specialized implementations in the VOs. But now we can handle these things much simpler. Also see commit 5bb24980. If there are VOs in the future which can't do this (e.g. they need to write to the image passed to vo_driver->draw_image), this still could be disabled on a per-VO basis etc., so we lose no potential performance advantages.
Diffstat (limited to 'video/out/vo.c')
-rw-r--r--video/out/vo.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/video/out/vo.c b/video/out/vo.c
index 36bd2a9c2e..11690afb67 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -135,7 +135,8 @@ struct vo_internal {
int64_t drop_count;
bool dropped_frame; // the previous frame was dropped
- struct mp_image *dropped_image; // used to possibly redraw the dropped frame
+
+ struct mp_image *current_frame; // last frame queued to the VO
int64_t wakeup_pts; // time at which to pull frame from decoder
@@ -333,6 +334,8 @@ static void run_reconfig(void *p)
int flags = *(int *)pp[2];
int *ret = pp[3];
+ struct vo_internal *in = vo->in;
+
vo->dwidth = params->d_w;
vo->dheight = params->d_h;
@@ -347,7 +350,11 @@ static void run_reconfig(void *p)
talloc_free(vo->params);
vo->params = NULL;
}
- forget_frames(vo); // implicitly synchronized
+
+ pthread_mutex_lock(&in->lock);
+ mp_image_unrefp(&in->current_frame);
+ forget_frames(vo);
+ pthread_mutex_unlock(&in->lock);
update_display_fps(vo);
}
@@ -388,7 +395,7 @@ static void forget_frames(struct vo *vo)
in->hasframe_rendered = false;
in->drop_count = 0;
mp_image_unrefp(&in->frame_queued);
- mp_image_unrefp(&in->dropped_image);
+ // don't unref current_frame; we always want to be able to redraw it
}
#ifndef __MINGW32__
@@ -555,7 +562,8 @@ static bool render_frame(struct vo *vo)
if (in->vsync_timed && !in->hasframe)
goto nothing_done;
- mp_image_unrefp(&in->dropped_image);
+ if (img)
+ mp_image_setrefp(&in->current_frame, img);
in->rendering = true;
in->frame_queued = NULL;
@@ -598,7 +606,7 @@ static bool render_frame(struct vo *vo)
}
if (in->dropped_frame) {
- in->dropped_image = img;
+ talloc_free(img);
} else {
in->hasframe_rendered = true;
pthread_mutex_unlock(&in->lock);
@@ -679,20 +687,21 @@ static void do_redraw(struct vo *vo)
pthread_mutex_lock(&in->lock);
in->request_redraw = false;
in->want_redraw = false;
- bool skip = !in->paused && in->dropped_frame;
- struct mp_image *img = in->dropped_image;
- if (!skip) {
- in->dropped_image = NULL;
+ bool force_full_redraw = in->dropped_frame;
+ struct mp_image *img = NULL;
+ if (vo->config_ok)
+ img = mp_image_new_ref(in->current_frame);
+ if (img)
in->dropped_frame = false;
- }
pthread_mutex_unlock(&in->lock);
- if (!vo->config_ok || skip)
+ if (!img)
return;
- if (img) {
+ if (force_full_redraw) {
vo->driver->draw_image(vo, img);
} else {
+ talloc_free(img);
if (vo->driver->control(vo, VOCTRL_REDRAW_FRAME, NULL) < 1)
return;
}
@@ -749,6 +758,7 @@ static void *vo_thread(void *ptr)
wait_vo(vo, wait_until);
}
forget_frames(vo); // implicitly synchronized
+ mp_image_unrefp(&in->current_frame);
vo->driver->uninit(vo);
return NULL;
}
@@ -920,6 +930,15 @@ int vo_query_and_reset_events(struct vo *vo, int events)
return r;
}
+struct mp_image *vo_get_current_frame(struct vo *vo)
+{
+ struct vo_internal *in = vo->in;
+ pthread_mutex_lock(&in->lock);
+ struct mp_image *r = mp_image_new_ref(vo->in->current_frame);
+ pthread_mutex_unlock(&in->lock);
+ return r;
+}
+
/**
* \brief lookup an integer in a table, table must have 0 as the last key
* \param key key to search for