• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <Python.h>
6 
7 #if !defined(USE_DRM)
8 #include <X11/Xlib.h>
9 #include <va/va.h>
10 #include <va/va_x11.h>
11 #else
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <fcntl.h>
15 #include <va/va.h>
16 #include <va/va_drm.h>
17 #endif
18 
19 static PyObject *VaapiError;
20 
21 namespace {
22 
23 struct DisplayBundle {
24 #if !defined(USE_DRM)
25   Display *x11_display;
26 #else
27   int drm_fd;
28 #endif
29   VADisplay va_display;
30 };
31 
destroy_display_bundle(PyObject * object)32 static void destroy_display_bundle(PyObject* object) {
33   DisplayBundle* bundle = (DisplayBundle*) PyCapsule_GetPointer(object, NULL);
34   vaTerminate(bundle->va_display);
35 #if !defined(USE_DRM)
36   XCloseDisplay(bundle->x11_display);
37 #else
38   close(bundle->drm_fd);
39 #endif
40   delete bundle;
41 }
42 
va_create_display(PyObject * self,PyObject * args)43 static PyObject* va_create_display(PyObject* self, PyObject* args) {
44 #if !defined(USE_DRM)
45   const char* display_name;
46   if (!PyArg_ParseTuple(args, "s", &display_name))
47     return NULL;
48 
49   Display *x11_display = XOpenDisplay(display_name);
50 
51   if (x11_display == NULL) {
52     PyErr_SetString(VaapiError, "Cannot connect X server!");
53     return NULL;
54   }
55 
56   VADisplay va_display = vaGetDisplay(x11_display);
57 #else
58   const char* drm_card_path;
59   if (!PyArg_ParseTuple(args, "s", &drm_card_path))
60     return NULL;
61 
62   int drm_fd = open(drm_card_path, O_RDWR);
63   if (drm_fd < 0) {
64     PyErr_SetString(VaapiError, "Cannot open drm card path");
65     return NULL;
66   }
67 
68   VADisplay va_display = vaGetDisplayDRM(drm_fd);
69 #endif
70   if (!vaDisplayIsValid(va_display)) {
71     PyErr_SetString(VaapiError, "Cannot get a valid display");
72     return NULL;
73   }
74 
75   int major_ver, minor_ver;
76 
77   VAStatus va_status = vaInitialize(va_display, &major_ver, &minor_ver);
78   if (va_status != VA_STATUS_SUCCESS) {
79     PyErr_SetString(VaapiError, "vaInitialize fail");
80     return NULL;
81   }
82 
83   DisplayBundle* bundle = new DisplayBundle();
84 #if !defined(USE_DRM)
85   bundle->x11_display = x11_display;
86 #else
87   bundle->drm_fd = drm_fd;
88 #endif
89   bundle->va_display = va_display;
90 
91   return PyCapsule_New(bundle, NULL, destroy_display_bundle);
92 }
93 
get_va_display(PyObject * object)94 static VADisplay get_va_display(PyObject* object) {
95   if (!PyCapsule_CheckExact(object)) {
96     PyErr_SetString(VaapiError, "invalid display object");
97     return NULL;
98   }
99 
100   DisplayBundle* bundle = (DisplayBundle*) PyCapsule_GetPointer(object, NULL);
101 
102   if (bundle == NULL)
103     return NULL;
104 
105   return bundle->va_display;
106 }
107 
va_query_profiles(PyObject * self,PyObject * args)108 static PyObject* va_query_profiles(PyObject* self, PyObject* args) {
109   PyObject* bundle;
110   if (!PyArg_ParseTuple(args, "O", &bundle))
111     return NULL;
112 
113   VADisplay va_display = get_va_display(bundle);
114 
115   if (va_display == NULL)
116     return NULL;
117 
118   int num_profiles = vaMaxNumProfiles(va_display);
119   VAProfile *profile = new VAProfile[num_profiles];
120 
121   VAStatus status = vaQueryConfigProfiles(va_display, profile, &num_profiles);
122 
123   if (status != VA_STATUS_SUCCESS) {
124     delete [] profile;
125     PyErr_SetString(VaapiError, "vaQueryConfigProfiles fail");
126     return NULL;
127   }
128 
129   PyObject *result = PyList_New(0);
130   for (int i = 0; i < num_profiles; ++i) {
131     size_t value = static_cast<size_t>(profile[i]);
132     PyList_Append(result, PyInt_FromSize_t(value));
133   }
134   delete [] profile;
135   return result;
136 }
137 
va_query_entrypoints(PyObject * self,PyObject * args)138 static PyObject* va_query_entrypoints(PyObject* self, PyObject* args) {
139   PyObject* bundle;
140   int profile;
141   if (!PyArg_ParseTuple(args, "Oi", &bundle, &profile))
142     return NULL;
143 
144   VADisplay va_display = get_va_display(bundle);
145   if (va_display == NULL)
146     return NULL;
147 
148   int num_entrypoints = vaMaxNumEntrypoints(va_display);
149   VAEntrypoint* entrypoint = new VAEntrypoint[num_entrypoints];
150 
151   VAStatus status = vaQueryConfigEntrypoints(va_display,
152                                              static_cast<VAProfile>(profile),
153                                              entrypoint,
154                                              &num_entrypoints);
155   if (status != VA_STATUS_SUCCESS) {
156     PyErr_SetString(VaapiError, "vaQueryConfigEntryPoints fail");
157     return NULL;
158   }
159 
160   PyObject *result = PyList_New(0);
161   for (int i = 0; i < num_entrypoints; ++i) {
162     size_t value = static_cast<size_t>(entrypoint[i]);
163     PyList_Append(result, PyInt_FromSize_t(value));
164   }
165   return result;
166 }
167 
va_get_rt_format(PyObject * self,PyObject * args)168 static PyObject* va_get_rt_format(PyObject* self, PyObject* args) {
169   PyObject* bundle;
170   int profile;
171   int entrypoint;
172   if (!PyArg_ParseTuple(args, "Oii", &bundle, &profile, &entrypoint))
173     return NULL;
174 
175   VADisplay va_display = get_va_display(bundle);
176   if (va_display == NULL)
177     return NULL;
178 
179   VAConfigAttrib attrib;
180   attrib.type = VAConfigAttribRTFormat;
181   VAStatus status = vaGetConfigAttributes(va_display,
182                                           static_cast<VAProfile>(profile),
183                                           static_cast<VAEntrypoint>(entrypoint),
184                                           &attrib,
185                                           1);
186   if (status != VA_STATUS_SUCCESS) {
187     PyErr_SetString(VaapiError, "vaGetConfgAttributes fail");
188     return NULL;
189   }
190 
191   return PyInt_FromSize_t(attrib.value);
192 }
193 
194 /*
195  * Bind Python function names to our C functions
196  */
197 static PyMethodDef vaapi_methods[] = {
198     {"create_display", va_create_display, METH_VARARGS},
199     {"query_profiles", va_query_profiles, METH_VARARGS},
200     {"query_entrypoints", va_query_entrypoints, METH_VARARGS},
201     {"get_rt_format", va_get_rt_format, METH_VARARGS},
202     {NULL, NULL}
203 };
204 
205 } // end of namespace
206 
207 /*
208  * Python calls this to let us initialize our module
209  */
initvaapi()210 PyMODINIT_FUNC initvaapi() {
211   PyObject *m = Py_InitModule("vaapi", vaapi_methods);
212   if (m == NULL)
213     return;
214 
215   VaapiError = PyErr_NewException((char*)"vaapi.error", NULL, NULL);
216   Py_INCREF(VaapiError);
217   PyModule_AddObject(m, "error", VaapiError);
218 }
219