blob: 324fe6e5e41fb374cb274de1067185c67d94ebf4 [file] [log] [blame]
// Copyright (c) 2013 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 <Python.h>
#include <X11/Xlib.h>
#include <va/va.h>
#include <va/va_x11.h>
static PyObject *VaapiError;
namespace {
struct DisplayBundle {
Display *x11_display;
VADisplay va_display;
};
static void destroy_display_bundle(PyObject* object) {
DisplayBundle* bundle = (DisplayBundle*) PyCapsule_GetPointer(object, NULL);
vaTerminate(bundle->va_display);
XCloseDisplay(bundle->x11_display);
delete bundle;
}
static PyObject* va_create_display(PyObject* self, PyObject* args) {
const char* display_name;
if (!PyArg_ParseTuple(args, "s", &display_name))
return NULL;
Display *x11_display = XOpenDisplay(display_name);
if (x11_display == NULL) {
PyErr_SetString(VaapiError, "Cannot connect X server!");
return NULL;
}
VADisplay va_display = vaGetDisplay(x11_display);
if (!vaDisplayIsValid(va_display)) {
PyErr_SetString(VaapiError, "Cannot get a valid display");
return NULL;
}
int major_ver, minor_ver;
VAStatus va_status = vaInitialize(va_display, &major_ver, &minor_ver);
if (va_status != VA_STATUS_SUCCESS) {
PyErr_SetString(VaapiError, "vaInitialize fail");
return NULL;
}
DisplayBundle* bundle = new DisplayBundle();
bundle->x11_display = x11_display;
bundle->va_display = va_display;
return PyCapsule_New(bundle, NULL, destroy_display_bundle);
}
static VADisplay get_va_display(PyObject* object) {
if (!PyCapsule_CheckExact(object)) {
PyErr_SetString(VaapiError, "invalid display object");
return NULL;
}
DisplayBundle* bundle = (DisplayBundle*) PyCapsule_GetPointer(object, NULL);
if (bundle == NULL)
return NULL;
return bundle->va_display;
}
static PyObject* va_query_profiles(PyObject* self, PyObject* args) {
PyObject* bundle;
if (!PyArg_ParseTuple(args, "O", &bundle))
return NULL;
VADisplay va_display = get_va_display(bundle);
if (va_display == NULL)
return NULL;
int num_profiles = vaMaxNumProfiles(va_display);
VAProfile *profile = new VAProfile[num_profiles];
VAStatus status = vaQueryConfigProfiles(va_display, profile, &num_profiles);
if (status != VA_STATUS_SUCCESS) {
delete [] profile;
PyErr_SetString(VaapiError, "vaQueryConfigProfiles fail");
return NULL;
}
PyObject *result = PyList_New(0);
for (int i = 0; i < num_profiles; ++i) {
size_t value = static_cast<size_t>(profile[i]);
PyList_Append(result, PyInt_FromSize_t(value));
}
delete [] profile;
return result;
}
static PyObject* va_query_entrypoints(PyObject* self, PyObject* args) {
PyObject* bundle;
int profile;
if (!PyArg_ParseTuple(args, "Oi", &bundle, &profile))
return NULL;
VADisplay va_display = get_va_display(bundle);
if (va_display == NULL)
return NULL;
int num_entrypoints = vaMaxNumEntrypoints(va_display);
VAEntrypoint* entrypoint = new VAEntrypoint[num_entrypoints];
VAStatus status = vaQueryConfigEntrypoints(va_display,
static_cast<VAProfile>(profile),
entrypoint,
&num_entrypoints);
if (status != VA_STATUS_SUCCESS) {
PyErr_SetString(VaapiError, "vaQueryConfigEntryPoints fail");
return NULL;
}
PyObject *result = PyList_New(0);
for (int i = 0; i < num_entrypoints; ++i) {
size_t value = static_cast<size_t>(entrypoint[i]);
PyList_Append(result, PyInt_FromSize_t(value));
}
return result;
}
static PyObject* va_get_rt_format(PyObject* self, PyObject* args) {
PyObject* bundle;
int profile;
int entrypoint;
if (!PyArg_ParseTuple(args, "Oii", &bundle, &profile, &entrypoint))
return NULL;
VADisplay va_display = get_va_display(bundle);
if (va_display == NULL)
return NULL;
VAConfigAttrib attrib;
attrib.type = VAConfigAttribRTFormat;
VAStatus status = vaGetConfigAttributes(va_display,
static_cast<VAProfile>(profile),
static_cast<VAEntrypoint>(entrypoint),
&attrib,
1);
if (status != VA_STATUS_SUCCESS) {
PyErr_SetString(VaapiError, "vaGetConfgAttributes fail");
return NULL;
}
return PyInt_FromSize_t(attrib.value);
}
/*
* Bind Python function names to our C functions
*/
static PyMethodDef vaapi_methods[] = {
{"create_display", va_create_display, METH_VARARGS},
{"query_profiles", va_query_profiles, METH_VARARGS},
{"query_entrypoints", va_query_entrypoints, METH_VARARGS},
{"get_rt_format", va_get_rt_format, METH_VARARGS},
{NULL, NULL}
};
} // end of namespace
/*
* Python calls this to let us initialize our module
*/
PyMODINIT_FUNC initvaapi() {
PyObject *m = Py_InitModule("vaapi", vaapi_methods);
if (m == NULL)
return;
VaapiError = PyErr_NewException("vaapi.error", NULL, NULL);
Py_INCREF(VaapiError);
PyModule_AddObject(m, "error", VaapiError);
}