void *thread_1_func(void *p) { (void)p; // unused VdpPresentationQueueTarget pq_target; VdpPresentationQueue pq; VdpOutputSurface out_surface; VdpOutputSurface out_surface_2; VdpBitmapSurface bmp_surface; ASSERT_OK(vdpPresentationQueueTargetCreateX11(device, window, &pq_target)); ASSERT_OK(vdpPresentationQueueCreate(device, pq_target, &pq)); ASSERT_OK(vdpOutputSurfaceCreate(device, VDP_RGBA_FORMAT_B8G8R8A8, 300, 150, &out_surface)); ASSERT_OK(vdpOutputSurfaceCreate(device, VDP_RGBA_FORMAT_B8G8R8A8, 300, 150, &out_surface_2)); ASSERT_OK(vdpBitmapSurfaceCreate(device, VDP_RGBA_FORMAT_B8G8R8A8, 300, 150, 1, &bmp_surface)); uint32_t buf[300*150]; for (uint32_t k = 0; k < 300*150; k ++) buf[k] = 0xff000000u + (k & 0xffffffu); const void * const source_data[] = { buf }; uint32_t source_pitches[] = { 4 * 300 }; ASSERT_OK(vdpBitmapSurfacePutBitsNative(bmp_surface, source_data, source_pitches, NULL)); VdpTime vdpTime = 0; ASSERT_OK(vdpPresentationQueueBlockUntilSurfaceIdle(pq, out_surface, &vdpTime)); ASSERT_OK(vdpPresentationQueueGetTime(pq, &vdpTime)); VdpOutputSurfaceRenderBlendState blend_state = { .blend_factor_source_color=VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE, .blend_factor_destination_color=VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO, .blend_factor_source_alpha=VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE, .blend_factor_destination_alpha=VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO, .blend_equation_color=VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, .blend_equation_alpha=VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, .blend_constant = { 0, 0, 0, 0} }; VdpRect source_rect = {0, 0, 300, 150}; VdpRect destination_rect = {0, 0, 300, 150}; ASSERT_OK(vdpOutputSurfaceRenderBitmapSurface(out_surface, &destination_rect, bmp_surface, &source_rect, NULL, &blend_state, VDP_OUTPUT_SURFACE_RENDER_ROTATE_0)); ASSERT_OK(vdpPresentationQueueDisplay(pq, out_surface, 0, 0, 0)); ASSERT_OK(vdpOutputSurfaceDestroy(out_surface)); ASSERT_OK(vdpOutputSurfaceDestroy(out_surface_2)); ASSERT_OK(vdpPresentationQueueDestroy(pq)); ASSERT_OK(vdpPresentationQueueTargetDestroy(pq_target)); ASSERT_OK(vdpBitmapSurfaceDestroy(bmp_surface)); return NULL; }
int main(void) { VdpDevice device; Display *dpy = get_dpy(); ASSERT_OK(vdpDeviceCreateX11(dpy, 0, &device, NULL)); VdpOutputSurface out_surface_1; VdpOutputSurface out_surface_2; ASSERT_OK(vdpOutputSurfaceCreate(device, VDP_RGBA_FORMAT_B8G8R8A8, 4, 4, &out_surface_1)); ASSERT_OK(vdpOutputSurfaceCreate(device, VDP_RGBA_FORMAT_B8G8R8A8, 4, 4, &out_surface_2)); uint32_t black_box[] = { 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000 }; uint32_t two_red_dots[] = { 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffff0000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffff0000 }; const void * const source_data_1[] = {black_box}; const void * const source_data_2[] = {two_red_dots}; uint32_t source_pitches[] = { 4 * 4 }; // upload data ASSERT_OK(vdpOutputSurfacePutBitsNative(out_surface_1, source_data_1, source_pitches, NULL)); ASSERT_OK(vdpOutputSurfacePutBitsNative(out_surface_2, source_data_2, source_pitches, NULL)); // render VdpOutputSurfaceRenderBlendState blend_state = { .struct_version = VDP_OUTPUT_SURFACE_RENDER_BLEND_STATE_VERSION, .blend_factor_source_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE, .blend_factor_source_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE, .blend_factor_destination_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO, .blend_factor_destination_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO, .blend_equation_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, .blend_equation_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, .blend_constant = {0, 0, 0, 0} }; ASSERT_OK(vdpOutputSurfaceRenderOutputSurface(out_surface_1, NULL, out_surface_2, NULL, NULL, &blend_state, VDP_OUTPUT_SURFACE_RENDER_ROTATE_0)); // get data back uint32_t receive_buf[16]; void * const dest_data[] = {receive_buf}; ASSERT_OK(vdpOutputSurfaceGetBitsNative(out_surface_1, NULL, dest_data, source_pitches)); printf("output surface\n"); for (int k = 0; k < 16; k ++) { printf("%x ", receive_buf[k]); if (3 == k % 4) printf("\n"); } printf("----------\n"); for (int k = 0; k < 16; k ++) { printf("%x ", two_red_dots[k]); if (3 == k % 4) printf("\n"); } // compare recieve_buf with two_red_dots if (memcmp(receive_buf, two_red_dots, 4*4*4)) { printf("fail\n"); return 1; } // Check bitmap surface rendering smoothing issue VdpBitmapSurface bmp_surface; ASSERT_OK(vdpBitmapSurfaceCreate(device, VDP_RGBA_FORMAT_B8G8R8A8, 4, 4, 1, &bmp_surface)); ASSERT_OK(vdpBitmapSurfacePutBitsNative(bmp_surface, source_data_2, source_pitches, NULL)); VdpOutputSurfaceRenderBlendState blend_state_opaque_copy = { .struct_version = VDP_OUTPUT_SURFACE_RENDER_BLEND_STATE_VERSION, .blend_factor_source_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE, .blend_factor_source_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE, .blend_factor_destination_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO, .blend_factor_destination_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO, .blend_equation_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, .blend_equation_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, .blend_constant = {0, 0, 0, 0} }; ASSERT_OK(vdpOutputSurfaceRenderBitmapSurface(out_surface_1, NULL, bmp_surface, NULL, NULL, &blend_state_opaque_copy, VDP_OUTPUT_SURFACE_RENDER_ROTATE_0)); ASSERT_OK(vdpOutputSurfaceGetBitsNative(out_surface_1, NULL, dest_data, source_pitches)); printf("bitmap surface\n"); for (int k = 0; k < 16; k ++) { printf("%x ", receive_buf[k]); if (3 == k % 4) printf("\n"); } printf("----------\n"); for (int k = 0; k < 16; k ++) { printf("%x ", two_red_dots[k]); if (3 == k % 4) printf("\n"); } if (memcmp(receive_buf, two_red_dots, 4*4*4)) { printf("fail\n"); return 2; } printf("pass\n"); return 0; }
int main(int argc, char *argv[]) { const int width = 720; const int height = 480; VdpGetProcAddress *get_proc_address; VdpDevice vdp_device; VdpVideoSurface vdp_video_surface; VdpVideoMixer vdp_video_mixer; VdpOutputSurface vdp_output_surface; Display *dpy; dpy = XOpenDisplay(NULL); assert(dpy); CHECK(vdpDeviceCreateX11(dpy, 0, &vdp_device, &get_proc_address)); CHECK(vdpVideoSurfaceCreate(vdp_device, VDP_CHROMA_TYPE_420, width, height, &vdp_video_surface)); CHECK(vdpOutputSurfaceCreate(vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, width, height, &vdp_output_surface)); CHECK(vdpVideoMixerCreate(vdp_device, 0, NULL, 0, NULL, NULL, &vdp_video_mixer)); char *y_plane = malloc(width * height); char *u_plane = malloc((width/2) * (height/2)); char *v_plane = malloc((width/2) * (height/2)); const void *source_planes[4] = { y_plane, u_plane, v_plane, NULL }; uint32_t source_pitches[4] = { width, width/2, width/2, 0 }; assert(y_plane); assert(u_plane); assert(v_plane); memset(y_plane, 128, width * height); memset(u_plane, 200, (width/2) * (height/2)); memset(v_plane, 95, (width/2) * (height/2)); struct timespec t_start, t_end; int rep_count = 3000; if (argc >= 2) rep_count = atoi(argv[1]); clock_gettime(CLOCK_MONOTONIC, &t_start); for (int k = 0; k < rep_count; k ++) { CHECK(vdpVideoSurfacePutBitsYCbCr(vdp_video_surface, VDP_YCBCR_FORMAT_YV12, source_planes, source_pitches)); CHECK(vdpVideoMixerRender(vdp_video_mixer, -1, NULL, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME, 0, NULL, vdp_video_surface, 0, NULL, NULL, vdp_output_surface, NULL, NULL, 0, NULL)); } clock_gettime(CLOCK_MONOTONIC, &t_end); double duration = t_end.tv_sec - t_start.tv_sec + (t_end.tv_nsec - t_start.tv_nsec) / 1.0e9; printf("%d repetitions in %f secs, %f per sec\n", rep_count, duration, rep_count / duration); CHECK(vdpOutputSurfaceDestroy(vdp_output_surface)); CHECK(vdpVideoMixerDestroy(vdp_video_mixer)); CHECK(vdpVideoSurfaceDestroy(vdp_video_surface)); CHECK(vdpDeviceDestroy(vdp_device)); return 0; }