/* * 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 -h -n * */ #include #include #include #include #include #include #include #include #include #include #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\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; }