diff options
Diffstat (limited to 'src/video_out')
-rw-r--r-- | src/video_out/video_out_vdpau.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/src/video_out/video_out_vdpau.c b/src/video_out/video_out_vdpau.c index 6b25b28c3..af7c33c3b 100644 --- a/src/video_out/video_out_vdpau.c +++ b/src/video_out/video_out_vdpau.c @@ -754,6 +754,7 @@ static vo_frame_t *vdpau_alloc_frame (vo_driver_t *this_gen) frame->vo_frame.dispose = vdpau_frame_dispose; frame->vo_frame.driver = this_gen; + frame->vdpau_accel_data.vo_frame = &frame->vo_frame; frame->vdpau_accel_data.vdp_device = vdp_device; frame->vdpau_accel_data.surface = VDP_INVALID_HANDLE; frame->vdpau_accel_data.chroma = VDP_CHROMA_TYPE_420; @@ -901,10 +902,19 @@ static void vdpau_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_ uint32_t width, uint32_t height, double ratio, int format, int flags) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; - vdpau_frame_t *frame = (vdpau_frame_t *) frame_gen; + vdpau_frame_t *frame = VDPAU_FRAME(frame_gen); VdpChromaType chroma = (flags & VO_CHROMA_422) ? VDP_CHROMA_TYPE_422 : VDP_CHROMA_TYPE_420; + vo_frame_t orig_frame_content; + if (format == XINE_IMGFMT_VDPAU) { + if (frame_gen != &frame->vo_frame) { + /* this is an intercepted frame, so we need to detect and propagate any + * changes on the original vo_frame to all the intercepted frames */ + xine_fast_memcpy(&orig_frame_content, &frame->vo_frame, sizeof (vo_frame_t)); + } + } + /* Check frame size and format and reallocate if necessary */ if ( (frame->width != width) || (frame->height != height) || (frame->format != format) || (frame->format==XINE_IMGFMT_VDPAU && frame->vdpau_accel_data.chroma!=chroma) || (frame->vdpau_accel_data.vdp_runtime_nr != this->vdp_runtime_nr)) { @@ -974,6 +984,36 @@ static void vdpau_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_ frame->vdpau_accel_data.color_standard = VDP_COLOR_STANDARD_ITUR_BT_601; frame->ratio = ratio; frame->vo_frame.future_frame = NULL; + + if (format == XINE_IMGFMT_VDPAU) { + if (frame_gen != &frame->vo_frame) { + /* this is an intercepted frame, so we need to detect and propagate any + * changes on the original vo_frame to all the intercepted frames */ + unsigned char *p0 = (unsigned char *)&orig_frame_content; + unsigned char *p1 = (unsigned char *)&frame->vo_frame; + int i; + for (i = 0; i < sizeof (vo_frame_t); i++) { + if (*p0 != *p1) { + /* propagate the change */ + vo_frame_t *f = frame_gen; + while (f->next) { + /* serveral restrictions apply when intercepting VDPAU frames. So let's check + * the intercepted frames before modifing them and fail otherwise. */ + unsigned char *p = (unsigned char *)f + i; + if (*p != *p0) { + xprintf(this->xine, XINE_VERBOSITY_DEBUG, "vdpau_update_frame_format: a post plugin violates the restrictions on intercepting VDPAU frames\n"); + _x_abort(); + } + + *p = *p1; + f = f->next; + } + } + p0++; + p1++; + } + } + } } |