2 * Copyright (c) 2007-2008 Intel Corporation. All Rights Reserved.
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
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
31 * gcc -o mpeg2vldemo mpeg2vldemo.c -lva -lva-x11 -I/usr/include/va
32 * ./mpeg2vldemo : only do decode
33 * ./mpeg2vldemo <any parameter >: decode+display
41 #include <sys/types.h>
48 #include <va/va_android.h>
49 #include <binder/IPCThreadState.h>
50 #include <binder/ProcessState.h>
51 #include <binder/IServiceManager.h>
52 #include <utils/Log.h>
53 #include <surfaceflinger/ISurfaceComposer.h>
54 #include <surfaceflinger/Surface.h>
55 #include <surfaceflinger/ISurface.h>
56 #include <surfaceflinger/SurfaceComposerClient.h>
57 #include <binder/MemoryHeapBase.h>
58 #define Display unsigned int
60 using namespace android;
61 sp<SurfaceComposerClient> client;
62 sp<Surface> android_surface;
63 sp<ISurface> android_isurface;
64 sp<SurfaceControl> surface_ctrl;
65 #include "../android_winsys.cpp"
67 #include <va/va_x11.h>
71 #define CHECK_VASTATUS(va_status,func) \
72 if (va_status != VA_STATUS_SUCCESS) { \
73 fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \
77 /* Data dump of a 16x16 MPEG2 video clip,it has one I frame
79 static unsigned char mpeg2_clip[]={
80 0x00,0x00,0x01,0xb3,0x01,0x00,0x10,0x13,0xff,0xff,0xe0,0x18,0x00,0x00,0x01,0xb5,
81 0x14,0x8a,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0xb8,0x00,0x08,0x00,0x00,0x00,0x00,
82 0x01,0x00,0x00,0x0f,0xff,0xf8,0x00,0x00,0x01,0xb5,0x8f,0xff,0xf3,0x41,0x80,0x00,
83 0x00,0x01,0x01,0x13,0xe1,0x00,0x15,0x81,0x54,0xe0,0x2a,0x05,0x43,0x00,0x2d,0x60,
84 0x18,0x01,0x4e,0x82,0xb9,0x58,0xb1,0x83,0x49,0xa4,0xa0,0x2e,0x05,0x80,0x4b,0x7a,
85 0x00,0x01,0x38,0x20,0x80,0xe8,0x05,0xff,0x60,0x18,0xe0,0x1d,0x80,0x98,0x01,0xf8,
86 0x06,0x00,0x54,0x02,0xc0,0x18,0x14,0x03,0xb2,0x92,0x80,0xc0,0x18,0x94,0x42,0x2c,
87 0xb2,0x11,0x64,0xa0,0x12,0x5e,0x78,0x03,0x3c,0x01,0x80,0x0e,0x80,0x18,0x80,0x6b,
88 0xca,0x4e,0x01,0x0f,0xe4,0x32,0xc9,0xbf,0x01,0x42,0x69,0x43,0x50,0x4b,0x01,0xc9,
89 0x45,0x80,0x50,0x01,0x38,0x65,0xe8,0x01,0x03,0xf3,0xc0,0x76,0x00,0xe0,0x03,0x20,
90 0x28,0x18,0x01,0xa9,0x34,0x04,0xc5,0xe0,0x0b,0x0b,0x04,0x20,0x06,0xc0,0x89,0xff,
91 0x60,0x12,0x12,0x8a,0x2c,0x34,0x11,0xff,0xf6,0xe2,0x40,0xc0,0x30,0x1b,0x7a,0x01,
92 0xa9,0x0d,0x00,0xac,0x64
95 /* hardcoded here without a bitstream parser helper
96 * please see picture mpeg2-I.jpg for bitstream details
98 static VAPictureParameterBufferMPEG2 pic_param={
101 forward_reference_picture:0xffffffff,
102 backward_reference_picture:0xffffffff,
103 picture_coding_type:1,
107 intra_dc_precision:0,
110 frame_pred_frame_dct:1,
111 concealment_motion_vectors:0,
115 repeat_first_field:0,
116 progressive_frame:1 ,
122 /* see MPEG2 spec65 for the defines of matrix */
123 static VAIQMatrixBufferMPEG2 iq_matrix = {
124 load_intra_quantiser_matrix:1,
125 load_non_intra_quantiser_matrix:1,
126 load_chroma_intra_quantiser_matrix:0,
127 load_chroma_non_intra_quantiser_matrix:0,
128 intra_quantiser_matrix:{
129 8, 16, 16, 19, 16, 19, 22, 22,
130 22, 22, 22, 22, 26, 24, 26, 27,
131 27, 27, 26, 26, 26, 26, 27, 27,
132 27, 29, 29, 29, 34, 34, 34, 29,
133 29, 29, 27, 27, 29, 29, 32, 32,
134 34, 34, 37, 38, 37, 35, 35, 34,
135 35, 38, 38, 40, 40, 40, 48, 48,
136 46, 46, 56, 56, 58, 69, 69, 83
138 non_intra_quantiser_matrix:{16},
139 chroma_intra_quantiser_matrix:{0},
140 chroma_non_intra_quantiser_matrix:{0}
144 static VASliceParameterBufferMPEG2 slice_param={
148 macroblock_offset:38, /* 4byte + 6bits=38bits */
149 slice_horizontal_position:0,
150 slice_vertical_position:0,
151 quantiser_scale_code:2,
156 #define CLIP_WIDTH 16
157 #define CLIP_HEIGHT 16
159 #define WIN_WIDTH (CLIP_WIDTH<<1)
160 #define WIN_HEIGHT (CLIP_HEIGHT<<1)
162 int main(int argc,char **argv)
164 VAEntrypoint entrypoints[5];
165 int num_entrypoints,vld_entrypoint;
166 VAConfigAttrib attrib;
167 VAConfigID config_id;
168 VASurfaceID surface_id;
169 VAContextID context_id;
170 VABufferID pic_param_buf,iqmatrix_buf,slice_param_buf,slice_data_buf;
171 int major_ver, minor_ver;
172 Display *x11_display;
180 x11_display = (Display*)malloc(sizeof(Display));
181 *(x11_display ) = 0x18c34078;
183 x11_display = XOpenDisplay(":0.0");
186 if (x11_display == NULL) {
187 fprintf(stderr, "Can't connect X server!\n");
193 va_dpy = vaGetDisplay(x11_display);
194 va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
195 assert(va_status == VA_STATUS_SUCCESS);
197 va_status = vaQueryConfigEntrypoints(va_dpy, VAProfileMPEG2Main, entrypoints,
199 CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
201 for (vld_entrypoint = 0; vld_entrypoint < num_entrypoints; vld_entrypoint++) {
202 if (entrypoints[vld_entrypoint] == VAEntrypointVLD)
205 if (vld_entrypoint == num_entrypoints) {
206 /* not find VLD entry point */
210 /* Assuming finding VLD, find out the format for the render target */
211 attrib.type = VAConfigAttribRTFormat;
212 vaGetConfigAttributes(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD,
214 if ((attrib.value & VA_RT_FORMAT_YUV420) == 0) {
215 /* not find desired YUV420 RT format */
219 va_status = vaCreateConfig(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD,
220 &attrib, 1,&config_id);
221 CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
223 va_status = vaCreateSurfaces(va_dpy,CLIP_WIDTH,CLIP_HEIGHT,
224 VA_RT_FORMAT_YUV420, 1, &surface_id);
225 CHECK_VASTATUS(va_status, "vaCreateSurfaces");
227 /* Create a context for this decode pipe */
228 va_status = vaCreateContext(va_dpy, config_id,
230 ((CLIP_HEIGHT+15)/16)*16,
235 CHECK_VASTATUS(va_status, "vaCreateContext");
237 va_status = vaCreateBuffer(va_dpy, context_id,
238 VAPictureParameterBufferType,
239 sizeof(VAPictureParameterBufferMPEG2),
242 CHECK_VASTATUS(va_status, "vaCreateBuffer");
244 va_status = vaCreateBuffer(va_dpy, context_id,
245 VAIQMatrixBufferType,
246 sizeof(VAIQMatrixBufferMPEG2),
249 CHECK_VASTATUS(va_status, "vaCreateBuffer");
251 va_status = vaCreateBuffer(va_dpy, context_id,
252 VASliceParameterBufferType,
253 sizeof(VASliceParameterBufferMPEG2),
255 &slice_param, &slice_param_buf);
256 CHECK_VASTATUS(va_status, "vaCreateBuffer");
258 va_status = vaCreateBuffer(va_dpy, context_id,
259 VASliceDataBufferType,
264 CHECK_VASTATUS(va_status, "vaCreateBuffer");
266 va_status = vaBeginPicture(va_dpy, context_id, surface_id);
267 CHECK_VASTATUS(va_status, "vaBeginPicture");
269 va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1);
270 CHECK_VASTATUS(va_status, "vaRenderPicture");
272 va_status = vaRenderPicture(va_dpy,context_id, &iqmatrix_buf, 1);
273 CHECK_VASTATUS(va_status, "vaRenderPicture");
275 va_status = vaRenderPicture(va_dpy,context_id, &slice_param_buf, 1);
276 CHECK_VASTATUS(va_status, "vaRenderPicture");
278 va_status = vaRenderPicture(va_dpy,context_id, &slice_data_buf, 1);
279 CHECK_VASTATUS(va_status, "vaRenderPicture");
281 va_status = vaEndPicture(va_dpy,context_id);
282 CHECK_VASTATUS(va_status, "vaEndPicture");
284 va_status = vaSyncSurface(va_dpy, surface_id);
285 CHECK_VASTATUS(va_status, "vaSyncSurface");
289 sp<ProcessState> proc(ProcessState::self());
290 ProcessState::self()->startThreadPool();
292 printf("Create window0 for thread0\n");
293 SURFACE_CREATE(client,surface_ctrl,android_surface, android_isurface, WIN_WIDTH, WIN_HEIGHT);
295 va_status = vaPutSurface(va_dpy, surface_id, android_isurface,
296 0,0,CLIP_WIDTH,CLIP_HEIGHT,
297 0,0,WIN_WIDTH,WIN_HEIGHT,
301 win = XCreateSimpleWindow(x11_display, RootWindow(x11_display, 0), 0, 0,
302 WIN_WIDTH,WIN_HEIGHT, 0, 0, WhitePixel(x11_display, 0));
303 XMapWindow(x11_display, win);
304 XSync(x11_display, False);
305 va_status = vaPutSurface(va_dpy, surface_id, win,
306 0,0,CLIP_WIDTH,CLIP_HEIGHT,
307 0,0,WIN_WIDTH,WIN_HEIGHT,
310 CHECK_VASTATUS(va_status, "vaPutSurface");
312 printf("press any key to exit\n");
315 vaDestroySurfaces(va_dpy,&surface_id,1);
316 vaDestroyConfig(va_dpy,config_id);
317 vaDestroyContext(va_dpy,context_id);
323 XCloseDisplay(x11_display);