summaryrefslogtreecommitdiffstats
path: root/video/out/vo_opengl.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-07-23 09:41:51 +0200
committerwm4 <wm4@nowhere>2017-07-24 04:32:55 +0200
commit64d56114ed9258efe2e864315d7130bb58a03d52 (patch)
treef4300ffb5c3d912f958b93acba86b0ed438ddcf7 /video/out/vo_opengl.c
parent9e7665b21b530cbbfeb187521dc9db78c2ca60db (diff)
downloadmpv-64d56114ed9258efe2e864315d7130bb58a03d52.tar.bz2
mpv-64d56114ed9258efe2e864315d7130bb58a03d52.tar.xz
vo_opengl: add direct rendering support
Can be enabled via --vd-lavc-dr=yes. See manpage additions for what it does. This reminds of the MPlayer -dr flag, but the implementation is completely different. It's the same basic concept: letting the decoder render into a GPU buffer to avoid a copy. Unlike MPlayer, this doesn't try to go through filters (libavfilter doesn't support this anyway). Unless a filter can work in-place, DR will be silently disabled. MPlayer had very complex semantics about buffer types and management (which apparently nobody ever understood) and weird restrictions that mostly limited it to mpeg2 style codecs. The mpv code does not do any of this, and just lets the decoder allocate an arbitrary number of untyped images. (No MPlayer code was used.) Parts of the code based on work by atomnuker (starting point for the generic code) and haasn (some GL definitions, some basic PBO code, and correct fencing).
Diffstat (limited to 'video/out/vo_opengl.c')
-rw-r--r--video/out/vo_opengl.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index f5b0bd37c4..d3b8bbffa3 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -343,6 +343,34 @@ static void wait_events(struct vo *vo, int64_t until_time_us)
}
}
+static void vo_opengl_free_dr(void *opaque, uint8_t *data)
+{
+ struct gl_priv *p = opaque;
+ gl_video_dr_free_buffer(p->renderer, data);
+}
+
+static struct mp_image *get_image(struct vo *vo, int imgfmt, int w, int h,
+ int stride_align)
+{
+ struct gl_priv *p = vo->priv;
+
+ int size = mp_image_get_alloc_size(imgfmt, w, h, stride_align);
+ if (size < 0)
+ return NULL;
+
+ int alloc_size = size + stride_align;
+ void *ptr = gl_video_dr_alloc_buffer(p->renderer, alloc_size);
+ if (!ptr)
+ return NULL;
+
+ struct mp_image *res = mp_image_from_buffer(imgfmt, w, h, stride_align,
+ ptr, alloc_size, p,
+ vo_opengl_free_dr);
+ if (!res)
+ gl_video_dr_free_buffer(p->renderer, ptr);
+ return res;
+}
+
static void uninit(struct vo *vo)
{
struct gl_priv *p = vo->priv;
@@ -427,6 +455,7 @@ const struct vo_driver video_out_opengl = {
.query_format = query_format,
.reconfig = reconfig,
.control = control,
+ .get_image = get_image,
.draw_frame = draw_frame,
.flip_page = flip_page,
.wait_events = wait_events,