hardware/intel/libva
修訂 | ffb82f3a85e424b869c2c1ce48251b3305e2cd61 (tree) |
---|---|
時間 | 2013-06-07 16:37:50 |
作者 | Gwenole Beauchesne <gwenole.beauchesne@inte...> |
Commiter | Xiang, Haihao |
tests: cope with new vaQuerySurfaceAttributes() API.
Also factor the code to check whether a specific image format or
surface attribute exists. Cache the list of supported image formats
and surface attributes.
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
@@ -25,6 +25,7 @@ | ||
25 | 25 | #include <stdio.h> |
26 | 26 | #include <string.h> |
27 | 27 | #include <stdlib.h> |
28 | +#include <stdint.h> | |
28 | 29 | #include <getopt.h> |
29 | 30 | |
30 | 31 | #include <sys/time.h> |
@@ -59,7 +60,11 @@ if (va_status != VA_STATUS_SUCCESS) { \ | ||
59 | 60 | |
60 | 61 | static void *win_display; |
61 | 62 | static VADisplay va_dpy; |
62 | -static VAConfigID config_id; | |
63 | +static VAImageFormat *va_image_formats; | |
64 | +static int va_num_image_formats = -1; | |
65 | +static VAConfigID vpp_config_id = VA_INVALID_ID; | |
66 | +static VASurfaceAttrib *va_surface_attribs; | |
67 | +static int va_num_surface_attribs = -1; | |
63 | 68 | static VASurfaceID surface_id[SURFACE_NUM]; |
64 | 69 | static pthread_mutex_t surface_mutex[SURFACE_NUM]; |
65 | 70 |
@@ -123,46 +128,151 @@ char* map_vafourcc_to_str (unsigned int format) | ||
123 | 128 | |
124 | 129 | } |
125 | 130 | |
126 | -int csc_preparation () | |
131 | +static int | |
132 | +va_value_equals(const VAGenericValue *v1, const VAGenericValue *v2) | |
133 | +{ | |
134 | + if (v1->type != v2->type) | |
135 | + return 0; | |
136 | + | |
137 | + switch (v1->type) { | |
138 | + case VAGenericValueTypeInteger: | |
139 | + return v1->value.i == v2->value.i; | |
140 | + case VAGenericValueTypeFloat: | |
141 | + return v1->value.f == v2->value.f; | |
142 | + case VAGenericValueTypePointer: | |
143 | + return v1->value.p == v2->value.p; | |
144 | + case VAGenericValueTypeFunc: | |
145 | + return v1->value.fn == v2->value.fn; | |
146 | + } | |
147 | + return 0; | |
148 | +} | |
149 | + | |
150 | +static int | |
151 | +ensure_image_formats(void) | |
127 | 152 | { |
128 | 153 | VAStatus va_status; |
154 | + VAImageFormat *image_formats; | |
155 | + int num_image_formats; | |
156 | + | |
157 | + if (va_num_image_formats >= 0) | |
158 | + return va_num_image_formats; | |
159 | + | |
160 | + num_image_formats = vaMaxNumImageFormats(va_dpy); | |
161 | + if (num_image_formats == 0) | |
162 | + return 0; | |
163 | + | |
164 | + image_formats = malloc(num_image_formats * sizeof(*image_formats)); | |
165 | + if (!image_formats) | |
166 | + return 0; | |
167 | + | |
168 | + va_status = vaQueryImageFormats(va_dpy, image_formats, &num_image_formats); | |
169 | + CHECK_VASTATUS(va_status, "vaQuerySurfaceAttributes()"); | |
170 | + | |
171 | + va_image_formats = image_formats; | |
172 | + va_num_image_formats = num_image_formats; | |
173 | + return num_image_formats; | |
174 | +} | |
175 | + | |
176 | +static const VAImageFormat * | |
177 | +lookup_image_format(uint32_t fourcc) | |
178 | +{ | |
129 | 179 | int i; |
130 | - | |
131 | - // 1. make sure dst fourcc is supported for vaImage | |
132 | - #define MAX_IMAGE_FORMAT_COUNT 10 | |
133 | - VAImageFormat format_list[MAX_IMAGE_FORMAT_COUNT]; | |
134 | - int num_formats = 0, find_dst_fourcc = 0; | |
135 | - | |
136 | - va_status = vaQueryImageFormats(va_dpy, format_list,&num_formats); | |
137 | - printf("num_formats: %d\n", num_formats); | |
138 | - assert(num_formats<MAX_IMAGE_FORMAT_COUNT); | |
139 | - for (i=0; i<num_formats; i++) { | |
140 | - if (format_list[i].fourcc == csc_dst_fourcc) { | |
141 | - find_dst_fourcc = 1; | |
180 | + | |
181 | + if (!ensure_image_formats()) | |
182 | + return NULL; | |
183 | + | |
184 | + for (i = 0; i < va_num_image_formats; i++) { | |
185 | + const VAImageFormat * const image_format = &va_image_formats[i]; | |
186 | + if (image_format->fourcc == fourcc) | |
187 | + return image_format; | |
188 | + } | |
189 | + return NULL; | |
190 | +} | |
191 | + | |
192 | +static int | |
193 | +ensure_surface_attribs(void) | |
194 | +{ | |
195 | + VAStatus va_status; | |
196 | + VASurfaceAttrib *surface_attribs; | |
197 | + unsigned int num_image_formats, num_surface_attribs; | |
198 | + | |
199 | + if (va_num_surface_attribs >= 0) | |
200 | + return va_num_surface_attribs; | |
201 | + | |
202 | + num_image_formats = vaMaxNumImageFormats(va_dpy); | |
203 | + if (num_image_formats == 0) | |
204 | + return 0; | |
205 | + | |
206 | + va_status = vaCreateConfig(va_dpy, VAProfileNone, VAEntrypointVideoProc, | |
207 | + NULL, 0, &vpp_config_id); | |
208 | + CHECK_VASTATUS(va_status, "vaCreateConfig()"); | |
209 | + | |
210 | + /* Guess the number of surface attributes, thus including any | |
211 | + pixel-format supported by the VA driver */ | |
212 | + num_surface_attribs = VASurfaceAttribCount + num_image_formats; | |
213 | + surface_attribs = malloc(num_surface_attribs * sizeof(*surface_attribs)); | |
214 | + if (!surface_attribs) | |
215 | + return 0; | |
216 | + | |
217 | + va_status = vaQuerySurfaceAttributes(va_dpy, vpp_config_id, | |
218 | + surface_attribs, &num_surface_attribs); | |
219 | + if (va_status == VA_STATUS_SUCCESS) | |
220 | + va_surface_attribs = surface_attribs; | |
221 | + else if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) { | |
222 | + va_surface_attribs = realloc(surface_attribs, | |
223 | + num_surface_attribs * sizeof(*va_surface_attribs)); | |
224 | + if (!va_surface_attribs) { | |
225 | + free(surface_attribs); | |
226 | + return 0; | |
142 | 227 | } |
228 | + va_status = vaQuerySurfaceAttributes(va_dpy, vpp_config_id, | |
229 | + va_surface_attribs, &num_surface_attribs); | |
230 | + } | |
231 | + CHECK_VASTATUS(va_status, "vaQuerySurfaceAttributes()"); | |
232 | + va_num_surface_attribs = num_surface_attribs; | |
233 | + return num_surface_attribs; | |
234 | +} | |
235 | + | |
236 | +static const VASurfaceAttrib * | |
237 | +lookup_surface_attrib(VASurfaceAttribType type, const VAGenericValue *value) | |
238 | +{ | |
239 | + int i; | |
240 | + | |
241 | + if (!ensure_surface_attribs()) | |
242 | + return NULL; | |
243 | + | |
244 | + for (i = 0; i < va_num_surface_attribs; i++) { | |
245 | + const VASurfaceAttrib * const surface_attrib = &va_surface_attribs[i]; | |
246 | + if (surface_attrib->type != type) | |
247 | + continue; | |
248 | + if (!(surface_attrib->flags & VA_SURFACE_ATTRIB_SETTABLE)) | |
249 | + continue; | |
250 | + if (va_value_equals(&surface_attrib->value, value)) | |
251 | + return surface_attrib; | |
143 | 252 | } |
144 | - if (!find_dst_fourcc) { | |
253 | + return NULL; | |
254 | +} | |
255 | + | |
256 | +int csc_preparation () | |
257 | +{ | |
258 | + VAStatus va_status; | |
259 | + | |
260 | + // 1. make sure dst fourcc is supported for vaImage | |
261 | + if (!lookup_image_format(csc_dst_fourcc)) { | |
145 | 262 | test_color_conversion = 0; |
146 | - printf("vaImage doesn't support %s, skip additional color conversion\n", map_vafourcc_to_str(csc_dst_fourcc)); | |
263 | + printf("VA driver doesn't support %s image, skip additional color conversion\n", map_vafourcc_to_str(csc_dst_fourcc)); | |
147 | 264 | goto cleanup; |
148 | 265 | } |
149 | 266 | |
150 | 267 | // 2. make sure src_fourcc is supported for vaSurface |
151 | - VASurfaceAttrib s_attrib[1]; | |
152 | - va_status = vaCreateConfig(va_dpy, VAProfileNone, VAEntrypointVideoProc, | |
153 | - NULL, 0,&config_id); | |
154 | - CHECK_VASTATUS(va_status, "vaCreateConfig"); | |
155 | - | |
156 | - s_attrib[0].flags = VA_SURFACE_ATTRIB_SETTABLE; | |
157 | - s_attrib[0].type = VASurfaceAttribPixelFormat; | |
158 | - s_attrib[0].value.type = VAGenericValueTypeInteger; | |
159 | - s_attrib[0].value.value.i = csc_src_fourcc; | |
160 | - | |
161 | - va_status = vaGetSurfaceAttributes(va_dpy, config_id, s_attrib, 1); | |
162 | - CHECK_VASTATUS(va_status,"vaGetSurfaceAttributes"); | |
163 | - if (! (s_attrib[0].flags & VA_SURFACE_ATTRIB_SETTABLE)) { | |
164 | - printf("vaSurface doesn't support %s, skip additional color conversion\n", map_vafourcc_to_str(csc_src_fourcc)); | |
165 | - vaDestroyConfig (va_dpy, config_id); | |
268 | + VASurfaceAttrib surface_attribs[1], * const s_attrib = &surface_attribs[0]; | |
269 | + s_attrib->type = VASurfaceAttribPixelFormat; | |
270 | + s_attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; | |
271 | + s_attrib->value.type = VAGenericValueTypeInteger; | |
272 | + s_attrib->value.value.i = csc_src_fourcc; | |
273 | + | |
274 | + if (!lookup_surface_attrib(VASurfaceAttribPixelFormat, &s_attrib->value)) { | |
275 | + printf("VA driver doesn't support %s surface, skip additional color conversion\n", map_vafourcc_to_str(csc_src_fourcc)); | |
166 | 276 | test_color_conversion = 0; |
167 | 277 | goto cleanup; |
168 | 278 | } |
@@ -173,7 +283,7 @@ int csc_preparation () | ||
173 | 283 | va_dpy, |
174 | 284 | VA_RT_FORMAT_YUV420, surface_width, surface_height, |
175 | 285 | &surface_id[0], SURFACE_NUM, |
176 | - s_attrib, 1 | |
286 | + surface_attribs, 1 | |
177 | 287 | ); |
178 | 288 | CHECK_VASTATUS(va_status,"vaCreateSurfaces"); |
179 | 289 |
@@ -190,11 +300,11 @@ int csc_preparation () | ||
190 | 300 | |
191 | 301 | |
192 | 302 | // 3.3 create a temp VASurface for final rendering(vaPutSurface) |
193 | - s_attrib[0].value.value.i = VA_FOURCC_NV12; | |
303 | + s_attrib->value.value.i = VA_FOURCC_NV12; | |
194 | 304 | va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, |
195 | 305 | surface_width, surface_height, |
196 | 306 | &csc_render_surface, 1, |
197 | - s_attrib, 1); | |
307 | + surface_attribs, 1); | |
198 | 308 | CHECK_VASTATUS(va_status,"vaCreateSurfaces"); |
199 | 309 | |
200 | 310 |
@@ -560,12 +670,18 @@ int main(int argc,char **argv) | ||
560 | 670 | |
561 | 671 | va_status = vaDestroyImage(va_dpy, csc_dst_fourcc_image.image_id); |
562 | 672 | CHECK_VASTATUS(va_status,"vaDestroyImage"); |
563 | - vaDestroyConfig (va_dpy, config_id); | |
564 | 673 | } |
565 | - | |
674 | + | |
675 | + if (vpp_config_id != VA_INVALID_ID) { | |
676 | + vaDestroyConfig (va_dpy, vpp_config_id); | |
677 | + vpp_config_id = VA_INVALID_ID; | |
678 | + } | |
679 | + | |
566 | 680 | vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM); |
567 | 681 | vaTerminate(va_dpy); |
568 | 682 | |
683 | + free(va_image_formats); | |
684 | + free(va_surface_attribs); | |
569 | 685 | close_display(win_display); |
570 | 686 | |
571 | 687 | return 0; |