[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