/* VA-API GPE pipeline load tester * * This little application tests the stability of VPP sharpening and * libva-intel-driver GPE pipeline */ // To compile: // gcc -ggdb -Wall -lX11 -lva -lva-x11 gpe-crash.c -o gpe-crash // To run: // ./gpe-crash #include #include #include #include #include #include #include #define ASSERT assert #define SURFACE_WIDTH 720 #define SURFACE_HEIGHT 576 #define PP_SURFACES_N 1 #define SRC_SURFACES_N 1 #define NUM_ITERATIONS 40000 VASurfaceID g_src_surfaces[SRC_SURFACES_N]; VASurfaceID g_pp_surfaces[PP_SURFACES_N]; VAConfigID g_vpp_ctx; void vpp_setup(VADisplay va_dpy) { int i, imageformat_n, entrypoint_n; VAStatus va_status; VAImage image[1]; VAImageFormat image_formats[vaMaxNumImageFormats(va_dpy)]; VAImageFormat * image_format = NULL; uint8_t * image_data; VAEntrypoint entrypoints[vaMaxNumEntrypoints(va_dpy)]; VAEntrypoint vpp_entrypoint = VA_INVALID_ID; VAConfigID vpp_config = VA_INVALID_ID; /* Source/Result surfaces */ va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, 720, 576, g_src_surfaces, SRC_SURFACES_N, NULL, 0); ASSERT( VA_STATUS_SUCCESS == va_status ); va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, 720, 576, g_pp_surfaces, PP_SURFACES_N, NULL, 0); ASSERT( VA_STATUS_SUCCESS == va_status ); /* Initialize VPP */ va_status = vaQueryConfigEntrypoints(va_dpy, VAProfileNone, entrypoints, &entrypoint_n); ASSERT( VA_STATUS_SUCCESS == va_status ); for (i = 0; i < entrypoint_n; ++i) { if (entrypoints[i] == VAEntrypointVideoProc) { vpp_entrypoint = entrypoints[i]; break; } } ASSERT( vpp_entrypoint != VA_INVALID_ID ); /* entrypoint was found? */ va_status = vaCreateConfig(va_dpy, VAProfileNone, vpp_entrypoint, NULL, 0, &vpp_config); ASSERT( VA_STATUS_SUCCESS == va_status ); va_status = vaCreateContext(va_dpy, vpp_config, SURFACE_WIDTH, SURFACE_HEIGHT, VA_PROGRESSIVE, g_pp_surfaces, PP_SURFACES_N, &g_vpp_ctx); ASSERT( VA_STATUS_SUCCESS == va_status ); /* Create simple image to fill source surface */ va_status = vaQueryImageFormats(va_dpy, image_formats, &imageformat_n); ASSERT( VA_STATUS_SUCCESS == va_status ); for (i = 0; i < imageformat_n; ++i) { if (image_formats[i].fourcc == VA_FOURCC_NV12) { image_format = &image_formats[i]; break; } } ASSERT( image_format ); /* suitable imageformat was found? */ va_status = vaCreateImage(va_dpy, image_format, SURFACE_WIDTH, SURFACE_HEIGHT, image); ASSERT( VA_STATUS_SUCCESS == va_status ); va_status = vaMapBuffer(va_dpy, image->buf, (void**)&image_data); ASSERT( VA_STATUS_SUCCESS == va_status ); for (i = 0; i < image->data_size; ++i) { if (i < image->offsets[1]) image_data[i] = 0x00; /* Y */ else if (i %2 == 0) image_data[i] = 0x80; /* U */ else image_data[i] = 0xFF; /* V */ } va_status = vaUnmapBuffer(va_dpy, image->buf); ASSERT( VA_STATUS_SUCCESS == va_status ); va_status = vaPutImage(va_dpy, g_src_surfaces[0], image->image_id, 0, 0, SURFACE_WIDTH, SURFACE_HEIGHT, 0, 0, SURFACE_WIDTH, SURFACE_HEIGHT); ASSERT( VA_STATUS_SUCCESS == va_status ); } void gpe_loop(VADisplay va_dpy) { int i; VAStatus va_status; VAProcFilterParameterBuffer param_buf; VABufferID sharpen_buf_id[1], gpe_pipeline_buf[1]; VAProcPipelineParameterBuffer pipeline_param; memset(&pipeline_param, '\0', sizeof(VAProcPipelineParameterBuffer)); vpp_setup(va_dpy); param_buf.type = VAProcFilterSharpening; param_buf.value = 0.3; /* Use some value for sharpening */ va_status = vaCreateBuffer(va_dpy, g_vpp_ctx, VAProcFilterParameterBufferType, sizeof(param_buf), 1, ¶m_buf, sharpen_buf_id); pipeline_param.surface = g_src_surfaces[0]; pipeline_param.surface_region = NULL; pipeline_param.surface_color_standard = VAProcColorStandardNone; pipeline_param.output_region = NULL; pipeline_param.output_background_color = 0xff000000; pipeline_param.output_color_standard = VAProcColorStandardNone; pipeline_param.pipeline_flags = 0; pipeline_param.filter_flags = VA_FRAME_PICTURE; pipeline_param.filters = sharpen_buf_id; pipeline_param.num_filters = 1; pipeline_param.forward_references = NULL; pipeline_param.num_forward_references = 0; pipeline_param.backward_references = NULL; pipeline_param.num_backward_references = 0; i = 0; while(i < NUM_ITERATIONS) { va_status = vaCreateBuffer(va_dpy, g_vpp_ctx, VAProcPipelineParameterBufferType, sizeof(VAProcPipelineParameterBuffer), 1, &pipeline_param, gpe_pipeline_buf); ASSERT( VA_STATUS_SUCCESS == va_status ); vaSyncSurface(va_dpy, g_src_surfaces[0]); ASSERT( VA_STATUS_SUCCESS == va_status ); va_status = vaBeginPicture(va_dpy, g_vpp_ctx, g_pp_surfaces[0]); ASSERT( VA_STATUS_SUCCESS == va_status ); va_status = vaRenderPicture(va_dpy, g_vpp_ctx, gpe_pipeline_buf, 1); ASSERT( VA_STATUS_SUCCESS == va_status ); va_status = vaEndPicture(va_dpy, g_vpp_ctx); ASSERT( VA_STATUS_SUCCESS == va_status ); va_status = vaSyncSurface(va_dpy, g_pp_surfaces[0]); ASSERT( VA_STATUS_SUCCESS == va_status ); usleep(2 * 1000); printf("gpe_loop iteration: %d (%d%%)\r", i, i * 100 / NUM_ITERATIONS); ++i; } printf("\n"); printf("success!\n"); } int main(void) { Display *dpy; VADisplay va_dpy; VAStatus va_status; int major_version, minor_version; dpy = XOpenDisplay(NULL); ASSERT( dpy ); va_dpy = vaGetDisplay(dpy); ASSERT( va_dpy ); va_status = vaInitialize(va_dpy, &major_version, &minor_version); ASSERT( VA_STATUS_SUCCESS == va_status ); printf("vaInitialize: major = %d minor = %d\n", major_version, minor_version); /* Setup surfaces and VPP for GPE postprocessing (sharpening) */ vpp_setup(va_dpy); /* Run GPP in a loop */ gpe_loop(va_dpy); return 0; }