+/**
+ * Video filter
+ */
+static picture_t *FilterVideo( filter_t *p_filter, picture_t *p_src )
+{
+ filter_sys_t *p_sys = p_filter->p_sys;
+ logo_list_t *p_list = &p_sys->list;
+
+ picture_t *p_dst = filter_NewPicture( p_filter );
+ if( !p_dst )
+ goto exit;
+
+ picture_Copy( p_dst, p_src );
+
+ /* */
+ vlc_mutex_lock( &p_sys->lock );
+
+ logo_t *p_logo;
+ if( p_list->i_next_pic < p_src->date )
+ p_logo = LogoListNext( p_list, p_src->date );
+ else
+ p_logo = LogoListCurrent( p_list );
+
+ /* */
+ const picture_t *p_pic = p_logo->p_pic;
+ if( p_pic )
+ {
+ const video_format_t *p_fmt = &p_pic->format;
+ const int i_dst_w = p_filter->fmt_out.video.i_visible_width;
+ const int i_dst_h = p_filter->fmt_out.video.i_visible_height;
+
+ if( p_sys->i_pos )
+ {
+ if( p_sys->i_pos & SUBPICTURE_ALIGN_BOTTOM )
+ {
+ p_sys->i_pos_y = i_dst_h - p_fmt->i_visible_height;
+ }
+ else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_TOP) )
+ {
+ p_sys->i_pos_y = ( i_dst_h - p_fmt->i_visible_height ) / 2;
+ }
+ else
+ {
+ p_sys->i_pos_y = 0;
+ }
+
+ if( p_sys->i_pos & SUBPICTURE_ALIGN_RIGHT )
+ {
+ p_sys->i_pos_x = i_dst_w - p_fmt->i_visible_width;
+ }
+ else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_LEFT) )
+ {
+ p_sys->i_pos_x = ( i_dst_w - p_fmt->i_visible_width ) / 2;
+ }
+ else
+ {
+ p_sys->i_pos_x = 0;
+ }
+ }
+
+ if( p_sys->i_pos_x < 0 || p_sys->i_pos_y < 0 )
+ {
+ msg_Warn( p_filter,
+ "logo(%ix%i) doesn't fit into video(%ix%i)",
+ p_fmt->i_visible_width, p_fmt->i_visible_height,
+ i_dst_w,i_dst_h );
+ p_sys->i_pos_x = (p_sys->i_pos_x > 0) ? p_sys->i_pos_x : 0;
+ p_sys->i_pos_y = (p_sys->i_pos_y > 0) ? p_sys->i_pos_y : 0;
+ }
+
+ /* */
+ const int i_alpha = p_logo->i_alpha != -1 ? p_logo->i_alpha : p_list->i_alpha;
+ if( filter_ConfigureBlend( p_sys->p_blend, i_dst_w, i_dst_h, p_fmt ) ||
+ filter_Blend( p_sys->p_blend, p_dst, p_sys->i_pos_x, p_sys->i_pos_y,
+ p_pic, i_alpha ) )
+ {
+ msg_Err( p_filter, "failed to blend a picture" );
+ }
+ }
+ vlc_mutex_unlock( &p_sys->lock );
+
+exit:
+ picture_Release( p_src );
+ return p_dst;
+}
+
+static int Mouse( filter_t *p_filter, vlc_mouse_t *p_mouse,
+ const vlc_mouse_t *p_old, const vlc_mouse_t *p_new )
+{
+ filter_sys_t *p_sys = p_filter->p_sys;
+
+ vlc_mutex_lock( &p_sys->lock );
+ logo_t *p_logo = LogoListCurrent( &p_sys->list );
+ const picture_t *p_pic = p_logo->p_pic;
+
+ if( p_pic )
+ {
+ const video_format_t *p_fmt = &p_pic->format;
+ const int i_logo_w = p_fmt->i_visible_width;
+ const int i_logo_h = p_fmt->i_visible_height;
+
+ /* Check if we are over the logo */
+ const bool b_over = p_new->i_x >= p_sys->i_pos_x &&
+ p_new->i_x < p_sys->i_pos_x + i_logo_w &&
+ p_new->i_y >= p_sys->i_pos_y &&
+ p_new->i_y < p_sys->i_pos_y + i_logo_h;
+
+ if( b_over && vlc_mouse_HasPressed( p_old, p_new, MOUSE_BUTTON_LEFT ) )
+ p_sys->b_mouse_grab = true;
+ else if( vlc_mouse_HasReleased( p_old, p_new, MOUSE_BUTTON_LEFT ) )
+ p_sys->b_mouse_grab = false;
+
+ if( p_sys->b_mouse_grab )
+ {
+ int i_dx, i_dy;
+ vlc_mouse_GetMotion( &i_dx, &i_dy, p_old, p_new );
+ p_sys->i_pos_x = VLC_CLIP( p_sys->i_pos_x + i_dx, 0,
+ p_filter->fmt_in.video.i_width - i_logo_w );
+ p_sys->i_pos_y = VLC_CLIP( p_sys->i_pos_y + i_dy, 0,
+ p_filter->fmt_in.video.i_height - i_logo_h );
+
+ /* object under mouse has moved */
+ var_SetBool( p_filter->p_parent, "mouse-object", true );
+ }
+ else if( b_over )
+ {
+ /* object under mouse stoped moving */
+ var_SetBool( p_filter->p_parent, "mouse-object", false );
+ }
+
+ if( p_sys->b_mouse_grab || b_over )
+ {
+ vlc_mutex_unlock( &p_sys->lock );
+ return VLC_EGENERIC;
+ }
+ }
+ vlc_mutex_unlock( &p_sys->lock );
+
+ *p_mouse = *p_new;
+ return VLC_SUCCESS;
+}
+