+static void AspectRatio ( int, int *, int * );
+static int BinaryLog ( uint32_t );
+static void MaskToShift ( int *, int *, uint32_t );
+
+/* Object variables callbacks */
+static int DeinterlaceCallback( vlc_object_t *, char const *,
+ vlc_value_t, vlc_value_t, void * );
+static int FilterCallback( vlc_object_t *, char const *,
+ vlc_value_t, vlc_value_t, void * );
+static int VideoFilter2Callback( vlc_object_t *, char const *,
+ vlc_value_t, vlc_value_t, void * );
+
+/* From vout_intf.c */
+int vout_Snapshot( vout_thread_t *, picture_t * );
+
+/* Video filter2 parsing */
+static int ParseVideoFilter2Chain( vout_thread_t *, char * );
+static void RemoveVideoFilters2( vout_thread_t *p_vout );
+
+/* Display media title in OSD */
+static void DisplayTitleOnOSD( vout_thread_t *p_vout );
+
+/*****************************************************************************
+ * Video Filter2 functions
+ *****************************************************************************/
+struct filter_owner_sys_t
+{
+ vout_thread_t *p_vout;
+};
+
+static picture_t *video_new_buffer_filter( filter_t *p_filter )
+{
+ picture_t *p_picture;
+ vout_thread_t *p_vout = p_filter->p_owner->p_vout;
+
+ p_picture = vout_CreatePicture( p_vout, 0, 0, 0 );
+
+ return p_picture;
+}
+
+static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
+{
+ vout_DestroyPicture( p_filter->p_owner->p_vout, p_pic );
+}
+
+/*****************************************************************************
+ * vout_Request: find a video output thread, create one, or destroy one.
+ *****************************************************************************
+ * This function looks for a video output thread matching the current
+ * properties. If not found, it spawns a new one.
+ *****************************************************************************/
+vout_thread_t *__vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout,
+ video_format_t *p_fmt )
+{
+ if( !p_fmt )
+ {
+ /* Reattach video output to playlist before bailing out */
+ if( p_vout )
+ {
+ playlist_t *p_playlist = pl_Yield( p_this );
+ spu_Attach( p_vout->p_spu, p_this, VLC_FALSE );
+ vlc_object_detach( p_vout );
+ vlc_object_attach( p_vout, p_playlist );
+ pl_Release( p_this );
+ }
+ return NULL;
+ }
+
+ /* If a video output was provided, lock it, otherwise look for one. */
+ if( p_vout )
+ {
+ vlc_object_yield( p_vout );
+ }
+ else
+ {
+ p_vout = vlc_object_find( p_this, VLC_OBJECT_VOUT, FIND_CHILD );
+
+ if( !p_vout )
+ {
+ playlist_t *p_playlist = pl_Yield( p_this );
+ vlc_mutex_lock( &p_playlist->gc_lock );
+ p_vout = vlc_object_find( p_playlist,
+ VLC_OBJECT_VOUT, FIND_CHILD );
+ /* only first children of p_input for unused vout */
+ if( p_vout && p_vout->p_parent != (vlc_object_t *)p_playlist )
+ {
+ vlc_object_release( p_vout );
+ p_vout = NULL;
+ }
+ if( p_vout )
+ vlc_object_detach( p_vout ); /* Remove it from the GC */
+ vlc_mutex_unlock( &p_playlist->gc_lock );
+ pl_Release( p_this );
+ }
+ }
+
+ /* If we now have a video output, check it has the right properties */
+ if( p_vout )
+ {
+ char *psz_filter_chain;
+ vlc_value_t val;
+
+ /* We don't directly check for the "vout-filter" variable for obvious
+ * performance reasons. */
+ if( p_vout->b_filter_change )
+ {
+ var_Get( p_vout, "vout-filter", &val );
+ psz_filter_chain = val.psz_string;
+
+ if( psz_filter_chain && !*psz_filter_chain )
+ {
+ free( psz_filter_chain );
+ psz_filter_chain = NULL;
+ }
+ if( p_vout->psz_filter_chain && !*p_vout->psz_filter_chain )
+ {
+ free( p_vout->psz_filter_chain );
+ p_vout->psz_filter_chain = NULL;
+ }
+
+ if( !psz_filter_chain && !p_vout->psz_filter_chain )
+ {
+ p_vout->b_filter_change = VLC_FALSE;
+ }
+
+ if( psz_filter_chain ) free( psz_filter_chain );
+ }
+
+ if( ( p_vout->fmt_render.i_width != p_fmt->i_width ) ||
+ ( p_vout->fmt_render.i_height != p_fmt->i_height ) ||
+ ( p_vout->fmt_render.i_aspect != p_fmt->i_aspect ) ||
+ p_vout->b_filter_change )
+ {
+ /* We are not interested in this format, close this vout */
+ vlc_object_release( p_vout );
+ vout_Destroy( p_vout );
+ p_vout = NULL;
+ }
+ else
+ {
+ /* This video output is cool! Hijack it. */
+ spu_Attach( p_vout->p_spu, p_this, VLC_TRUE );
+ vlc_object_attach( p_vout, p_this );
+ if( p_vout->b_title_show )
+ DisplayTitleOnOSD( p_vout );
+ vlc_object_release( p_vout );
+ }
+ }
+
+ if( !p_vout )
+ {
+ msg_Dbg( p_this, "no usable vout present, spawning one" );
+
+ p_vout = vout_Create( p_this, p_fmt );
+ }
+
+ return p_vout;
+}