blob: c2c2e1f6f9139f12ef245a8e95cb559e5d120411 [file] [log] [blame]
// Copyright 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <alloca.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <va/va.h>
#include <va/va_drm.h>
#include "label_detect.h"
/* Returns true if given VA profile |va_profile| has |entrypoint| and the entry
* point supports given raw |format|.
*/
static bool has_vaapi_entrypoint(VADisplay va_display, VAProfile va_profile,
VAEntrypoint entrypoint, unsigned int format) {
VAStatus va_res;
VAConfigAttrib attrib = {VAConfigAttribRTFormat, 0};
va_res = vaGetConfigAttributes(va_display, va_profile, entrypoint,
&attrib, 1);
if (va_res != VA_STATUS_SUCCESS) {
TRACE("vaGetConfigAttributes failed (%d)\n", va_res);
return false;
}
return attrib.value & format;
}
/* Returns true if the current platform supports at least one of the
* |required_profiles| and |entrypoint| for that profile supports given raw
* |format|.
*/
static bool match_vaapi_capabilities(VADisplay va_display,
VAProfile* required_profiles,
VAEntrypoint entrypoint, unsigned int format) {
int i;
bool found = false;
int num_supported_profiles;
VAStatus va_res;
VAProfile* profiles;
int max_profiles = vaMaxNumProfiles(va_display);
if (max_profiles < 0) {
TRACE("vaMaxNumProfiles returns negative number\n");
return false;
}
profiles = (VAProfile*) alloca(sizeof(VAProfile) * max_profiles);
if (!profiles) {
TRACE("alloca failed\n");
return false;
}
va_res = vaQueryConfigProfiles(va_display, profiles, &num_supported_profiles);
if (va_res != VA_STATUS_SUCCESS) {
TRACE("vaQueryConfigProfiles failed (%d)\n", va_res);
return false;
}
for (i = 0; i < num_supported_profiles; i++) {
int j;
VAProfile profile = profiles[i];
TRACE("supported profile: %d\n", profile);
for (j = 0; required_profiles[j] != VAProfileNone; j++) {
if (required_profiles[j] == profile &&
has_vaapi_entrypoint(va_display, profile, entrypoint, format)) {
found = true;
/* continue the loop in order to output all supported profiles */
}
}
}
return found;
}
/* Returns true if libva supports any given profiles. And that profile has said
* entrypoint with format.
*/
bool is_vaapi_support_formats(int fd, VAProfile* profiles,
VAEntrypoint entrypoint, unsigned int format) {
bool found = false;
VAStatus va_res;
VADisplay va_display;
int major_version, minor_version;
va_display = vaGetDisplayDRM(fd);
if (!vaDisplayIsValid(va_display)) {
TRACE("vaGetDisplay returns invalid display\n");
return false;
}
va_res = vaInitialize(va_display, &major_version, &minor_version);
if (va_res != VA_STATUS_SUCCESS) {
TRACE("vaInitialize failed\n");
return false;
}
if (match_vaapi_capabilities(va_display, profiles, entrypoint, format))
found = true;
vaTerminate(va_display);
return found;
}