summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-07-15 13:27:25 +0200
committerwm4 <wm4@nowhere>2015-07-15 13:27:25 +0200
commit50bd2807ad4f94bcf215991566336060ebfdd249 (patch)
tree78c533eb7d754d252ec00734a409f5720a989460 /video
parente3e20f1431fa0c2d7988234787994d87fb6385c2 (diff)
downloadmpv-50bd2807ad4f94bcf215991566336060ebfdd249.tar.bz2
mpv-50bd2807ad4f94bcf215991566336060ebfdd249.tar.xz
vaapi: don't assume vaQueryImageFormats() returns sorted list
vaQueryImageFormats() returns a randomly ordered list - so we shouldn't assume the first format on the list which works is the best. This effectively switches to nv12 instead of yuv420p on some drivers. We handle this by reusing va_to_imgfmt[], and ordering it by preference. We hardcode that GPUs prefer nv12 pver yuv420p. In theory we could do complicated probing (allocate dummy surface + use vaDeriveImage on it, then retrieve the FourCC) - but all things which could break assumption in the future are not supported yet (like 10 bit or 4:4:4), so this is fine.
Diffstat (limited to 'video')
-rw-r--r--video/vaapi.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/video/vaapi.c b/video/vaapi.c
index 6017bc4ded..ed021cfdd1 100644
--- a/video/vaapi.c
+++ b/video/vaapi.c
@@ -50,10 +50,10 @@ struct fmtentry {
};
static const struct fmtentry va_to_imgfmt[] = {
+ {VA_FOURCC_NV12, IMGFMT_NV12},
{VA_FOURCC_YV12, IMGFMT_420P},
{VA_FOURCC_I420, IMGFMT_420P},
{VA_FOURCC_IYUV, IMGFMT_420P},
- {VA_FOURCC_NV12, IMGFMT_NV12},
{VA_FOURCC_UYVY, IMGFMT_UYVY},
{VA_FOURCC_YUY2, IMGFMT_YUYV},
// Note: not sure about endian issues (the mp formats are byte-addressed)
@@ -456,13 +456,18 @@ struct mp_image *va_surface_download(struct mp_image *src,
return mpi;
// We have no clue which format will work, so try them all.
- for (int i = 0; i < ctx->image_formats->num; i++) {
- VAImageFormat *format = &ctx->image_formats->entries[i];
- if (va_surface_image_alloc(src, format) < 0)
- continue;
- mpi = try_download(src, pool);
- if (mpi)
- return mpi;
+ // Make sure to start with the most preferred format (nv12), to avoid
+ // slower code paths.
+ for (int n = 0; va_to_imgfmt[n].mp; n++) {
+ VAImageFormat *format =
+ va_image_format_from_imgfmt(ctx, va_to_imgfmt[n].mp);
+ if (format) {
+ if (va_surface_image_alloc(src, format) < 0)
+ continue;
+ mpi = try_download(src, pool);
+ if (mpi)
+ return mpi;
+ }
}
MP_ERR(ctx, "failed to get surface data.\n");