From 76a1501dd33f56236c28e74d24e8da3c1a3a381f Mon Sep 17 00:00:00 2001 From: Austin Yuan Date: Thu, 28 Feb 2013 14:28:14 +0800 Subject: [PATCH] test/h264encode: refine the h264encode to support advanced mode Signed-off-by: Austin Yuan --- test/android_winsys.cpp | 22 +- test/common/va_display_android.cpp | 16 +- test/encode/Android.mk | 23 ++ test/encode/Makefile.am | 17 +- test/encode/h264encode_common.c | 435 ------------------------------------- test/encode/h264encode_x11.c | 102 --------- 6 files changed, 53 insertions(+), 562 deletions(-) delete mode 100644 test/encode/h264encode_common.c delete mode 100644 test/encode/h264encode_x11.c diff --git a/test/android_winsys.cpp b/test/android_winsys.cpp index 3c6a245..21df279 100644 --- a/test/android_winsys.cpp +++ b/test/android_winsys.cpp @@ -32,20 +32,28 @@ do { \ client = new SurfaceComposerClient(); \ android::DisplayInfo info; \ int w, h; \ - \ - client->getDisplayInfo(android::DisplayID(0), &info); \ + sp dtoken(SurfaceComposerClient::getBuiltInDisplay( \ + ISurfaceComposer::eDisplayIdMain)); \ + client->getDisplayInfo(dtoken, &info); \ /*w = min(win_width, info.w);*/ \ /*h = min(win_height, info.h);*/ \ w = win_width, h = win_height; \ \ - surface_ctrl = client->createSurface(getpid(), 0, w, h, PIXEL_FORMAT_RGB_565); \ + surface_ctrl = client->createSurface(String8("libVA"), w, h, PIXEL_FORMAT_RGB_888); \ android_surface = surface_ctrl->getSurface(); \ \ - client->openGlobalTransaction(); \ - surface_ctrl->setPosition(x, y); \ + SurfaceComposerClient::openGlobalTransaction(); \ + surface_ctrl->setLayer(0x7FFFFFFF); \ + surface_ctrl->show(); \ + SurfaceComposerClient::closeGlobalTransaction(); \ + \ + SurfaceComposerClient::openGlobalTransaction(); \ + surface_ctrl->setPosition(0, 0); \ + SurfaceComposerClient::closeGlobalTransaction(); \ + \ + SurfaceComposerClient::openGlobalTransaction(); \ surface_ctrl->setSize(w, h); \ - surface_ctrl->setLayer(0x100000); \ - client->closeGlobalTransaction(); \ + SurfaceComposerClient::closeGlobalTransaction(); \ } while (0) diff --git a/test/common/va_display_android.cpp b/test/common/va_display_android.cpp index 1e45ae9..82c05a3 100644 --- a/test/common/va_display_android.cpp +++ b/test/common/va_display_android.cpp @@ -29,15 +29,17 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include static unsigned int fake_display = 0xdeada01d; using namespace android; + sp client; sp android_surface; sp android_isurface; @@ -63,9 +65,9 @@ va_put_surface_android( const VARectangle *dst_rect ) { - sp proc(ProcessState::self()); - ProcessState::self()->startThreadPool(); - + //sp proc(ProcessState::self()); + //ProcessState::self()->startThreadPool(); + printf("Create window0 for thread0\n"); SURFACE_CREATE( client, diff --git a/test/encode/Android.mk b/test/encode/Android.mk index 9bc662a..e8305bc 100755 --- a/test/encode/Android.mk +++ b/test/encode/Android.mk @@ -6,6 +6,29 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := \ + ../common/va_display.c \ + ../common/va_display_android.cpp \ + h264encode.c + +LOCAL_CFLAGS += \ + -DANDROID + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../../va \ + $(LOCAL_PATH)/../common \ + $(TARGET_OUT_HEADERS)/libva + +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := h264encode + +LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libgui + +include $(BUILD_EXECUTABLE) + + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ ../common/va_display.c \ ../common/va_display_android.cpp \ avcenc.c diff --git a/test/encode/Makefile.am b/test/encode/Makefile.am index 07602ce..0f9efac 100644 --- a/test/encode/Makefile.am +++ b/test/encode/Makefile.am @@ -20,10 +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 = avcenc mpeg2enc -if USE_X11 -bin_PROGRAMS += h264encode -endif +bin_PROGRAMS = avcenc mpeg2enc h264encode AM_CPPFLAGS = \ -Wall \ @@ -31,15 +28,15 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/va \ $(NULL) -h264encode_SOURCES = h264encode_x11.c -h264encode_CFLAGS = $(X11_CFLAGS) +h264encode_SOURCES = h264encode.c +h264encode_CFLAGS = -I$(top_srcdir)/test/common -g h264encode_LDADD = \ $(top_builddir)/va/libva.la \ - $(top_builddir)/va/libva-x11.la \ - $(X11_LIBS) + $(top_builddir)/test/common/libva-display.la \ + -lpthread avcenc_SOURCES = avcenc.c -avcenc_CFLAGS = -I$(top_srcdir)/test/common +avcenc_CFLAGS = -I$(top_srcdir)/test/common -g avcenc_LDADD = \ $(top_builddir)/va/libva.la \ $(top_builddir)/test/common/libva-display.la \ @@ -52,8 +49,6 @@ mpeg2enc_LDADD = \ $(top_builddir)/test/common/libva-display.la \ -lpthread -EXTRA_DIST = h264encode_common.c - valgrind: $(bin_PROGRAMS) for a in $(bin_PROGRAMS); do \ valgrind --leak-check=full --show-reachable=yes .libs/$$a; \ diff --git a/test/encode/h264encode_common.c b/test/encode/h264encode_common.c deleted file mode 100644 index bba0e7d..0000000 --- a/test/encode/h264encode_common.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * 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 - * ./h264encode -w -h -n - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef ANDROID -#include -#else -#include -#endif - -#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 18 /* 16 surfaces for src, 2 surface for reconstructed/reference */ -#define CODEDBUF_NUM 5 -static VADisplay va_dpy; -static VASurfaceID surface_id[SURFACE_NUM]; -static VABufferID coded_buf[CODEDBUF_NUM]; -static VAContextID context_id; -static Display *x11_display; -static int coded_fd; -static char coded_file[256]; -static int frame_width=320, frame_height=240; -static int win_width; -static int win_height; -static int frame_display = 0; /* display the frame during encoding */ -static int frame_rate = 30; -static int frame_count = 400; -static int intra_count = 30; -static int frame_bitrate = 8000000; /* 8M */ -static int initial_qp = 15; -static int minimal_qp = 0; - -static int display_surface(int frame_id, int *exit_encode); - -static int upload_source_YUV_once_for_all() -{ - void *surface_p=NULL, *U_start,*V_start; - VAStatus va_status; - int box_width=8; - int row_shift=0; - int i; - - for (i=0; isize); - coded_size += write(coded_fd, buf_list->buf, buf_list->size); - buf_list = (VACodedBufferSegment *) buf_list->next; - } - 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)"); - printf(" "); - - return 0; -} - - -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) -{ - VAEncPictureParameterBufferH264 pic_h264; - VAEncSliceParameterBuffer slice_h264; - VAStatus va_status; - VABufferID seq_param_buf, pic_param_buf, slice_param_buf; - int codedbuf_size; - VASurfaceStatus surface_status; - int src_surface, dst_surface, ref_surface; - int codedbuf_idx = 0; - int frame_skipped = 0; - int i; - - /* upload RAW YUV data into all surfaces */ - upload_source_YUV_once_for_all(); - - codedbuf_size = (frame_width * frame_height * 400) / (16*16); - - for (i = 0; i < CODEDBUF_NUM; i++) { - /* create coded buffer once for all - * other VA buffers which won't be used again after vaRenderPicture. - * so APP can always vaCreateBuffer for every frame - * but coded buffer need to be mapped and accessed after vaRenderPicture/vaEndPicture - * so VA won't maintain the coded buffer - */ - va_status = vaCreateBuffer(va_dpy,context_id,VAEncCodedBufferType, - codedbuf_size, 1, NULL, &coded_buf[i]); - CHECK_VASTATUS(va_status,"vaCreateBuffer"); - } - - 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) { - VAEncSequenceParameterBufferH264 seq_h264; - VAEncMiscParameterRateControl rc_h264; - VABufferID seq_param_buf, rc_param_buf; - - - seq_h264.level_idc = SH_LEVEL_3; - seq_h264.picture_width_in_mbs = frame_width / 16; - seq_h264.picture_height_in_mbs = frame_height / 16; - seq_h264.bits_per_second = frame_bitrate; - //seq_h264.frame_rate = frame_rate; - rc_h264.initial_qp = initial_qp; - rc_h264.min_qp = minimal_qp; - rc_h264.basic_unit_size = 0; - - 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 = vaCreateBuffer(va_dpy, context_id, - VAEncMiscParameterBufferType, - sizeof(rc_h264),1,&rc_h264,&rc_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 = vaRenderPicture(va_dpy,context_id, &rc_param_buf, 1); - CHECK_VASTATUS(va_status,"vaRenderPicture");; - } - - - pic_h264.ReferenceFrames[0].picture_id= surface_id[ref_surface]; - pic_h264.CurrPic.picture_id= surface_id[dst_surface]; - pic_h264.coded_buf = coded_buf[codedbuf_idx]; - //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");; - - va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1); - CHECK_VASTATUS(va_status,"vaRenderPicture"); - - /* 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) == 0); - 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, &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[src_surface]); - CHECK_VASTATUS(va_status,"vaSyncSurface"); - - surface_status = (VASurfaceStatus) 0; - va_status = vaQuerySurfaceStatus(va_dpy, surface_id[src_surface],&surface_status); - frame_skipped = (surface_status & VASurfaceSkipped); - - save_coded_buf(coded_buf[codedbuf_idx], i, frame_skipped); -#if 0 - /* should display reconstructed frame, but just diplay source frame */ - if (frame_display) { - int exit_encode = 0; - - display_surface(src_surface, &exit_encode); - if (exit_encode) - frame_count = i; - } -#endif - /* use next surface */ - src_surface++; - if (src_surface == (SURFACE_NUM - 2)) - src_surface = 0; - - /* use next codedbuf */ - codedbuf_idx++; - if (codedbuf_idx == (CODEDBUF_NUM - 1)) - codedbuf_idx = 0; - - /* 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; - } - } - - 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, "/sdcard/1.264"); - while ((c =getopt(argc,argv,"w:h:n:p:f:r:q:s:o:d?") ) != 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 'd': - frame_display = 1; - break; - case 'o': - strcpy(coded_file, optarg); - break; - case ':': - case '?': - printf("./h264encode \n"); - printf(" -w -h: resolution\n"); - printf(" -n frame number\n"); - printf(" -d display the source frame\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(" -o coded file\n"); - exit(0); - } - } - -#ifdef ANDROID - x11_display = (Display*)malloc(sizeof(Display)); - *(x11_display) = 0x18c34078; -#else - x11_display = XOpenDisplay(":0.0"); -#endif - 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(); - - printf("\n\n"); - - vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM); - vaDestroyContext(va_dpy,context_id); - vaDestroyConfig(va_dpy,config_id); - - vaTerminate(va_dpy); - -#ifdef ANDROID - free(x11_display); -#else - XCloseDisplay(x11_display); -#endif - - return 0; -} diff --git a/test/encode/h264encode_x11.c b/test/encode/h264encode_x11.c deleted file mode 100644 index 3f7aff2..0000000 --- a/test/encode/h264encode_x11.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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 - * ./h264encode -w -h -n - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SURFACE_NUM 18 /* 16 surfaces for src, 2 surface for reconstructed/reference */ - -static Display *x11_display; -static VADisplay va_dpy; -static VASurfaceID surface_id[SURFACE_NUM]; -static Window display_win = 0; -static int win_width; -static int win_height; - -static int display_surface(int frame_id, int *exit_encode); - -#include "h264encode_common.c" - - -static int display_surface(int frame_id, int *exit_encode) -{ - Window win = display_win; - XEvent event; - VAStatus va_status; - - if (win == 0) { /* display reconstructed surface */ - win_width = frame_width; - win_height = frame_height; - - 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; - } - - va_status = vaPutSurface(va_dpy, surface_id[frame_id], win, - 0,0, frame_width, frame_height, - 0,0, win_width, win_height, - NULL,0,0); - - *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; - } - } - - return 0; -} - -- 2.7.4