OSDN Git Service

1) test/*: enable/refine the test/* for both X11 and Android
[android-x86/hardware-intel-common-libva.git] / test / decode / mpeg2vldemo.cpp
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
47 #ifdef ANDROID
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
59
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"
66 #else
67 #include <va/va_x11.h>
68 #include <X11/Xlib.h>
69 #endif
70
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__); \
74     exit(1);                                                            \
75 }
76
77 /* Data dump of a 16x16 MPEG2 video clip,it has one I frame
78  */
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
93 };
94
95 /* hardcoded here without a bitstream parser helper
96  * please see picture mpeg2-I.jpg for bitstream details
97  */
98 static VAPictureParameterBufferMPEG2 pic_param={
99   horizontal_size:16,
100   vertical_size:16,
101   forward_reference_picture:0xffffffff,
102   backward_reference_picture:0xffffffff,
103   picture_coding_type:1,
104   f_code:0xffff,
105   {
106       {
107         intra_dc_precision:0,
108         picture_structure:3,
109         top_field_first:0,
110         frame_pred_frame_dct:1,
111         concealment_motion_vectors:0,
112         q_scale_type:0,
113         intra_vlc_format:0,
114         alternate_scan:0,
115         repeat_first_field:0,
116         progressive_frame:1 ,
117         is_first_field:1
118       },
119   }
120 };
121
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
137     },
138   non_intra_quantiser_matrix:{16},
139   chroma_intra_quantiser_matrix:{0},
140   chroma_non_intra_quantiser_matrix:{0}
141 };
142
143 #if 1
144 static VASliceParameterBufferMPEG2 slice_param={
145   slice_data_size:150,
146   slice_data_offset:0,
147   slice_data_flag:0,
148   macroblock_offset:38, /* 4byte + 6bits=38bits */
149   slice_horizontal_position:0,
150   slice_vertical_position:0,
151   quantiser_scale_code:2,
152   intra_slice_flag:0
153 };
154 #endif
155
156 #define CLIP_WIDTH  16
157 #define CLIP_HEIGHT 16
158
159 #define WIN_WIDTH  (CLIP_WIDTH<<1)
160 #define WIN_HEIGHT (CLIP_HEIGHT<<1)
161
162 int main(int argc,char **argv)
163 {
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;
173     VADisplay   va_dpy;
174     VAStatus va_status;
175     int putsurface=0;
176
177     if (argc > 1)
178         putsurface=1;
179 #ifdef ANDROID 
180     x11_display = (Display*)malloc(sizeof(Display));
181     *(x11_display ) = 0x18c34078;
182 #else
183     x11_display = XOpenDisplay(":0.0");
184 #endif
185
186     if (x11_display == NULL) {
187       fprintf(stderr, "Can't connect X server!\n");
188       exit(-1);
189     }
190
191     assert(x11_display);
192     
193     va_dpy = vaGetDisplay(x11_display);
194     va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
195     assert(va_status == VA_STATUS_SUCCESS);
196     
197     va_status = vaQueryConfigEntrypoints(va_dpy, VAProfileMPEG2Main, entrypoints, 
198                              &num_entrypoints);
199     CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
200
201     for (vld_entrypoint = 0; vld_entrypoint < num_entrypoints; vld_entrypoint++) {
202         if (entrypoints[vld_entrypoint] == VAEntrypointVLD)
203             break;
204     }
205     if (vld_entrypoint == num_entrypoints) {
206         /* not find VLD entry point */
207         assert(0);
208     }
209
210     /* Assuming finding VLD, find out the format for the render target */
211     attrib.type = VAConfigAttribRTFormat;
212     vaGetConfigAttributes(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD,
213                           &attrib, 1);
214     if ((attrib.value & VA_RT_FORMAT_YUV420) == 0) {
215         /* not find desired YUV420 RT format */
216         assert(0);
217     }
218     
219     va_status = vaCreateConfig(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD,
220                               &attrib, 1,&config_id);
221     CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
222
223     va_status = vaCreateSurfaces(va_dpy,CLIP_WIDTH,CLIP_HEIGHT,
224                                 VA_RT_FORMAT_YUV420, 1, &surface_id);
225     CHECK_VASTATUS(va_status, "vaCreateSurfaces");
226
227     /* Create a context for this decode pipe */
228     va_status = vaCreateContext(va_dpy, config_id,
229                                CLIP_WIDTH,
230                                ((CLIP_HEIGHT+15)/16)*16,
231                                VA_PROGRESSIVE,
232                                &surface_id,
233                                1,
234                                &context_id);
235     CHECK_VASTATUS(va_status, "vaCreateContext");
236     
237     va_status = vaCreateBuffer(va_dpy, context_id,
238                               VAPictureParameterBufferType,
239                               sizeof(VAPictureParameterBufferMPEG2),
240                               1, &pic_param,
241                               &pic_param_buf);
242     CHECK_VASTATUS(va_status, "vaCreateBuffer");
243     
244     va_status = vaCreateBuffer(va_dpy, context_id,
245                               VAIQMatrixBufferType,
246                               sizeof(VAIQMatrixBufferMPEG2),
247                               1, &iq_matrix,
248                               &iqmatrix_buf );
249     CHECK_VASTATUS(va_status, "vaCreateBuffer");
250
251     va_status = vaCreateBuffer(va_dpy, context_id,
252                               VASliceParameterBufferType,
253                               sizeof(VASliceParameterBufferMPEG2),
254                               1,
255                               &slice_param, &slice_param_buf);
256     CHECK_VASTATUS(va_status, "vaCreateBuffer");
257
258     va_status = vaCreateBuffer(va_dpy, context_id,
259                               VASliceDataBufferType,
260                               0xc4-0x2f+1,
261                               1,
262                               mpeg2_clip+0x2f,
263                               &slice_data_buf);
264     CHECK_VASTATUS(va_status, "vaCreateBuffer");
265
266     va_status = vaBeginPicture(va_dpy, context_id, surface_id);
267     CHECK_VASTATUS(va_status, "vaBeginPicture");
268
269     va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1);
270     CHECK_VASTATUS(va_status, "vaRenderPicture");
271     
272     va_status = vaRenderPicture(va_dpy,context_id, &iqmatrix_buf, 1);
273     CHECK_VASTATUS(va_status, "vaRenderPicture");
274     
275     va_status = vaRenderPicture(va_dpy,context_id, &slice_param_buf, 1);
276     CHECK_VASTATUS(va_status, "vaRenderPicture");
277     
278     va_status = vaRenderPicture(va_dpy,context_id, &slice_data_buf, 1);
279     CHECK_VASTATUS(va_status, "vaRenderPicture");
280     
281     va_status = vaEndPicture(va_dpy,context_id);
282     CHECK_VASTATUS(va_status, "vaEndPicture");
283
284     va_status = vaSyncSurface(va_dpy, surface_id);
285     CHECK_VASTATUS(va_status, "vaSyncSurface");
286
287     if (putsurface) {
288 #ifdef ANDROID 
289         sp<ProcessState> proc(ProcessState::self());
290         ProcessState::self()->startThreadPool();
291
292         printf("Create window0 for thread0\n");
293         SURFACE_CREATE(client,surface_ctrl,android_surface, android_isurface, WIN_WIDTH, WIN_HEIGHT);
294
295         va_status = vaPutSurface(va_dpy, surface_id, android_isurface,
296                 0,0,CLIP_WIDTH,CLIP_HEIGHT,
297                 0,0,WIN_WIDTH,WIN_HEIGHT,
298                 NULL,0,0);
299 #else
300         Window  win;
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,
308                                 NULL,0,0);
309 #endif
310        CHECK_VASTATUS(va_status, "vaPutSurface");
311     }
312     printf("press any key to exit\n");
313     getchar();
314
315     vaDestroySurfaces(va_dpy,&surface_id,1);
316     vaDestroyConfig(va_dpy,config_id);
317     vaDestroyContext(va_dpy,context_id);
318
319     vaTerminate(va_dpy);
320 #ifdef ANDROID
321     free(x11_display);
322 #else
323     XCloseDisplay(x11_display);
324 #endif
325     
326     return 0;
327 }