[Libva] [PATCH] test/decode/jpegdecode: add a test sample for JPEG coding

Hai Lan hai.lan at intel.com
Tue Dec 27 10:57:30 PST 2011


This sample will use hardware(IVB+) to decode a 8x8 jpg file

Signed-off-by: Hai Lan <hai.lan at intel.com>
---
 test/decode/Makefile.am    |    4 +-
 test/decode/jpegdecode.cpp |  410 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 413 insertions(+), 1 deletions(-)
 create mode 100644 test/decode/jpegdecode.cpp

diff --git a/test/decode/Makefile.am b/test/decode/Makefile.am
index d0c5f39..59a318a 100644
--- a/test/decode/Makefile.am
+++ b/test/decode/Makefile.am
@@ -20,7 +20,7 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-bin_PROGRAMS = mpeg2vldemo
+bin_PROGRAMS = mpeg2vldemo jpegdecode
 
 INCLUDES = -I$(top_srcdir)
 
@@ -29,6 +29,8 @@ TEST_LIBS = $(top_builddir)/va/$(libvabackendlib) $(top_builddir)/va/$(libvacore
 mpeg2vldemo_LDADD = $(TEST_LIBS)
 mpeg2vldemo_SOURCES = mpeg2vldemo.cpp
 
+jpegdecode_LDADD = $(TEST_LIBS)
+jpegdecode_SOURCES = jpegdecode.cpp
 
 valgrind:	$(bin_PROGRAMS)
 	for a in $(bin_PROGRAMS); do \
diff --git a/test/decode/jpegdecode.cpp b/test/decode/jpegdecode.cpp
new file mode 100644
index 0000000..f81feff
--- /dev/null
+++ b/test/decode/jpegdecode.cpp
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 2007-2008 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 mpeg2vldemo.c,
+ *
+ * g++ -o  jpegdecode  jpegdecode.cpp -lva -lva-x11 -I/usr/include/va
+ * ./jpegdecode  : only do decode
+ * ./jpegdecode <any parameter >: decode+display
+ *
+ */  
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <va/va.h>
+
+#ifdef ANDROID
+#include <va/va_android.h>
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/ISurface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+#include <binder/MemoryHeapBase.h>
+#define Display unsigned int
+
+using namespace android;
+sp<SurfaceComposerClient> client;
+sp<Surface> android_surface;
+sp<ISurface> android_isurface;
+sp<SurfaceControl> surface_ctrl;
+#include "../android_winsys.cpp"
+#else
+#include <va/va_x11.h>
+#include <X11/Xlib.h>
+#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,
+    {
+        {
+            component_id:1,
+            h_sampling_factor:2,
+            v_sampling_factor:2,
+            quantizer_table_index:0,
+        },
+        {
+            component_id:2,
+            h_sampling_factor:1,
+            v_sampling_factor:1,
+            quantizer_table_index:1,
+        },
+        {
+            component_id:3,
+            h_sampling_factor:1,
+            v_sampling_factor:1,
+            quantizer_table_index:1,
+        },
+        /*{
+            component_id:0,
+            h_sampling_factor:0,
+            v_sampling_factor:0,
+            quantizer_table_index:0,
+        },*/
+    },
+
+    /* ROI (region of interest), for JPEG2000 */
+    {
+        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 = {
+  quantizer_matrix_mask:VA_JPEG_QUANTIZER_MATRIX_Y_MASK|VA_JPEG_QUANTIZER_MATRIX_U_MASK|VA_JPEG_QUANTIZER_MATRIX_V_MASK,
+  quantizer_matrix:
+  {
+    {
+        2,  1,  1,  2,  3,  5,  6,  7,
+        1,  1,  2,  2,  3,  7,  7,  7, 
+        2,  2,  2,  3,  5,  7,  8,  7,
+        2,  2,  3,  3,  6, 10, 10,  7, 
+        2,  3,  4,  7,  8, 13, 12,  9, 
+        3,  4,  7,  8, 10, 12, 14, 11, 
+        6,  8,  9, 10, 12, 15, 14, 12,
+        9, 11, 11, 12, 13, 12, 12, 12 
+    },
+    {
+        2,  2,  3,  6, 12, 12, 12, 12,
+        2,  3,  3,  8, 12, 12, 12, 12,
+        3,  3,  7, 12, 12, 12, 12, 12,
+        6,  8, 12, 12, 12, 12, 12, 12,
+       12, 12, 12, 12, 12, 12, 12, 12,
+       12, 12, 12, 12, 12, 12, 12, 12,
+       12, 12, 12, 12, 12, 12, 12, 12,
+       12, 12, 12, 12, 12, 12, 12, 12 
+    },
+  }
+};
+
+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:
+    {
+        {index:0},      /* index to the ARRAY components in VAPictureParameterBufferJPEG */
+        {index:1},      /* index to the ARRAY components in VAPictureParameterBufferJPEG */
+        {index:2},      /* index to the ARRAY components in VAPictureParameterBufferJPEG */
+        {index:0}      /* index to the ARRAY components in VAPictureParameterBufferJPEG */
+    },
+
+    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 */
+};
+#if 1
+static VAHuffmanTableBufferJPEG huffman_table_param={
+    huffman_table_mask:VA_JPEG_HUFFMAN_TABLE_MASK_Y|VA_JPEG_HUFFMAN_TABLE_MASK_U|VA_JPEG_HUFFMAN_TABLE_MASK_V,
+    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:{},
+            ac_huffval:{},  /* only the first 162 bytes are available */
+        },
+        {
+            dc_bits:{},
+            dc_huffval:{},
+            ac_bits:{0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,125},
+            ac_huffval:{
+                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
+            },/*,0xonly,0xthe,0xfirst,0x162,0xbytes,0xare,0xavailable,0x*/
+        },
+        {
+            dc_bits:{0,3,1,1,1,1,1,1,1,1,1,0},
+            dc_huffval:{0,1,2,3,4,5,6,7,8,9,0xa,0xb},
+            ac_bits:{},
+            ac_huffval:{},  /* only the first 162 bytes are available */
+        },
+        {
+            dc_bits:{},
+            dc_huffval:{},
+            ac_bits:{0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,119},
+            ac_huffval:{
+                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
+            },/*,0xonly,0xthe,0xfirst,0x162,0xbytes,0xare,0xavailable,0x*/
+        },
+    }
+};
+#endif
+
+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<ProcessState> 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;
+}
-- 
1.7.4.1



More information about the Libva mailing list