Commit b0e4126e authored by Austin Yuan's avatar Austin Yuan

re-arrange test programs

Signed-off-by: default avatarAustin Yuan <shengquan.yuan@intel.com>
parent ec0e66e5
......@@ -126,6 +126,10 @@ AC_OUTPUT([
i965_drv_video/shaders/mpeg2/vld/Makefile
i965_drv_video/shaders/render/Makefile
test/Makefile
test/basic/Makefile
test/decode/Makefile
test/putsurface/Makefile
test/encode/Makefile
libva.pc
libva-x11.pc
])
......
......@@ -20,62 +20,17 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
check_PROGRAMS = test_01 test_02 test_03 test_04 test_05 test_06 \
test_07 test_08 test_09 test_10 test_11 test_12
bin_PROGRAMS = vainfo
testdir = $(bindir)
AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/test/basic -I$(top_srcdir)/src/x11 -DIN_LIBVA
AM_CFLAGS = -I$(top_srcdir)/../../include/external/ -I$(top_srcdir)/src -I$(top_srcdir)/src/x11 -DIN_LIBVA
TESTS = $(check_PROGRAMS)
TEST_LIBS = $(top_srcdir)/src/$(libvabackendlib)
vainfo_LDADD = $(top_srcdir)/src/$(libvabackendlib)
vainfo_DEPENDENCIES = $(top_srcdir)/src/$(libvabackendlib)
vainfo_SOURCES = vainfo.c
test_01_LDADD = $(TEST_LIBS)
test_01_SOURCES = test_01.c
test_02_LDADD = $(TEST_LIBS)
test_02_SOURCES = test_02.c
test_03_LDADD = $(TEST_LIBS)
test_03_SOURCES = test_03.c
test_04_LDADD = $(TEST_LIBS)
test_04_SOURCES = test_04.c
test_05_LDADD = $(TEST_LIBS)
test_05_SOURCES = test_05.c
test_06_LDADD = $(TEST_LIBS)
test_06_SOURCES = test_06.c
test_07_LDADD = $(TEST_LIBS)
test_07_SOURCES = test_07.c
test_08_LDADD = $(TEST_LIBS)
test_08_SOURCES = test_08.c
test_09_LDADD = $(TEST_LIBS)
test_09_SOURCES = test_09.c
test_10_LDADD = $(TEST_LIBS)
test_10_SOURCES = test_10.c
test_11_LDADD = $(TEST_LIBS)
test_11_SOURCES = test_11.c
test_12_LDADD = $(TEST_LIBS)
test_12_SOURCES = test_12.c
EXTRA_DIST = test_common.c mpeg2-I.jpg mpeg2-I.mpg
SUBDIRS = basic decode encode putsurface
valgrind: $(check_PROGRAMS)
for a in $(check_PROGRAMS); do \
valgrind --leak-check=full --show-reachable=yes .libs/$$a; \
done
valgrind: vainfo
valgrind --leak-check=full --show-reachable=yes .libs/vainfo;
# Copyright (c) 2007 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.
bin_PROGRAMS = test_01 test_02 test_03 test_04 test_05 test_06 \
test_07 test_08 test_09 test_10 test_11
TEST_LIBS = $(top_srcdir)/src/$(libvabackendlib)
test_01_LDADD = $(TEST_LIBS)
test_01_SOURCES = test_01.c
test_02_LDADD = $(TEST_LIBS)
test_02_SOURCES = test_02.c
test_03_LDADD = $(TEST_LIBS)
test_03_SOURCES = test_03.c
test_04_LDADD = $(TEST_LIBS)
test_04_SOURCES = test_04.c
test_05_LDADD = $(TEST_LIBS)
test_05_SOURCES = test_05.c
test_06_LDADD = $(TEST_LIBS)
test_06_SOURCES = test_06.c
test_07_LDADD = $(TEST_LIBS)
test_07_SOURCES = test_07.c
test_08_LDADD = $(TEST_LIBS)
test_08_SOURCES = test_08.c
test_09_LDADD = $(TEST_LIBS)
test_09_SOURCES = test_09.c
test_10_LDADD = $(TEST_LIBS)
test_10_SOURCES = test_10.c
test_11_LDADD = $(TEST_LIBS)
test_11_SOURCES = test_11.c
EXTRA_DIST = test_common.c
valgrind: $(bin_PROGRAMS)
for a in $(bin_PROGRAMS); do \
valgrind --leak-check=full --show-reachable=yes .libs/$$a; \
done
# Copyright (c) 2007 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.
bin_PROGRAMS = mpeg2vldemo
AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/x11 -DIN_LIBVA
TEST_LIBS = $(top_srcdir)/src/$(libvabackendlib)
mpeg2vldemo_LDADD = $(TEST_LIBS)
mpeg2vldemo_SOURCES = mpeg2vldemo.c
valgrind: $(bin_PROGRAMS)
for a in $(bin_PROGRAMS); do \
valgrind --leak-check=full --show-reachable=yes .libs/$$a; \
done
/*
* Copyright (c) 2007 Intel Corporation. All Rights Reserved.
* 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
......@@ -22,23 +22,38 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#define TEST_DESCRIPTION "Sample MPEG2 VLD Decoding"
#ifdef IN_LIBVA
#include <va_x11.h>
#else
#include <va/va_x11.h>
#endif
/*
* it is a real program to show how VAAPI decode work,
* It does VLD decode for a simple MPEG2 clip "mpeg2-I.m2v"
* "mpeg2-I.m2v" and VA parameters are hardcoded into mpeg2vldemo.c,
* See mpeg2-I.jif to know how those VA parameters come from
*
* gcc -o mpeg2vldemo mpeg2vldemo.c -lva -lva-x11
* ./mpeg2vldemo : only do decode
* ./mpeg2vldemo <any parameter >: decode+display
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <X11/Xlib.h>
#include "test_common.c"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void pre()
{
test_init();
#include <assert.h>
#include <va/va.h>
#include <va/va_x11.h>
#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 16x16 MPEG2 video clip,it has one I frame
......@@ -120,23 +135,43 @@ static VASliceParameterBufferMPEG2 slice_param={
#define CLIP_WIDTH 16
#define CLIP_HEIGHT 16
int surf_width=CLIP_WIDTH,surf_height=CLIP_HEIGHT;
int win_width=CLIP_WIDTH<<1,win_height=CLIP_HEIGHT<<1;
#define WIN_WIDTH (CLIP_WIDTH<<1)
#define WIN_HEIGHT (CLIP_HEIGHT<<1)
void test()
int main(int argc,char **argv)
{
VAEntrypoint entrypoints[5];
int num_entrypoints,vld_entrypoint;
VAConfigAttrib attrib;
VAConfigID config_id;
VASurfaceID vaSurface;
VAContextID vaContext;
VABufferID vaPicParamBuf,vaIQMatrixBuf,vaSliceParamBuf,vaSliceDataBuf;
Window win = 0;
VASurfaceID surface_id;
VAContextID context_id;
VABufferID pic_param_buf,iqmatrix_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;
x11_display = XOpenDisplay(":0.0");
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, VAProfileMPEG2Main, entrypoints,
&num_entrypoints);
ASSERT( VA_STATUS_SUCCESS == va_status );
CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
for (vld_entrypoint = 0; vld_entrypoint < num_entrypoints; vld_entrypoint++) {
if (entrypoints[vld_entrypoint] == VAEntrypointVLD)
......@@ -144,107 +179,108 @@ void test()
}
if (vld_entrypoint == num_entrypoints) {
/* not find VLD entry point */
ASSERT(0);
assert(0);
}
/* Assuming finding VLD, find out the format for the render target */
attrib.type = VAConfigAttribRTFormat;
va_status = vaGetConfigAttributes(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD,
vaGetConfigAttributes(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD,
&attrib, 1);
ASSERT( VA_STATUS_SUCCESS == va_status );
if ((attrib.value & VA_RT_FORMAT_YUV420) == 0) {
/* not find desired YUV420 RT format */
ASSERT(0);
assert(0);
}
va_status = vaCreateConfig(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD,
&attrib, 1,&config_id);
ASSERT( VA_STATUS_SUCCESS == va_status );
va_status = vaCreateSurfaces(va_dpy,surf_width,surf_height,
VA_RT_FORMAT_YUV420, 1, &vaSurface);
ASSERT( VA_STATUS_SUCCESS == va_status );
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,
&vaSurface,
&surface_id,
1,
&vaContext);
ASSERT( VA_STATUS_SUCCESS == va_status );
&context_id);
CHECK_VASTATUS(va_status, "vaCreateContext");
va_status = vaCreateBuffer(va_dpy, vaContext,
va_status = vaCreateBuffer(va_dpy, context_id,
VAPictureParameterBufferType,
sizeof(VAPictureParameterBufferMPEG2),
1, &pic_param,
&vaPicParamBuf);
ASSERT( VA_STATUS_SUCCESS == va_status );
va_status = vaCreateBuffer(va_dpy, vaContext,
&pic_param_buf);
CHECK_VASTATUS(va_status, "vaCreateBuffer");
va_status = vaCreateBuffer(va_dpy, context_id,
VAIQMatrixBufferType,
sizeof(VAIQMatrixBufferMPEG2),
1, &iq_matrix,
&vaIQMatrixBuf );
ASSERT( VA_STATUS_SUCCESS == va_status );
&iqmatrix_buf );
CHECK_VASTATUS(va_status, "vaCreateBuffer");
va_status = vaCreateBuffer(va_dpy, vaContext,
va_status = vaCreateBuffer(va_dpy, context_id,
VASliceParameterBufferType,
sizeof(VASliceParameterBufferMPEG2),
1,
&slice_param, &vaSliceParamBuf);
ASSERT( VA_STATUS_SUCCESS == va_status );
&slice_param, &slice_param_buf);
CHECK_VASTATUS(va_status, "vaCreateBuffer");
va_status = vaCreateBuffer(va_dpy, vaContext,
va_status = vaCreateBuffer(va_dpy, context_id,
VASliceDataBufferType,
0xc4-0x2f+1,
1,
mpeg2_clip+0x2f,
&vaSliceDataBuf);
ASSERT( VA_STATUS_SUCCESS == va_status );
va_status = vaBeginPicture(va_dpy, vaContext, vaSurface);
ASSERT( VA_STATUS_SUCCESS == va_status );
va_status = vaRenderPicture(va_dpy,vaContext, &vaPicParamBuf, 1);
ASSERT( VA_STATUS_SUCCESS == va_status );
va_status = vaRenderPicture(va_dpy,vaContext, &vaIQMatrixBuf, 1);
ASSERT( VA_STATUS_SUCCESS == va_status );
&slice_data_buf);
CHECK_VASTATUS(va_status, "vaCreateBuffer");
va_status = vaRenderPicture(va_dpy,vaContext, &vaSliceParamBuf, 1);
ASSERT( VA_STATUS_SUCCESS == va_status );
va_status = vaBeginPicture(va_dpy, context_id, surface_id);
CHECK_VASTATUS(va_status, "vaBeginPicture");
va_status = vaRenderPicture(va_dpy,vaContext, &vaSliceDataBuf, 1);
ASSERT( VA_STATUS_SUCCESS == va_status );
va_status = vaEndPicture(va_dpy,vaContext);
ASSERT( VA_STATUS_SUCCESS == va_status );
va_status = vaSyncSurface(va_dpy, vaSurface);
ASSERT( VA_STATUS_SUCCESS == va_status );
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, &slice_param_buf, 1);
CHECK_VASTATUS(va_status, "vaRenderPicture");
win = XCreateSimpleWindow(dpy, RootWindow(dpy, 0), 0, 0,
win_width,win_height, 0, 0, WhitePixel(dpy, 0));
XMapWindow(dpy, win);
XSync(dpy, False);
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 = vaPutSurface(va_dpy, vaSurface, win,
0,0,surf_width,surf_height,
0,0,win_width,win_height,
NULL,0,0);
ASSERT( VA_STATUS_SUCCESS == va_status );
va_status = vaSyncSurface(va_dpy, surface_id);
CHECK_VASTATUS(va_status, "vaSyncSurface");
if (putsurface) {
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);
CHECK_VASTATUS(va_status, "vaPutSurface");
}
printf("press any key to exit\n");
getchar();
vaDestroySurfaces(va_dpy,&vaSurface,1);
vaDestroySurfaces(va_dpy,&surface_id,1);
vaDestroyConfig(va_dpy,config_id);
vaDestroyContext(va_dpy,vaContext);
}
vaDestroyContext(va_dpy,context_id);
void post()
{
test_terminate();
vaTerminate(va_dpy);
XCloseDisplay(x11_display);
return 0;
}
# Copyright (c) 2007 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.
bin_PROGRAMS = h264encode
AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/x11 -DIN_LIBVA
TEST_LIBS = $(top_srcdir)/src/$(libvabackendlib)
h264encode_LDADD = $(TEST_LIBS)
h264encode_SOURCES = h264encode.c
valgrind: $(bin_PROGRAMS)
for a in $(bin_PROGRAMS); do \
valgrind --leak-check=full --show-reachable=yes .libs/$$a; \
done
/*
* 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 encoding work,
* It does H264 element stream level encoding on auto-generated YUV data
*
* gcc -o h264encode h264encode -lva -lva-x11 -I /usr/include/va
* ./h264encode -w <width> -h <height> -n <frame_num>
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <X11/Xlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include "va.h"
#include "va_x11.h"
#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); \
}
#define SURFACE_NUM 18 /* 16 surfaces for src, 2 surface for reconstructed/reference */
static Display *x11_display;
static VADisplay va_dpy;
static VAContextID context_id;
static VASurfaceID surface_id[SURFACE_NUM];
static Window display_win = 0;
static int win_width;
static int win_height;
static int coded_fd;
static char coded_file[256];
static int frame_width=352, frame_height=288;
static int frame_rate = 30;
static int frame_count = 1000;
static int intra_count = 30;
static int frame_bitrate = 64000;
static int initial_qp = 15;
static int minimal_qp = 0;
static int upload_source_YUV_once_for_all()
{
VAImage surface_image;
void *surface_p=NULL, *U_start,*V_start;
VAStatus va_status;
int box_width=8;
int row_shift=0;
int i;
for (i=0; i<SURFACE_NUM-2; i++) {
upload_surafce(va_dpy, surface_id[i], box_width, row_shift, 0);
row_shift++;
if (row_shift==(2*box_width)) row_shift= 0;
}
return 0;
}
static int save_coded_buf(VABufferID coded_buf, int current_frame, int frame_skipped)
{
void *coded_p=NULL;
int coded_size,coded_offset,wrt_size;
VAStatus va_status;
va_status = vaMapBuffer(va_dpy,coded_buf,&coded_p);
coded_size = *((unsigned long *) coded_p); /* first DWord is the coded video size */
coded_offset = *((unsigned long *) (coded_p + 4)); /* second DWord is byte offset */
wrt_size = write(coded_fd,coded_p+coded_offset,coded_size);
assert(wrt_size==coded_size);
vaUnmapBuffer(va_dpy,coded_buf);
printf("\r "); /* return back to startpoint */
switch (current_frame % 4) {
case 0:
printf("|");
break;
case 1:
printf("/");
break;
case 2:
printf("-");
break;
case 3:
printf("\\");
break;
}
printf("%08d", current_frame);
if (current_frame % intra_count == 0)
printf("(I)");
else
printf("(P)");
printf("(%06d bytes coded)",coded_size);
if (frame_skipped)
printf("(SKipped)");
return;
}
static int display_surface(int current_frame, int *exit_encode)
{
Window win = display_win;
XEvent event;
VAStatus va_status;
if (current_frame == 0) {
win_width = frame_width;
win_height = frame_height;
}
if (win == 0) { /* display reconstructed surface */
win = XCreateSimpleWindow(x11_display, RootWindow(x11_display, 0), 0, 0,
frame_width, frame_height, 0, 0, WhitePixel(x11_display, 0));
XMapWindow(x11_display, win);
XSync(x11_display, False);
display_win = win;
}
*exit_encode = 0;
while(XPending(x11_display)) {
XNextEvent(x11_display, &event);
/* bail on any focused key press */
if(event.type == KeyPress) {
*exit_encode = 1;
break;
}
/* rescale the video to fit the window */
if(event.type == ConfigureNotify) {
win_width = event.xconfigure.width;
win_height = event.xconfigure.height;
}
}
va_status = vaPutSurface(va_dpy, surface_id[current_frame], win,
0,0, frame_width, frame_height,
0,0, win_width, win_height,
NULL,0,0);
return;
}
enum {
SH_LEVEL_1=10,
SH_LEVEL_1B=11,
SH_LEVEL_2=20,
SH_LEVEL_3=30,
SH_LEVEL_31=31,
SH_LEVEL_32=32,
SH_LEVEL_4=40,
SH_LEVEL_5=50
};
static int do_h264_encoding(void)
{
VAEncSequenceParameterBufferH264 seq_h264;
VAEncPictureParameterBufferH264 pic_h264;
VAEncSliceParameterBuffer slice_h264;
VAStatus va_status;
VABufferID coded_buf, seq_param_buf, pic_param_buf, slice_param_buf;
int codedbuf_size;
VASurfaceStatus surface_status;
int src_surface, dst_surface, ref_surface;
int putsurface=0, frame_skipped = 0;
int exit_encode = 0;
int i;
codedbuf_size = (frame_width * frame_height * 400) / (16*16);
src_surface = 0;
/* the last two frames are reference/reconstructed frame */
dst_surface = SURFACE_NUM - 1;
ref_surface = SURFACE_NUM - 2;
for (i=0; i < frame_count; i++) {
va_status = vaBeginPicture(va_dpy, context_id, surface_id[src_surface]);
CHECK_VASTATUS(va_status,"vaBeginPicture");
if (i == 0) {
seq_h264.level_idc = SH_LEVEL_3;
seq_h264.picture_width_in_mbs = frame_width;
seq_h264.picture_height_in_mbs = frame_height;
seq_h264.bits_per_second = frame_bitrate;
seq_h264.frame_rate = frame_rate;
seq_h264.initial_qp = initial_qp;
seq_h264.min_qp = minimal_qp;
seq_h264.basic_unit_size = 6;
seq_h264.intra_period = intra_count;
va_status = vaCreateBuffer(va_dpy, context_id,
VAEncSequenceParameterBufferType,
sizeof(seq_h264),1,&seq_h264,&seq_param_buf);
CHECK_VASTATUS(va_status,"vaCreateBuffer");;
va_status = vaRenderPicture(va_dpy,context_id, &seq_param_buf, 1);
CHECK_VASTATUS(va_status,"vaRenderPicture");;
}
va_status = vaCreateBuffer(va_dpy,context_id,VAEncCodedBufferType,
codedbuf_size, 1, NULL, &coded_buf);
/* if a frame is skipped, current frame still use last reference frame */
if (frame_skipped == 0) {
/* swap ref/dst */
int tmp = dst_surface;
dst_surface = ref_surface;
ref_surface = tmp;
}
pic_h264.reference_picture = surface_id[ref_surface];
pic_h264.reconstructed_picture= surface_id[dst_surface];
pic_h264.coded_buf = coded_buf;
pic_h264.picture_width = frame_width;
pic_h264.picture_height = frame_height;
pic_h264.last_picture = (i==frame_count);
va_status = vaCreateBuffer(va_dpy, context_id,VAEncPictureParameterBufferType,
sizeof(pic_h264),1,&pic_h264,&pic_param_buf);
CHECK_VASTATUS(va_status,"vaCreateBuffer");;
/* one frame, one slice */
slice_h264.start_row_number = 0;
slice_h264.slice_height = frame_height/16; /* Measured by MB */
slice_h264.slice_flags.bits.is_intra = i % intra_count;
slice_h264.slice_flags.bits.disable_deblocking_filter_idc = 0;
va_status = vaCreateBuffer(va_dpy,context_id,VAEncSliceParameterBufferType,
sizeof(slice_h264),1,&slice_h264,&slice_param_buf);
CHECK_VASTATUS(va_status,"vaCreateBuffer");;
va_status = vaRenderPicture(va_dpy,context_id, &pic_param_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 = vaEndPicture(va_dpy,context_id);
CHECK_VASTATUS(va_status,"vaEndPicture");;
va_status = vaSyncSurface(va_dpy, surface_id[0]);
CHECK_VASTATUS(va_status,"vaSyncSurface");;
va_status = vaQuerySurfaceStatus(va_dpy, surface_id[src_surface],&surface_status);
frame_skipped = (surface_status & VASurfaceSkipped);
save_coded_buf(coded_buf, i, frame_skipped);
/* should display reconstructed frame, but just diplay source frame */
display_surface(src_surface, &exit_encode);
if (exit_encode)
frame_count = i;
/* use next surface */
src_surface++;
if (src_surface == (SURFACE_NUM - 2))
src_surface = 0;
}
return 0;
}
int main(int argc,char **argv)
{
VAEntrypoint entrypoints[5];
int num_entrypoints,slice_entrypoint;
VAConfigAttrib attrib[2];
VAConfigID config_id;
int major_ver, minor_ver;
VAStatus va_status;
char c;
strcpy(coded_file, "/tmp/demo.264");
while ((c =getopt(argc,argv,"w:h:n:p:f:r:q:s:o:?") ) != EOF) {
switch (c) {
case 'w':
frame_width = atoi(optarg);
break;
case 'h':
frame_height = atoi(optarg);
break;
case 'n':
frame_count = atoi(optarg);
break;
case 'p':
intra_count = atoi(optarg);
break;
case 'f':
frame_rate = atoi(optarg);
break;
case 'b':
frame_bitrate = atoi(optarg);
break;
case 'q':
initial_qp = atoi(optarg);
break;
case 's':
minimal_qp = atoi(optarg);
break;
case 'o':
strcpy(coded_file, optarg);
break;
case ':':
case '?':
printf("./h264encode <options>\n");
printf(" -w -h: resolution\n");
printf(" -n frame number\n");
printf(" -p P frame count between two I frames\n");
printf(" -f frame rate\n");
printf(" -r bit rate\n");
printf(" -q initial QP\n");
printf(" -s maximum QP\n");
printf(" -s coded file\n");
exit(0);
}
}
x11_display = XOpenDisplay(":0.0");
assert(x11_display);
va_dpy = vaGetDisplay(x11_display);
va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
CHECK_VASTATUS(va_status, "vaInitialize");
vaQueryConfigEntrypoints(va_dpy, VAProfileH264Baseline, entrypoints,
&num_entrypoints);
for (slice_entrypoint = 0; slice_entrypoint < num_entrypoints; slice_entrypoint++) {
if (entrypoints[slice_entrypoint] == VAEntrypointEncSlice)
break;
}
if (slice_entrypoint == num_entrypoints) {
/* not find Slice entry point */
assert(0);
}
/* find out the format for the render target, and rate control mode */
attrib[0].type = VAConfigAttribRTFormat;
attrib[1].type = VAConfigAttribRateControl;
vaGetConfigAttributes(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice,
&attrib[0], 2);
if ((attrib[0].value & VA_RT_FORMAT_YUV420) == 0) {
/* not find desired YUV420 RT format */
assert(0);
}
if ((attrib[1].value & VA_RC_VBR) == 0) {
/* Can't find matched RC mode */
printf("VBR mode doesn't found, exit\n");
assert(0);
}
attrib[0].value = VA_RT_FORMAT_YUV420; /* set to desired RT format */
attrib[1].value = VA_RC_VBR; /* set to desired RC mode */
va_status = vaCreateConfig(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice,
&attrib[0], 2,&config_id);
CHECK_VASTATUS(va_status, "vaCreateConfig");
va_status = vaCreateSurfaces(va_dpy,frame_width, frame_height,
VA_RT_FORMAT_YUV420, SURFACE_NUM, &surface_id[0]);
CHECK_VASTATUS(va_status, "vaCreateSurfaces");
/* Create a context for this decode pipe */
va_status = vaCreateContext(va_dpy, config_id,
frame_width, ((frame_height+15)/16)*16,
VA_PROGRESSIVE,&surface_id[0],SURFACE_NUM,&context_id);
CHECK_VASTATUS(va_status, "vaCreateContext");
/* store coded data into a file */
coded_fd = open(coded_file,O_CREAT|O_RDWR, 0);
if (coded_fd == -1) {
printf("Open file %s failed, exit\n", coded_file);
exit(1);
}
printf("Coded %d frames, %dx%d, save the coded file into %s\n",
frame_count, frame_width, frame_height, coded_file);
do_h264_encoding();
vaDestroySurfaces(va_dpy,&surface_id[0],3);
vaDestroyConfig(va_dpy,config_id);
vaDestroyContext(va_dpy,context_id);
vaTerminate(va_dpy);
XCloseDisplay(x11_display);
return 0;
}
# Copyright (c) 2007 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.
bin_PROGRAMS = putsurface
AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/x11 -DIN_LIBVA
TEST_LIBS = $(top_srcdir)/src/$(libvabackendlib)
putsurface_LDADD = $(TEST_LIBS)
putsurface_SOURCES = putsurface.c
valgrind: $(bin_PROGRAMS)
for a in $(bin_PROGRAMS); do \
valgrind --leak-check=full --show-reachable=yes .libs/$$a; \
done
static int yuvgen_planar(int width, int height,
unsigned char *Y_start, int Y_pitch,
unsigned char *U_start, int U_pitch,
unsigned char *V_start, int V_pitch,
int UV_interleave, int box_width, int row_shift,
int field)
{
int row;
/* copy Y plane */
for (row=0;row<height;row++) {
unsigned char *Y_row = Y_start + row * Y_pitch;
int jj, xpos, ypos;
ypos = (row / box_width) & 0x1;
/* fill garbage data into the other field */
if (((field == VA_TOP_FIELD) && (row &1))
|| ((field == VA_BOTTOM_FIELD) && ((row &1)==0))) {
memset(Y_row, 0xff, width);
continue;
}
for (jj=0; jj<width; jj++) {
xpos = ((row_shift + jj) / box_width) & 0x1;
if ((xpos == 0) && (ypos == 0))
Y_row[jj] = 0xeb;
if ((xpos == 1) && (ypos == 1))
Y_row[jj] = 0xeb;
if ((xpos == 1) && (ypos == 0))
Y_row[jj] = 0x10;
if ((xpos == 0) && (ypos == 1))
Y_row[jj] = 0x10;
}
}
/* copy UV data */
for( row =0; row < height/2; row++) {
unsigned short value = 0x80;
/* fill garbage data into the other field */
if (((field == VA_TOP_FIELD) && (row &1))
|| ((field == VA_BOTTOM_FIELD) && ((row &1)==0))) {
value = 0xff;
}
if (UV_interleave) {
unsigned short *UV_row = (unsigned short *)(U_start + row * U_pitch);
memset(UV_row, value, width);
} else {
unsigned char *U_row = U_start + row * U_pitch;
unsigned char *V_row = V_start + row * V_pitch;
memset (U_row,value,width/2);
memset (V_row,value,width/2);
}
}
return 0;
}
static int upload_surface(VADisplay va_dpy, VASurfaceID surface_id,
int box_width, int row_shift,
int field)
{
VAImage surface_image;
void *surface_p=NULL, *U_start,*V_start;
VAStatus va_status;
va_status = vaDeriveImage(va_dpy,surface_id,&surface_image);
CHECK_VASTATUS(va_status,"vaDeriveImage");
vaMapBuffer(va_dpy,surface_image.buf,&surface_p);
assert(VA_STATUS_SUCCESS == va_status);
U_start = surface_p + surface_image.offsets[1];
V_start = surface_p + surface_image.offsets[2];
/* assume surface is planar format */
yuvgen_planar(surface_image.width, surface_image.height,
surface_p, surface_image.pitches[0],
U_start, surface_image.pitches[1],
V_start, surface_image.pitches[2],
(surface_image.format.fourcc==VA_FOURCC_NV12),
box_width, row_shift, field);
vaUnmapBuffer(va_dpy,surface_image.buf);
vaDestroyImage(va_dpy,surface_image.image_id);
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <va/va.h>
#include <va/va_x11.h>
#include <assert.h>
#include <pthread.h>
/*currently, if XCheckWindowEvent was called in more than one thread, it would cause
* XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0.0"
* after 87 requests (83 known processed) with 0 events remaining.
*
* X Error of failed request: BadGC (invalid GC parameter)
* Major opcode of failed request: 60 (X_FreeGC)
* Resource id in failed request: 0x600034
* Serial number of failed request: 398
* Current serial number in output stream: 399
* The root cause is unknown. */
#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); \
}
#include "loadsurface.h"
#define SURFACE_NUM 5
static VASurfaceID surface_id[SURFACE_NUM];
static int surface_width=352, surface_height=288;
static int win_width=352, win_height=288;
static Window win_thread0, win_thread1;
static Pixmap pixmap_thread0, pixmap_thread1;
static GC context_thread0, context_thread1;
static Display *x11_display;
static VADisplay *va_dpy;
static int multi_thread=0;
static int put_pixmap = 0;
static int test_clip = 1;
static int display_field = VA_FRAME_PICTURE;
static int check_event = 1;
static int verbose=0;
static pthread_mutex_t surface_mutex[SURFACE_NUM];
static pthread_mutex_t gmutex;
static int box_width=32;
static Pixmap create_pixmap(int width, int height)
{
int screen = DefaultScreen(x11_display);
Window root;
Pixmap pixmap;
XWindowAttributes attr;
root = RootWindow(x11_display, screen);
XGetWindowAttributes (x11_display, root, &attr);
printf("Create a pixmap from ROOT window %dx%d\n\n", attr.width, attr.height);
pixmap = XCreatePixmap(x11_display, root, attr.width, attr.height,
DefaultDepth(x11_display, DefaultScreen(x11_display)));
return pixmap;
}
static int create_window(int width, int height)
{
int screen = DefaultScreen(x11_display);
Window root, win;
root = RootWindow(x11_display, screen);
printf("Create window0 for thread0\n");
win_thread0 = win = XCreateSimpleWindow(x11_display, root, 0, 0, width, height,
0, 0, WhitePixel(x11_display, 0));
if (win) {
XSizeHints sizehints;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize;
XSetNormalHints(x11_display, win, &sizehints);
XSetStandardProperties(x11_display, win, "Thread 0", "Thread 0",
None, (char **)NULL, 0, &sizehints);
XMapWindow(x11_display, win);
}
context_thread0 = XCreateGC(x11_display, win, 0, 0);
XSelectInput(x11_display, win, KeyPressMask | StructureNotifyMask);
XSync(x11_display, False);
if (put_pixmap)
pixmap_thread0 = create_pixmap(width, height);
if (multi_thread == 0)
return 0;
printf("Create window1 for thread1\n");
win_thread1 = win = XCreateSimpleWindow(x11_display, root, width, 0, width, height,
0, 0, WhitePixel(x11_display, 0));
if (win) {
XSizeHints sizehints;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize;
XSetNormalHints(x11_display, win, &sizehints);
XSetStandardProperties(x11_display, win, "Thread 1", "Thread 1",
None, (char **)NULL, 0, &sizehints);
XMapWindow(x11_display, win);
}
if (put_pixmap)
pixmap_thread1 = create_pixmap(width, height);
context_thread1 = XCreateGC(x11_display, win, 0, 0);
XSelectInput(x11_display, win, KeyPressMask | StructureNotifyMask);
XSync(x11_display, False);
return 0;
}
static VASurfaceID get_next_free_surface(int *index)
{
VASurfaceStatus surface_status;
int i;
assert(index);
for (i=0; i<SURFACE_NUM; i++) {
surface_status = 0;
vaQuerySurfaceStatus(va_dpy, surface_id[i], &surface_status);
if (surface_status == VASurfaceReady)
{
if (0 == pthread_mutex_trylock(&surface_mutex[i]))
{
*index = i;
break;
}
}
}
if (i==SURFACE_NUM)
return VA_INVALID_SURFACE;
else
return surface_id[i];
}
static int putsurface_thread(void *data)
{
int width=win_width, height=win_height;
Drawable draw;
Window win = (Window)data;
Pixmap pixmap = 0;
GC context = NULL;
int quit = 0;
VAStatus vaStatus;
int row_shift = 0;
int index = 0;
Bool is_event;
XEvent event;
if (win == win_thread0) {
printf("Enter into thread0\n\n");
pixmap = pixmap_thread0;
context = context_thread0;
}
if (win == win_thread1) {
printf("Enter into thread1\n\n");
pixmap = pixmap_thread1;
context = context_thread1;
}
if (put_pixmap) {
printf("vaPutSurface into a Pixmap, then copy into the Window\n\n");
draw = pixmap;
} else {
printf("vaPutSurface into a Window directly\n\n");
draw = win;
}
while (!quit) {
VASurfaceID surface_id = VA_INVALID_SURFACE;
while (surface_id == VA_INVALID_SURFACE)
surface_id = get_next_free_surface(&index);
if (verbose) printf("Thread %x Display surface 0x%p,\n", (unsigned int)win, (void *)surface_id);
upload_surface(va_dpy, surface_id, box_width, row_shift, display_field);
vaStatus = vaPutSurface(va_dpy, surface_id, draw,
0,0,surface_width,surface_height,
0,0,width,height,
NULL,0,display_field);
CHECK_VASTATUS(vaStatus,"vaPutSurface");
if (put_pixmap)
XCopyArea(x11_display, pixmap, win, context, 0, 0, width, height, 0, 0);
pthread_mutex_unlock(&surface_mutex[index]);
if (check_event) {
pthread_mutex_lock(&gmutex);
is_event =XCheckWindowEvent(x11_display, win, StructureNotifyMask|KeyPressMask,&event);
pthread_mutex_unlock(&gmutex);
if (is_event) {
/* bail on any focused key press */
if(event.type == KeyPress) {
quit = 1;
break;
}
/* rescale the video to fit the window */
if(event.type == ConfigureNotify) {
width = event.xconfigure.width;
height = event.xconfigure.height;
printf("Scale window to %dx%d\n", width, height);
}
}
}
row_shift++;
if (row_shift==(2*box_width)) row_shift= 0;
}
pthread_exit(NULL);
}
int main(int argc,char **argv)
{
int major_ver, minor_ver;
VAStatus va_status;
pthread_t thread1;
int ret;
char c;
int i;
while ((c =getopt(argc,argv,"w:h:d:f:tep?nv") ) != EOF) {
switch (c) {
case '?':
printf("putsurface <options>\n");
printf(" -p output to pixmap\n");
printf(" -d the dimension of black/write square box, default is 32\n");
printf(" -t multi-threads\n");
printf(" -e don't check X11 event\n");
printf(" -c test clipbox\n");
printf(" -f <1/2> top field, or bottom field\n");
printf(" -v verbose output\n");
exit(0);
break;
case 'w':
win_width = atoi(optarg);
break;
case 'h':
win_height = atoi(optarg);
break;
case 'd':
box_width = atoi(optarg);
break;
case 't':
multi_thread = 1;
printf("Two threads to do vaPutSurface\n");
break;
case 'e':
check_event = 0;
break;
case 'p':
put_pixmap = 1;
break;
case 'c':
test_clip = 1;
break;
case 'f':
if (atoi(optarg) == 1) {
printf("Display TOP field\n");
display_field = VA_TOP_FIELD;
} else if (atoi(optarg) == 2) {
printf("Display BOTTOM field\n");
display_field = VA_BOTTOM_FIELD;
} else
printf("The validate input for -f is: 1(top field)/2(bottom field)\n");
break;
case 'v':
verbose = 1;
printf("Enable verbose output\n");
break;
}
}
x11_display = XOpenDisplay(":0.0");
if (x11_display == NULL) {
fprintf(stderr, "Can't connect X server!\n");
exit(-1);
}
create_window(win_width, win_height);
va_dpy = vaGetDisplay(x11_display);
va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
CHECK_VASTATUS(va_status, "vaInitialize");
surface_width = win_width;
surface_height = win_height;
va_status = vaCreateSurfaces(va_dpy,surface_width, surface_height,
VA_RT_FORMAT_YUV420, SURFACE_NUM, &surface_id[0]);
CHECK_VASTATUS(va_status, "vaCreateSurfaces");
if (check_event)
pthread_mutex_init(&gmutex, NULL);
for(i = 0; i< SURFACE_NUM; i++)
pthread_mutex_init(&surface_mutex[i], NULL);
if (multi_thread == 1)
ret = pthread_create(&thread1, NULL, (void *)putsurface_thread, (void*)win_thread1);
putsurface_thread((void *)win_thread0);
if (multi_thread == 1)
pthread_join(thread1, (void **)&ret);
vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM);
vaTerminate(va_dpy);
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment