From 757114e22cf9a7ce24801bbc8f8be10552b5bc86 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Thu, 12 Jan 2012 13:38:14 +0800 Subject: A simple case to decode a 8x8 JPEG image Signed-off-by: Hai Lan Signed-off-by: Xiang, Haihao --- test/decode/jpegdecode.cpp | 418 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 418 insertions(+) create mode 100644 test/decode/jpegdecode.cpp diff --git a/test/decode/jpegdecode.cpp b/test/decode/jpegdecode.cpp new file mode 100644 index 0000000..7ac1bba --- /dev/null +++ b/test/decode/jpegdecode.cpp @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2012 Intel Corporation. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * it is a real program to show how VAAPI decode work, + * It does VLD decode for a simple JPEG clip "8x8.jpg" + * and VA parameters are hardcoded into jpegdecode.cpp + * + * g++ -o jpegdecode jpegdecode.cpp -lva -lva-x11 -I/usr/include/va + * ./jpegdecode : only do decode + * ./jpegdecode : decode+display + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef ANDROID +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define Display unsigned int + +using namespace android; +sp client; +sp android_surface; +sp android_isurface; +sp surface_ctrl; +#include "../android_winsys.cpp" +#else +#include +#include +#endif + +#define CLIP_WIDTH 8 +#define CLIP_HEIGHT 8 + +#define WIN_WIDTH (CLIP_WIDTH<<4) +#define WIN_HEIGHT (CLIP_HEIGHT<<4) + +#define CHECK_VASTATUS(va_status,func) \ + if (va_status != VA_STATUS_SUCCESS) { \ + fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \ + exit(1); \ + } + +/* Data dump of a 8x8 jpeg clip + */ +static unsigned char jpeg_clip[]={ + 0xf8,0xbe,0x8a,0x28,0xaf,0xe5,0x33,0xfd,0xfc,0x3f +}; + +/* hardcoded here without a bitstream parser helper + * please see picture mpeg2-I.jpg for bitstream details + */ +static VAPictureParameterBufferJPEG pic_param={ + type:VA_JPEG_SOF0, /* SOFn */ + sample_precision:8, + image_width:CLIP_WIDTH, + image_height:CLIP_HEIGHT, + num_components:3, + components: { + { + component_id:VA_JPEG_COMPONENT_ID_Y, + h_sampling_factor:2, + v_sampling_factor:2, + quantiser_table_selector:0, + }, + { + component_id:VA_JPEG_COMPONENT_ID_U, + h_sampling_factor:1, + v_sampling_factor:1, + quantiser_table_selector:1, + }, + { + component_id:VA_JPEG_COMPONENT_ID_V, + h_sampling_factor:1, + v_sampling_factor:1, + quantiser_table_selector:1, + }, + }, + + /* ROI (region of interest), for JPEG2000 */ + roi: { + enabled:0, + start_x:0, + start_y:0, + end_x:0, + end_y:0, + }, + + rotation:0 +}; + +/* see JPEG spec65 for the defines of matrix */ +static VAIQMatrixBufferJPEG iq_matrix = { + precision: { + 0, 0, 0, 0 + }, + + quantiser_matrix: { + { + 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x05, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x04, + 0x03, 0x05, 0x07, 0x06, 0x07, 0x07, 0x07, 0x06, + 0x07, 0x07, 0x08, 0x09, 0x0b, 0x09, 0x08, 0x08, + 0x0a, 0x08, 0x07, 0x07, 0x0a, 0x0d, 0x0a, 0x0a, + 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x09, 0x0e, + 0x0f, 0x0d, 0x0c, 0x0e, 0x0b, 0x0c, 0x0c, 0x0c, + }, + { + 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x06, 0x03, + 0x03, 0x06, 0x0c, 0x08, 0x07, 0x08, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + }, + } +}; + +static VASliceParameterBufferJPEG slice_param={ + slice_data_size:10, /* number of bytes in the slice data buffer for this slice */ + slice_data_offset:0, /* the offset to the first byte of slice data */ + slice_data_flag:VA_SLICE_DATA_FLAG_ALL, /* see VA_SLICE_DATA_FLAG_XXX definitions */ + slice_horizontal_position:0, + slice_vertical_position:0, + + num_components:3, + components: { + { + component_id:VA_JPEG_COMPONENT_ID_Y, + dc_selector:0, + ac_selector:0, + }, + { + component_id:VA_JPEG_COMPONENT_ID_U, + dc_selector:1, + ac_selector:1, + }, + { + component_id:VA_JPEG_COMPONENT_ID_V, + dc_selector:1, + ac_selector:1, + }, + }, + + restart_interval:0, /* specifies the number of MCUs in restart interval, defined in DRI marker */ + num_mcus:1 /* indicates the number of MCUs in a scan */ +}; + +static VAHuffmanTableBufferJPEG huffman_table_param = { + huffman_table: { + { + dc_bits:{0,1,5,1, + 1,1,1,1, + 1,0,0,0}, + dc_huffval:{0x00,0x01,0x02,0x03, + 0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b}, + ac_bits:{0,2,1,3, + 3,2,4,3, + 5,5,4,4, + 0,0,1,125}, + ac_huffval:{0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07, + 0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0, + 0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, + 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49, + 0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69, + 0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, + 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7, + 0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5, + 0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, + 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8, + 0xf9,0xfa}, + }, + { + dc_bits:{0,3,1,1, + 1,1,1,1, + 1,1,1,0}, + dc_huffval:{0x0,0x1,0x2,0x3, + 0x4,0x5,0x6,0x7, + 0x8,0x9,0xa,0xb}, + ac_bits:{0x0,0x2,0x1,0x2, + 0x4,0x4,0x3,0x4, + 0x7,0x5,0x4,0x4, + 0x0,0x1,0x2,0x77}, + ac_huffval:{ + 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71, + 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0, + 0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, + 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48, + 0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68, + 0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, + 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5, + 0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3, + 0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, + 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8, + 0xf9,0xfa + } + }, + } +}; + +int main(int argc,char **argv) +{ + VAEntrypoint entrypoints[5]; + int num_entrypoints,vld_entrypoint; + VAConfigAttrib attrib; + VAConfigID config_id; + VASurfaceID surface_id; + VAContextID context_id; + VABufferID pic_param_buf,iqmatrix_buf,huffmantable_buf,slice_param_buf,slice_data_buf; + int major_ver, minor_ver; + Display *x11_display; + VADisplay va_dpy; + VAStatus va_status; + int putsurface=0; + + if (argc > 1) + putsurface=1; +#ifdef ANDROID + x11_display = (Display*)malloc(sizeof(Display)); + *(x11_display ) = 0x18c34078; +#else + x11_display = XOpenDisplay(":0.0"); +#endif + + if (x11_display == NULL) { + fprintf(stderr, "Can't connect X server!\n"); + exit(-1); + } + + assert(x11_display); + + va_dpy = vaGetDisplay(x11_display); + va_status = vaInitialize(va_dpy, &major_ver, &minor_ver); + assert(va_status == VA_STATUS_SUCCESS); + + va_status = vaQueryConfigEntrypoints(va_dpy, VAProfileJPEGBaseline, entrypoints, + &num_entrypoints); + CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints"); + + for (vld_entrypoint = 0; vld_entrypoint < num_entrypoints; vld_entrypoint++) { + if (entrypoints[vld_entrypoint] == VAEntrypointVLD) + break; + } + if (vld_entrypoint == num_entrypoints) { + /* not find VLD entry point */ + assert(0); + } + + /* Assuming finding VLD, find out the format for the render target */ + attrib.type = VAConfigAttribRTFormat; + vaGetConfigAttributes(va_dpy, VAProfileJPEGBaseline, VAEntrypointVLD, + &attrib, 1); + if ((attrib.value & VA_RT_FORMAT_YUV420) == 0) { + /* not find desired YUV420 RT format */ + assert(0); + } + + va_status = vaCreateConfig(va_dpy, VAProfileJPEGBaseline, VAEntrypointVLD, + &attrib, 1,&config_id); + CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints"); + + va_status = vaCreateSurfaces(va_dpy,CLIP_WIDTH,CLIP_HEIGHT, + VA_RT_FORMAT_YUV420, 1, &surface_id); + CHECK_VASTATUS(va_status, "vaCreateSurfaces"); + + /* Create a context for this decode pipe */ + va_status = vaCreateContext(va_dpy, config_id, + CLIP_WIDTH, + ((CLIP_HEIGHT+15)/16)*16, + VA_PROGRESSIVE, + &surface_id, + 1, + &context_id); + CHECK_VASTATUS(va_status, "vaCreateContext"); + + va_status = vaCreateBuffer(va_dpy, context_id, + VAPictureParameterBufferType, + sizeof(VAPictureParameterBufferJPEG), + 1, &pic_param, + &pic_param_buf); + CHECK_VASTATUS(va_status, "vaCreateBuffer"); + + va_status = vaCreateBuffer(va_dpy, context_id, + VAIQMatrixBufferType, + sizeof(VAIQMatrixBufferJPEG), + 1, &iq_matrix, + &iqmatrix_buf ); + CHECK_VASTATUS(va_status, "vaCreateBuffer"); + + va_status = vaCreateBuffer(va_dpy, context_id, + VAHuffmanTableBufferType, + sizeof(VAHuffmanTableBufferJPEG), + 1, &huffman_table_param, + &huffmantable_buf ); + CHECK_VASTATUS(va_status, "vaCreateBuffer"); + + va_status = vaCreateBuffer(va_dpy, context_id, + VASliceParameterBufferType, + sizeof(VASliceParameterBufferJPEG), + 1, + &slice_param, &slice_param_buf); + CHECK_VASTATUS(va_status, "vaCreateBuffer"); + + va_status = vaCreateBuffer(va_dpy, context_id, + VASliceDataBufferType, + 10, + 1, + jpeg_clip, + &slice_data_buf); + CHECK_VASTATUS(va_status, "vaCreateBuffer"); + + va_status = vaBeginPicture(va_dpy, context_id, surface_id); + CHECK_VASTATUS(va_status, "vaBeginPicture"); + + va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1); + CHECK_VASTATUS(va_status, "vaRenderPicture"); + + va_status = vaRenderPicture(va_dpy,context_id, &iqmatrix_buf, 1); + CHECK_VASTATUS(va_status, "vaRenderPicture"); + + va_status = vaRenderPicture(va_dpy,context_id, &huffmantable_buf, 1); + CHECK_VASTATUS(va_status, "vaRenderPicture"); + + va_status = vaRenderPicture(va_dpy,context_id, &slice_param_buf, 1); + CHECK_VASTATUS(va_status, "vaRenderPicture"); + + va_status = vaRenderPicture(va_dpy,context_id, &slice_data_buf, 1); + CHECK_VASTATUS(va_status, "vaRenderPicture"); + + va_status = vaEndPicture(va_dpy,context_id); + CHECK_VASTATUS(va_status, "vaEndPicture"); + + va_status = vaSyncSurface(va_dpy, surface_id); + CHECK_VASTATUS(va_status, "vaSyncSurface"); + + if (putsurface) { +#ifdef ANDROID + sp proc(ProcessState::self()); + ProcessState::self()->startThreadPool(); + + printf("Create window0 for thread0\n"); + SURFACE_CREATE(client,surface_ctrl,android_surface, android_isurface, 0, 0, WIN_WIDTH, WIN_HEIGHT); + + va_status = vaPutSurface(va_dpy, surface_id, android_isurface, + 0,0,CLIP_WIDTH,CLIP_HEIGHT, + 0,0,WIN_WIDTH,WIN_HEIGHT, + NULL,0,0); +#else + Window win; + win = XCreateSimpleWindow(x11_display, RootWindow(x11_display, 0), 0, 0, + WIN_WIDTH,WIN_HEIGHT, 0, 0, WhitePixel(x11_display, 0)); + XMapWindow(x11_display, win); + XSync(x11_display, False); + va_status = vaPutSurface(va_dpy, surface_id, win, + 0,0,CLIP_WIDTH,CLIP_HEIGHT, + 0,0,WIN_WIDTH,WIN_HEIGHT, + NULL,0,0); +#endif + CHECK_VASTATUS(va_status, "vaPutSurface"); + } + printf("press any key to exit\n"); + getchar(); + + vaDestroySurfaces(va_dpy,&surface_id,1); + vaDestroyConfig(va_dpy,config_id); + vaDestroyContext(va_dpy,context_id); + + vaTerminate(va_dpy); +#ifdef ANDROID + free(x11_display); +#else + XCloseDisplay(x11_display); +#endif + + return 0; +} -- cgit v1.2.1