frontends/va: Derive image from interlaced buffers in some cases

Add an allowlist to make an exception when deriving images from
interlaced buffers. Normally, the function should fail if the surface
needs to be modified to derive the image. But some applications do not
follow the fall-back method of using vaCreateImage + vaPutImage as
mentioned in the VAAPI documentation, so we have to make an exception.

Signed-off-by: Thong Thai <thong.thai@amd.com>
Reviewed-by: Leo Liu <leo.liu@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5942>
This commit is contained in:
Thong Thai 2020-08-15 14:36:45 -04:00 committed by Marge Bot
parent fcb558321e
commit 338745c6f4
1 changed files with 21 additions and 0 deletions

View File

@ -32,6 +32,7 @@
#include "util/u_handle_table.h"
#include "util/u_surface.h"
#include "util/u_video.h"
#include "util/u_process.h"
#include "vl/vl_winsys.h"
#include "vl/vl_video_buffer.h"
@ -208,6 +209,17 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
unsigned stride = 0;
unsigned offset = 0;
/* This function is used by some programs to test for hardware decoding, but on
* AMD devices, the buffers default to interlaced, which causes this function to fail.
* Some programs expect this function to fail, while others, assume this means
* hardware acceleration is not available and give up without trying the fall-back
* vaCreateImage + vaPutImage
*/
const char *proc = util_get_process_name();
const char *derive_interlaced_allowlist[] = {
"vlc",
};
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
@ -226,6 +238,15 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
if (!surf || !surf->buffer)
return VA_STATUS_ERROR_INVALID_SURFACE;
if (surf->buffer->interlaced) {
for (i = 0; i < ARRAY_SIZE(derive_interlaced_allowlist); i++)
if ((strcmp(derive_interlaced_allowlist[i], proc) == 0))
break;
if (i >= ARRAY_SIZE(derive_interlaced_allowlist))
return VA_STATUS_ERROR_OPERATION_FAILED;
}
surfaces = surf->buffer->get_surfaces(surf->buffer);
if (!surfaces || !surfaces[0]->texture)
return VA_STATUS_ERROR_ALLOCATION_FAILED;