From d8673e73b3a63bfca56748e02e5a889328c3e702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Thu, 26 Jul 2007 21:39:14 +0200 Subject: clip overlay against sub image when calling XvMCCompositeSubpicture() Blending functions like _x_blend_xx44() take care to clip the overlay against the destination bitmap. The same clipping must be applied to determine the relevant area in the destination bitmap for the call to XvMCCompositeSubpicture(). --- src/video_out/video_out_xxmc.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/video_out/video_out_xxmc.c b/src/video_out/video_out_xxmc.c index 1c71bb534..4b926a2f1 100644 --- a/src/video_out/video_out_xxmc.c +++ b/src/video_out/video_out_xxmc.c @@ -1500,6 +1500,7 @@ static void xxmc_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, } else if (frame->format == XINE_IMGFMT_XXMC) { if (this->ovl_changed && this->hwSubpictures) { if (this->new_subpic) { + int x0, y0, x1, y1, w, h; LOCK_AND_SURFACE_VALID( this, frame->xvmc_surf ); if (this->first_overlay) { memset(this->subImage->data,0,this->subImage->width* @@ -1510,13 +1511,29 @@ static void xxmc_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, this->subImage->height, this->subImage->width, &this->alphablend_extra_data, &this->palette, (this->subImage->id == FOURCC_IA44)); - XVMCLOCKDISPLAY( this->display ); - XvMCCompositeSubpicture( this->display, this->new_subpic, - this->subImage, - overlay->x, overlay->y,overlay->width, - overlay->height, - overlay->x, overlay->y); - XVMCUNLOCKDISPLAY( this->display ); + + /* clip overlay against sub image like in _x_blend_xx44() */ + x0 = overlay->x; + y0 = overlay->y; + x1 = x0 + overlay->width; + y1 = y0 + overlay->height; + w = this->subImage->width; + h = this->subImage->height; + + x0 = (x0 < 0) ? 0 : ((x0 > w) ? w : x0); + y0 = (y0 < 0) ? 0 : ((y0 > h) ? h : y0); + x1 = (x1 < 0) ? 0 : ((x1 > w) ? w : x1); + y1 = (y1 < 0) ? 0 : ((y1 > h) ? h : y1); + + /* anything left after clipping? */ + if (x0 != x1 && y0 != y1) { + XVMCLOCKDISPLAY( this->display ); + XvMCCompositeSubpicture( this->display, this->new_subpic, + this->subImage, + x0, y0, x1 - x0, y1 - y0, + x0, y0); + XVMCUNLOCKDISPLAY( this->display ); + } xvmc_context_reader_unlock( &this->xvmc_lock ); } } -- cgit v1.2.3 From d27eb600c51ce69d45468865f3fa3c3fd84df05c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Thu, 26 Jul 2007 23:54:24 +0200 Subject: copy stream in _x_post_frame_copy_up() and add refcounting Without copying stream up, _x_post_restore_video_frame() will reset the native frame's stream to the value at _x_post_intercept_video_frame(), which is typically NULL. This behaviour differs from normal frame processing, i. e. without postprocessing. Copying the stream up reveals that stream refcounting was missing in several postprocessing functions, which is hereby added. --HG-- extra : transplant_source : I%F1%0B%86%B5%5E%5D%10_6%BC%B6%BCPZ%11%04y%83/ --- src/xine-engine/post.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/xine-engine/post.c b/src/xine-engine/post.c index 6ae96e982..f2e14990b 100644 --- a/src/xine-engine/post.c +++ b/src/xine-engine/post.c @@ -362,6 +362,9 @@ vo_frame_t *_x_post_intercept_video_frame(vo_frame_t *frame, post_video_port_t * /* make a copy and attach the original */ xine_fast_memcpy(new_frame, frame, sizeof(vo_frame_t)); new_frame->next = frame; + + if (new_frame->stream) + _x_refcounter_inc(new_frame->stream->refcounter); /* modify the frame with the intercept functions */ new_frame->port = &port->new_port; @@ -399,6 +402,9 @@ vo_frame_t *_x_post_restore_video_frame(vo_frame_t *frame, post_video_port_t *po /* propagate any changes */ _x_post_frame_copy_down(frame, original); + if (frame->stream) + _x_refcounter_dec(frame->stream->refcounter); + /* put the now free slot into the free frames list */ pthread_mutex_lock(&port->free_frames_lock); frame->next = port->free_frame_slots; @@ -410,6 +416,11 @@ vo_frame_t *_x_post_restore_video_frame(vo_frame_t *frame, post_video_port_t *po void _x_post_frame_copy_down(vo_frame_t *from, vo_frame_t *to) { /* propagate changes downwards (from decoders to video out) */ + if (from->stream) + _x_refcounter_inc(from->stream->refcounter); + if (to->stream) + _x_refcounter_dec(to->stream->refcounter); + to->pts = from->pts; to->bad_frame = from->bad_frame; to->duration = from->duration; @@ -432,8 +443,14 @@ void _x_post_frame_copy_down(vo_frame_t *from, vo_frame_t *to) { void _x_post_frame_copy_up(vo_frame_t *to, vo_frame_t *from) { /* propagate changes upwards (from video out to decoders) */ + if (from->stream) + _x_refcounter_inc(from->stream->refcounter); + if (to->stream) + _x_refcounter_dec(to->stream->refcounter); + to->vpts = from->vpts; to->duration = from->duration; + to->stream = from->stream; if (to->extra_info != from->extra_info) _x_extra_info_merge(to->extra_info, from->extra_info); @@ -441,6 +458,11 @@ void _x_post_frame_copy_up(vo_frame_t *to, vo_frame_t *from) { void _x_post_frame_u_turn(vo_frame_t *frame, xine_stream_t *stream) { /* frame's travel will end here => do the housekeeping */ + if (stream) + _x_refcounter_inc(stream->refcounter); + if (frame->stream) + _x_refcounter_dec(frame->stream->refcounter); + frame->stream = stream; if (stream) { _x_extra_info_merge(frame->extra_info, stream->video_decoder_extra_info); -- cgit v1.2.3 From 7c671e1d523f7707ddaa1d7d7111ffca58772bf4 Mon Sep 17 00:00:00 2001 From: Kirill Belokurov Date: Fri, 27 Jul 2007 22:24:01 +0300 Subject: Fixed race, reordered broadcaster shutdown sequence to avoid multiple access to connections list --- src/xine-engine/broadcaster.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/xine-engine/broadcaster.c b/src/xine-engine/broadcaster.c index 30cdadc7c..43390ede5 100644 --- a/src/xine-engine/broadcaster.c +++ b/src/xine-engine/broadcaster.c @@ -352,6 +352,17 @@ broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port) void _x_close_broadcaster(broadcaster_t *this) { + this->running = 0; + pthread_cancel(this->manager_thread); + pthread_join(this->manager_thread,NULL); + close(this->msock); + + if (this->stream->video_fifo) + this->stream->video_fifo->unregister_put_cb(this->stream->video_fifo, video_put_cb); + + if(this->stream->audio_fifo) + this->stream->audio_fifo->unregister_put_cb(this->stream->audio_fifo, audio_put_cb); + xine_list_iterator_t ite; while ( (ite = xine_list_front(this->connections)) ) { @@ -362,18 +373,9 @@ void _x_close_broadcaster(broadcaster_t *this) xine_list_remove (this->connections, ite); } xine_list_delete(this->connections); - - this->running = 0; - close(this->msock); - pthread_mutex_lock( &this->lock ); - pthread_cancel(this->manager_thread); - pthread_join(this->manager_thread,NULL); - - this->stream->video_fifo->unregister_put_cb(this->stream->video_fifo, video_put_cb); - if(this->stream->audio_fifo) - this->stream->audio_fifo->unregister_put_cb(this->stream->audio_fifo, audio_put_cb); - + pthread_mutex_destroy( &this->lock ); + free(this); } -- cgit v1.2.3