1 /*
2 * Copyright (c) 2007-2008 Intel Corporation. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /*
26 * it is a real program to show how VAAPI decode work,
27 * It does VLD decode for a simple MPEG2 clip "mpeg2-I.m2v"
28 * "mpeg2-I.m2v" and VA parameters are hardcoded into mpeg2vldemo.c,
29 * See mpeg2-I.jif to know how those VA parameters come from
30 *
31 * gcc -o mpeg2vldemo mpeg2vldemo.c -lva -lva-x11 -I/usr/include/va
32 * ./mpeg2vldemo : only do decode
33 * ./mpeg2vldemo <any parameter >: decode+display
34 *
35 */
36 #include <stdio.h>
37 #include <string.h>
38 #include <stdlib.h>
39 #include <getopt.h>
40 #include <unistd.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <fcntl.h>
44 #include <assert.h>
45 #include <va/va.h>
46 #include "va_display.h"
47
48 #define CHECK_VASTATUS(va_status,func) \
49 if (va_status != VA_STATUS_SUCCESS) { \
50 fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \
51 exit(1); \
52 }
53
54 /* Data dump of a 16x16 MPEG2 video clip,it has one I frame
55 */
56 static unsigned char mpeg2_clip[]={
57 0x00,0x00,0x01,0xb3,0x01,0x00,0x10,0x13,0xff,0xff,0xe0,0x18,0x00,0x00,0x01,0xb5,
58 0x14,0x8a,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0xb8,0x00,0x08,0x00,0x00,0x00,0x00,
59 0x01,0x00,0x00,0x0f,0xff,0xf8,0x00,0x00,0x01,0xb5,0x8f,0xff,0xf3,0x41,0x80,0x00,
60 0x00,0x01,0x01,0x13,0xe1,0x00,0x15,0x81,0x54,0xe0,0x2a,0x05,0x43,0x00,0x2d,0x60,
61 0x18,0x01,0x4e,0x82,0xb9,0x58,0xb1,0x83,0x49,0xa4,0xa0,0x2e,0x05,0x80,0x4b,0x7a,
62 0x00,0x01,0x38,0x20,0x80,0xe8,0x05,0xff,0x60,0x18,0xe0,0x1d,0x80,0x98,0x01,0xf8,
63 0x06,0x00,0x54,0x02,0xc0,0x18,0x14,0x03,0xb2,0x92,0x80,0xc0,0x18,0x94,0x42,0x2c,
64 0xb2,0x11,0x64,0xa0,0x12,0x5e,0x78,0x03,0x3c,0x01,0x80,0x0e,0x80,0x18,0x80,0x6b,
65 0xca,0x4e,0x01,0x0f,0xe4,0x32,0xc9,0xbf,0x01,0x42,0x69,0x43,0x50,0x4b,0x01,0xc9,
66 0x45,0x80,0x50,0x01,0x38,0x65,0xe8,0x01,0x03,0xf3,0xc0,0x76,0x00,0xe0,0x03,0x20,
67 0x28,0x18,0x01,0xa9,0x34,0x04,0xc5,0xe0,0x0b,0x0b,0x04,0x20,0x06,0xc0,0x89,0xff,
68 0x60,0x12,0x12,0x8a,0x2c,0x34,0x11,0xff,0xf6,0xe2,0x40,0xc0,0x30,0x1b,0x7a,0x01,
69 0xa9,0x0d,0x00,0xac,0x64
70 };
71
72 /* hardcoded here without a bitstream parser helper
73 * please see picture mpeg2-I.jpg for bitstream details
74 */
75 static VAPictureParameterBufferMPEG2 pic_param={
76 horizontal_size:16,
77 vertical_size:16,
78 forward_reference_picture:0xffffffff,
79 backward_reference_picture:0xffffffff,
80 picture_coding_type:1,
81 f_code:0xffff,
82 {
83 {
84 intra_dc_precision:0,
85 picture_structure:3,
86 top_field_first:0,
87 frame_pred_frame_dct:1,
88 concealment_motion_vectors:0,
89 q_scale_type:0,
90 intra_vlc_format:0,
91 alternate_scan:0,
92 repeat_first_field:0,
93 progressive_frame:1 ,
94 is_first_field:1
95 },
96 }
97 };
98
99 /* see MPEG2 spec65 for the defines of matrix */
100 static VAIQMatrixBufferMPEG2 iq_matrix = {
101 load_intra_quantiser_matrix:1,
102 load_non_intra_quantiser_matrix:1,
103 load_chroma_intra_quantiser_matrix:0,
104 load_chroma_non_intra_quantiser_matrix:0,
105 intra_quantiser_matrix:{
106 8, 16, 16, 19, 16, 19, 22, 22,
107 22, 22, 22, 22, 26, 24, 26, 27,
108 27, 27, 26, 26, 26, 26, 27, 27,
109 27, 29, 29, 29, 34, 34, 34, 29,
110 29, 29, 27, 27, 29, 29, 32, 32,
111 34, 34, 37, 38, 37, 35, 35, 34,
112 35, 38, 38, 40, 40, 40, 48, 48,
113 46, 46, 56, 56, 58, 69, 69, 83
114 },
115 non_intra_quantiser_matrix:{16},
116 chroma_intra_quantiser_matrix:{0},
117 chroma_non_intra_quantiser_matrix:{0}
118 };
119
120 #if 1
121 static VASliceParameterBufferMPEG2 slice_param={
122 slice_data_size:150,
123 slice_data_offset:0,
124 slice_data_flag:0,
125 macroblock_offset:38, /* 4byte + 6bits=38bits */
126 slice_horizontal_position:0,
127 slice_vertical_position:0,
128 quantiser_scale_code:2,
129 intra_slice_flag:0
130 };
131 #endif
132
133 #define CLIP_WIDTH 16
134 #define CLIP_HEIGHT 16
135
136 #define WIN_WIDTH (CLIP_WIDTH<<1)
137 #define WIN_HEIGHT (CLIP_HEIGHT<<1)
138
main(int argc,char ** argv)139 int main(int argc,char **argv)
140 {
141 VAEntrypoint entrypoints[5];
142 int num_entrypoints,vld_entrypoint;
143 VAConfigAttrib attrib;
144 VAConfigID config_id;
145 VASurfaceID surface_id;
146 VAContextID context_id;
147 VABufferID pic_param_buf,iqmatrix_buf,slice_param_buf,slice_data_buf;
148 int major_ver, minor_ver;
149 VADisplay va_dpy;
150 VAStatus va_status;
151 int putsurface=0;
152
153 va_init_display_args(&argc, argv);
154
155 if (argc > 1)
156 putsurface=1;
157
158 va_dpy = va_open_display();
159 va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
160 assert(va_status == VA_STATUS_SUCCESS);
161
162 va_status = vaQueryConfigEntrypoints(va_dpy, VAProfileMPEG2Main, entrypoints,
163 &num_entrypoints);
164 CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
165
166 for (vld_entrypoint = 0; vld_entrypoint < num_entrypoints; vld_entrypoint++) {
167 if (entrypoints[vld_entrypoint] == VAEntrypointVLD)
168 break;
169 }
170 if (vld_entrypoint == num_entrypoints) {
171 /* not find VLD entry point */
172 assert(0);
173 }
174
175 /* Assuming finding VLD, find out the format for the render target */
176 attrib.type = VAConfigAttribRTFormat;
177 vaGetConfigAttributes(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD,
178 &attrib, 1);
179 if ((attrib.value & VA_RT_FORMAT_YUV420) == 0) {
180 /* not find desired YUV420 RT format */
181 assert(0);
182 }
183
184 va_status = vaCreateConfig(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD,
185 &attrib, 1,&config_id);
186 CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
187
188 va_status = vaCreateSurfaces(
189 va_dpy,
190 VA_RT_FORMAT_YUV420, CLIP_WIDTH, CLIP_HEIGHT,
191 &surface_id, 1,
192 NULL, 0
193 );
194 CHECK_VASTATUS(va_status, "vaCreateSurfaces");
195
196 /* Create a context for this decode pipe */
197 va_status = vaCreateContext(va_dpy, config_id,
198 CLIP_WIDTH,
199 ((CLIP_HEIGHT+15)/16)*16,
200 VA_PROGRESSIVE,
201 &surface_id,
202 1,
203 &context_id);
204 CHECK_VASTATUS(va_status, "vaCreateContext");
205
206 va_status = vaCreateBuffer(va_dpy, context_id,
207 VAPictureParameterBufferType,
208 sizeof(VAPictureParameterBufferMPEG2),
209 1, &pic_param,
210 &pic_param_buf);
211 CHECK_VASTATUS(va_status, "vaCreateBuffer");
212
213 va_status = vaCreateBuffer(va_dpy, context_id,
214 VAIQMatrixBufferType,
215 sizeof(VAIQMatrixBufferMPEG2),
216 1, &iq_matrix,
217 &iqmatrix_buf );
218 CHECK_VASTATUS(va_status, "vaCreateBuffer");
219
220 va_status = vaCreateBuffer(va_dpy, context_id,
221 VASliceParameterBufferType,
222 sizeof(VASliceParameterBufferMPEG2),
223 1,
224 &slice_param, &slice_param_buf);
225 CHECK_VASTATUS(va_status, "vaCreateBuffer");
226
227 va_status = vaCreateBuffer(va_dpy, context_id,
228 VASliceDataBufferType,
229 0xc4-0x2f+1,
230 1,
231 mpeg2_clip+0x2f,
232 &slice_data_buf);
233 CHECK_VASTATUS(va_status, "vaCreateBuffer");
234
235 va_status = vaBeginPicture(va_dpy, context_id, surface_id);
236 CHECK_VASTATUS(va_status, "vaBeginPicture");
237
238 va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1);
239 CHECK_VASTATUS(va_status, "vaRenderPicture");
240
241 va_status = vaRenderPicture(va_dpy,context_id, &iqmatrix_buf, 1);
242 CHECK_VASTATUS(va_status, "vaRenderPicture");
243
244 va_status = vaRenderPicture(va_dpy,context_id, &slice_param_buf, 1);
245 CHECK_VASTATUS(va_status, "vaRenderPicture");
246
247 va_status = vaRenderPicture(va_dpy,context_id, &slice_data_buf, 1);
248 CHECK_VASTATUS(va_status, "vaRenderPicture");
249
250 va_status = vaEndPicture(va_dpy,context_id);
251 CHECK_VASTATUS(va_status, "vaEndPicture");
252
253 va_status = vaSyncSurface(va_dpy, surface_id);
254 CHECK_VASTATUS(va_status, "vaSyncSurface");
255
256 if (putsurface) {
257 VARectangle src_rect, dst_rect;
258
259 src_rect.x = 0;
260 src_rect.y = 0;
261 src_rect.width = CLIP_WIDTH;
262 src_rect.height = CLIP_HEIGHT;
263
264 dst_rect.x = 0;
265 dst_rect.y = 0;
266 dst_rect.width = WIN_WIDTH;
267 dst_rect.height = WIN_HEIGHT;
268
269 va_status = va_put_surface(va_dpy, surface_id, &src_rect, &dst_rect);
270 CHECK_VASTATUS(va_status, "vaPutSurface");
271 }
272 printf("press any key to exit\n");
273 getchar();
274
275 vaDestroySurfaces(va_dpy,&surface_id,1);
276 vaDestroyConfig(va_dpy,config_id);
277 vaDestroyContext(va_dpy,context_id);
278
279 vaTerminate(va_dpy);
280 va_close_display(va_dpy);
281 return 0;
282 }
283