Mercurial > mplayer.hg
comparison libvo/vo_vdpau.c @ 29735:8adf928e517a
Try to recover from VDPAU display pre-emptions.
Original patch by Uoti.
author | cehoyos |
---|---|
date | Sat, 17 Oct 2009 15:15:07 +0000 |
parents | 42abcc270fb6 |
children | 593354e0500d |
comparison
equal
deleted
inserted
replaced
29734:54145563612e | 29735:8adf928e517a |
---|---|
140 static VdpDecoderCreate *vdp_decoder_create; | 140 static VdpDecoderCreate *vdp_decoder_create; |
141 static VdpDecoderDestroy *vdp_decoder_destroy; | 141 static VdpDecoderDestroy *vdp_decoder_destroy; |
142 static VdpDecoderRender *vdp_decoder_render; | 142 static VdpDecoderRender *vdp_decoder_render; |
143 | 143 |
144 static VdpGenerateCSCMatrix *vdp_generate_csc_matrix; | 144 static VdpGenerateCSCMatrix *vdp_generate_csc_matrix; |
145 static VdpPreemptionCallbackRegister *vdp_preemption_callback_register; | |
145 | 146 |
146 static void *vdpau_lib_handle; | 147 static void *vdpau_lib_handle; |
147 /* output_surfaces[NUM_OUTPUT_SURFACES] is misused for OSD. */ | 148 /* output_surfaces[NUM_OUTPUT_SURFACES] is misused for OSD. */ |
148 #define osd_surface output_surfaces[NUM_OUTPUT_SURFACES] | 149 #define osd_surface output_surfaces[NUM_OUTPUT_SURFACES] |
149 static VdpOutputSurface output_surfaces[NUM_OUTPUT_SURFACES + 1]; | 150 static VdpOutputSurface output_surfaces[NUM_OUTPUT_SURFACES + 1]; |
175 static int vid_surface_num; | 176 static int vid_surface_num; |
176 static uint32_t vid_width, vid_height; | 177 static uint32_t vid_width, vid_height; |
177 static uint32_t image_format; | 178 static uint32_t image_format; |
178 static VdpChromaType vdp_chroma_type; | 179 static VdpChromaType vdp_chroma_type; |
179 static VdpYCbCrFormat vdp_pixel_format; | 180 static VdpYCbCrFormat vdp_pixel_format; |
181 | |
182 static volatile int is_preempted; | |
180 | 183 |
181 /* draw_osd */ | 184 /* draw_osd */ |
182 static unsigned char *index_data; | 185 static unsigned char *index_data; |
183 static int index_data_size; | 186 static int index_data_size; |
184 static uint32_t palette[PALETTE_SIZE]; | 187 static uint32_t palette[PALETTE_SIZE]; |
307 } | 310 } |
308 } | 311 } |
309 video_to_output_surface(); | 312 video_to_output_surface(); |
310 if (visible_buf) | 313 if (visible_buf) |
311 flip_page(); | 314 flip_page(); |
315 } | |
316 | |
317 static void preemption_callback(VdpDevice device, void *context) | |
318 { | |
319 mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Display preemption detected\n"); | |
320 is_preempted = 1; | |
312 } | 321 } |
313 | 322 |
314 /* Initialize vdp_get_proc_address, called from preinit() */ | 323 /* Initialize vdp_get_proc_address, called from preinit() */ |
315 static int win_x11_init_vdpau_procs(void) | 324 static int win_x11_init_vdpau_procs(void) |
316 { | 325 { |
364 {VDP_FUNC_ID_BITMAP_SURFACE_PUT_BITS_NATIVE, | 373 {VDP_FUNC_ID_BITMAP_SURFACE_PUT_BITS_NATIVE, |
365 &vdp_bitmap_surface_putbits_native}, | 374 &vdp_bitmap_surface_putbits_native}, |
366 {VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE, | 375 {VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE, |
367 &vdp_output_surface_render_bitmap_surface}, | 376 &vdp_output_surface_render_bitmap_surface}, |
368 {VDP_FUNC_ID_GENERATE_CSC_MATRIX, &vdp_generate_csc_matrix}, | 377 {VDP_FUNC_ID_GENERATE_CSC_MATRIX, &vdp_generate_csc_matrix}, |
378 {VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER, | |
379 &vdp_preemption_callback_register}, | |
369 {0, NULL} | 380 {0, NULL} |
370 }; | 381 }; |
371 | 382 |
372 vdp_st = vdp_device_create(mDisplay, mScreen, | 383 vdp_st = vdp_device_create(mDisplay, mScreen, |
373 &vdp_device, &vdp_get_proc_address); | 384 &vdp_device, &vdp_get_proc_address); |
383 mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Error when calling vdp_get_proc_address(function id %d): %s\n", | 394 mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Error when calling vdp_get_proc_address(function id %d): %s\n", |
384 dsc->id, vdp_get_error_string ? vdp_get_error_string(vdp_st) : "?"); | 395 dsc->id, vdp_get_error_string ? vdp_get_error_string(vdp_st) : "?"); |
385 return -1; | 396 return -1; |
386 } | 397 } |
387 } | 398 } |
399 vdp_st = vdp_preemption_callback_register(vdp_device, | |
400 preemption_callback, NULL); | |
401 CHECK_ST_ERROR("Error when calling vdp_preemption_callback_register") | |
402 | |
388 return 0; | 403 return 0; |
389 } | 404 } |
390 | 405 |
391 /* Initialize vdpau_flip_queue, called from config() */ | 406 /* Initialize vdpau_flip_queue, called from config() */ |
392 static int win_x11_init_vdpau_flip_queue(void) | 407 static int win_x11_init_vdpau_flip_queue(void) |
557 } | 572 } |
558 decoder_max_refs = max_refs; | 573 decoder_max_refs = max_refs; |
559 return 1; | 574 return 1; |
560 } | 575 } |
561 | 576 |
577 static void mark_vdpau_objects_uninitialized(void) | |
578 { | |
579 int i; | |
580 | |
581 decoder = VDP_INVALID_HANDLE; | |
582 for (i = 0; i < MAX_VIDEO_SURFACES; i++) | |
583 surface_render[i].surface = VDP_INVALID_HANDLE; | |
584 for (i = 0; i < 3; i++) { | |
585 deint_surfaces[i] = VDP_INVALID_HANDLE; | |
586 if (i < 2 && deint_mpi[i]) | |
587 deint_mpi[i]->usage_count--; | |
588 deint_mpi[i] = NULL; | |
589 } | |
590 video_mixer = VDP_INVALID_HANDLE; | |
591 vdp_flip_queue = VDP_INVALID_HANDLE; | |
592 vdp_flip_target = VDP_INVALID_HANDLE; | |
593 for (i = 0; i <= NUM_OUTPUT_SURFACES; i++) | |
594 output_surfaces[i] = VDP_INVALID_HANDLE; | |
595 vdp_device = VDP_INVALID_HANDLE; | |
596 for (i = 0; i < eosd_surface_count; i++) | |
597 eosd_surfaces[i].surface = VDP_INVALID_HANDLE; | |
598 output_surface_width = output_surface_height = -1; | |
599 eosd_render_count = 0; | |
600 visible_buf = 0; | |
601 } | |
602 | |
603 static int handle_preemption(void) | |
604 { | |
605 if (!is_preempted) | |
606 return 0; | |
607 is_preempted = 0; | |
608 mp_msg(MSGT_VO, MSGL_INFO, "[vdpau] Attempting to recover from preemption.\n"); | |
609 mark_vdpau_objects_uninitialized(); | |
610 if (win_x11_init_vdpau_procs() < 0 || | |
611 win_x11_init_vdpau_flip_queue() < 0 || | |
612 create_vdp_mixer(vdp_chroma_type) < 0) { | |
613 mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Recovering from preemption failed\n"); | |
614 is_preempted = 1; | |
615 return -1; | |
616 } | |
617 resize(); | |
618 mp_msg(MSGT_VO, MSGL_INFO, "[vdpau] Recovered from display preemption.\n"); | |
619 return 1; | |
620 } | |
621 | |
562 /* | 622 /* |
563 * connect to X server, create and map window, initialize all | 623 * connect to X server, create and map window, initialize all |
564 * VDPAU objects, create different surfaces etc. | 624 * VDPAU objects, create different surfaces etc. |
565 */ | 625 */ |
566 static int config(uint32_t width, uint32_t height, uint32_t d_width, | 626 static int config(uint32_t width, uint32_t height, uint32_t d_width, |
662 } | 722 } |
663 | 723 |
664 static void check_events(void) | 724 static void check_events(void) |
665 { | 725 { |
666 int e = vo_x11_check_events(mDisplay); | 726 int e = vo_x11_check_events(mDisplay); |
727 | |
728 if (handle_preemption() < 0) | |
729 return; | |
667 | 730 |
668 if (e & VO_EVENT_RESIZE) | 731 if (e & VO_EVENT_RESIZE) |
669 resize(); | 732 resize(); |
670 | 733 |
671 if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && int_pause) { | 734 if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && int_pause) { |
862 | 925 |
863 static void draw_osd(void) | 926 static void draw_osd(void) |
864 { | 927 { |
865 mp_msg(MSGT_VO, MSGL_DBG2, "DRAW_OSD\n"); | 928 mp_msg(MSGT_VO, MSGL_DBG2, "DRAW_OSD\n"); |
866 | 929 |
930 if (handle_preemption() < 0) | |
931 return; | |
932 | |
867 vo_draw_text_ext(vo_dwidth, vo_dheight, border_x, border_y, border_x, border_y, | 933 vo_draw_text_ext(vo_dwidth, vo_dheight, border_x, border_y, border_x, border_y, |
868 vid_width, vid_height, draw_osd_I8A8); | 934 vid_width, vid_height, draw_osd_I8A8); |
869 } | 935 } |
870 | 936 |
871 static void flip_page(void) | 937 static void flip_page(void) |
872 { | 938 { |
873 VdpStatus vdp_st; | 939 VdpStatus vdp_st; |
874 mp_msg(MSGT_VO, MSGL_DBG2, "\nFLIP_PAGE VID:%u -> OUT:%u\n", | 940 mp_msg(MSGT_VO, MSGL_DBG2, "\nFLIP_PAGE VID:%u -> OUT:%u\n", |
875 surface_render[vid_surface_num].surface, output_surfaces[surface_num]); | 941 surface_render[vid_surface_num].surface, output_surfaces[surface_num]); |
942 | |
943 if (handle_preemption() < 0) | |
944 return; | |
876 | 945 |
877 vdp_st = vdp_presentation_queue_display(vdp_flip_queue, output_surfaces[surface_num], | 946 vdp_st = vdp_presentation_queue_display(vdp_flip_queue, output_surfaces[surface_num], |
878 vo_dwidth, vo_dheight, | 947 vo_dwidth, vo_dheight, |
879 0); | 948 0); |
880 CHECK_ST_WARNING("Error when calling vdp_presentation_queue_display") | 949 CHECK_ST_WARNING("Error when calling vdp_presentation_queue_display") |
887 int x, int y) | 956 int x, int y) |
888 { | 957 { |
889 VdpStatus vdp_st; | 958 VdpStatus vdp_st; |
890 struct vdpau_render_state *rndr = (struct vdpau_render_state *)image[0]; | 959 struct vdpau_render_state *rndr = (struct vdpau_render_state *)image[0]; |
891 int max_refs = image_format == IMGFMT_VDPAU_H264 ? rndr->info.h264.num_ref_frames : 2; | 960 int max_refs = image_format == IMGFMT_VDPAU_H264 ? rndr->info.h264.num_ref_frames : 2; |
961 | |
962 if (handle_preemption() < 0) | |
963 return VO_TRUE; | |
964 | |
892 if (!IMGFMT_IS_VDPAU(image_format)) | 965 if (!IMGFMT_IS_VDPAU(image_format)) |
893 return VO_FALSE; | 966 return VO_FALSE; |
894 if ((decoder == VDP_INVALID_HANDLE || decoder_max_refs < max_refs) | 967 if ((decoder == VDP_INVALID_HANDLE || decoder_max_refs < max_refs) |
895 && !create_vdp_decoder(max_refs)) | 968 && !create_vdp_decoder(max_refs)) |
896 return VO_FALSE; | 969 return VO_FALSE; |
1201 return update_csc_matrix(); | 1274 return update_csc_matrix(); |
1202 } | 1275 } |
1203 | 1276 |
1204 static int control(uint32_t request, void *data, ...) | 1277 static int control(uint32_t request, void *data, ...) |
1205 { | 1278 { |
1279 if (handle_preemption() < 0) | |
1280 return VO_FALSE; | |
1281 | |
1206 switch (request) { | 1282 switch (request) { |
1207 case VOCTRL_GET_DEINTERLACE: | 1283 case VOCTRL_GET_DEINTERLACE: |
1208 *(int*)data = deint; | 1284 *(int*)data = deint; |
1209 return VO_TRUE; | 1285 return VO_TRUE; |
1210 case VOCTRL_SET_DEINTERLACE: | 1286 case VOCTRL_SET_DEINTERLACE: |