summaryrefslogtreecommitdiffstats
path: root/video/filter
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-04-11 20:46:05 +0200
committerwm4 <wm4@nowhere>2016-04-11 22:03:26 +0200
commitf5ff2656e0d192a2e25fe5f65edf219972211a48 (patch)
tree4400fd5f98c38a7c0923a5f8b468335684334f29 /video/filter
parent49431626cb1bde400ab6de6adc68ce39cdbbf6f8 (diff)
downloadmpv-f5ff2656e0d192a2e25fe5f65edf219972211a48.tar.bz2
mpv-f5ff2656e0d192a2e25fe5f65edf219972211a48.tar.xz
vaapi: determine surface format in decoder, not in renderer
Until now, we have made the assumption that a driver will use only 1 hardware surface format. the format is dictated by the driver (you don't create surfaces with a specific format - you just pass a rt_format and get a surface that will be in a specific driver-chosen format). In particular, the renderer created a dummy surface to probe the format, and hoped the decoder would produce the same format. Due to a driver bug this required a workaround to actually get the same format as the driver did. Change this so that the format is determined in the decoder. The format is then passed down as hw_subfmt, which allows the renderer to configure itself with the correct format. If the hardware surface changes its format midstream, the renderer can be reconfigured using the normal mechanisms. This calls va_surface_init_subformat() each time after the decoder returns a surface. Since libavcodec/AVFrame has no concept of sub- formats, this is unavoidable. It creates and destroys a derived VAImage, but this shouldn't have any bad performance effects (at least I didn't notice any measurable effects). Note that vaDeriveImage() failures are silently ignored as some drivers (the vdpau wrapper) support neither vaDeriveImage, nor EGL interop. In addition, we still probe whether we can map an image in the EGL interop code. This is important as it's the only way to determine whether EGL interop is supported at all. With respect to the driver bug mentioned above, it doesn't matter which format the test surface has. In vf_vavpp, also remove the rt_format guessing business. I think the existing logic was a bit meaningless anyway. It's not even a given that vavpp produces the same rt_format for output.
Diffstat (limited to 'video/filter')
-rw-r--r--video/filter/vf_vavpp.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/video/filter/vf_vavpp.c b/video/filter/vf_vavpp.c
index ae1d6b5476..e076713e9e 100644
--- a/video/filter/vf_vavpp.c
+++ b/video/filter/vf_vavpp.c
@@ -304,14 +304,6 @@ static int filter_ext(struct vf_instance *vf, struct mp_image *in)
struct vf_priv_s *p = vf->priv;
if (in) {
- int rt_format = in->imgfmt == IMGFMT_VAAPI ? va_surface_rt_format(in)
- : VA_RT_FORMAT_YUV420;
- if (!p->pool || p->current_rt_format != rt_format) {
- talloc_free(p->pool);
- p->pool = mp_image_pool_new(20);
- va_pool_set_allocator(p->pool, p->va, rt_format);
- p->current_rt_format = rt_format;
- }
if (in->imgfmt != IMGFMT_VAAPI) {
struct mp_image *tmp = upload(vf, in);
talloc_free(in);
@@ -350,10 +342,25 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
{
struct vf_priv_s *p = vf->priv;
+ flush_frames(vf);
+ talloc_free(p->pool);
+ p->pool = NULL;
+
p->params = *in;
+
+ p->current_rt_format = VA_RT_FORMAT_YUV420;
+ p->pool = mp_image_pool_new(20);
+ va_pool_set_allocator(p->pool, p->va, p->current_rt_format);
+
+ struct mp_image *probe = mp_image_pool_get(p->pool, IMGFMT_VAAPI, in->w, in->h);
+ if (!probe)
+ return -1;
+ va_surface_init_subformat(probe);
*out = *in;
- out->imgfmt = IMGFMT_VAAPI;
- flush_frames(vf);
+ out->imgfmt = probe->params.imgfmt;
+ out->hw_subfmt = probe->params.hw_subfmt;
+ talloc_free(probe);
+
return 0;
}