[vlc-devel] commit: Fixed completely broken video filter 2 chain in vout. Now they have a (Laurent Aimar )

git version control git at videolan.org
Thu Jul 24 20:01:22 CEST 2008


vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Thu Jul 24 19:58:05 2008 +0200| [6d937c8f88c36262433d5060a82f9cd3d5c69786]

Fixed completely broken video filter 2 chain in vout. Now they have a
chance to get a frame when they ask (close #1738).

Decoders and filters share the same pool of video frames. But the
decoders try to decode as fast as possible, using all buffers. Then it
s pure luck if the filter can grab a frame...

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6d937c8f88c36262433d5060a82f9cd3d5c69786
---

 include/vlc_vout.h               |    5 +++++
 src/input/decoder.c              |   20 +++++++++++++++++---
 src/misc/filter_chain.c          |    1 -
 src/video_output/vout_pictures.c |   29 +++++++++++++++++++++++++++++
 4 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/include/vlc_vout.h b/include/vlc_vout.h
index 635434f..420ad51 100644
--- a/include/vlc_vout.h
+++ b/include/vlc_vout.h
@@ -660,9 +660,14 @@ VLC_EXPORT( void,            vout_DatePicture,    ( vout_thread_t *, picture_t *
 VLC_EXPORT( void,            vout_LinkPicture,    ( vout_thread_t *, picture_t * ) );
 VLC_EXPORT( void,            vout_UnlinkPicture,  ( vout_thread_t *, picture_t * ) );
 VLC_EXPORT( void,            vout_PlacePicture,   ( vout_thread_t *, unsigned int, unsigned int, unsigned int *, unsigned int *, unsigned int *, unsigned int * ) );
+
+/* DO NOT use vout_RenderPicture unless you are in src/video_ouput */
 picture_t *     vout_RenderPicture  ( vout_thread_t *, picture_t *,
                                                        subpicture_t * );
 
+/* DO NOT use vout_CountPictureAvailable unless your are in src/input/dec.c (no exception) */
+int vout_CountPictureAvailable( vout_thread_t * );
+
 VLC_EXPORT( int, vout_vaControlDefault, ( vout_thread_t *, int, va_list ) );
 VLC_EXPORT( void *, vout_RequestWindow, ( vout_thread_t *, int *, int *, unsigned int *, unsigned int * ) );
 VLC_EXPORT( void,   vout_ReleaseWindow, ( vout_thread_t *, void * ) );
diff --git a/src/input/decoder.c b/src/input/decoder.c
index b4beedd..d0fdd14 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -1235,6 +1235,9 @@ static void aout_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
                           p_dec->p_owner->p_aout_input, p_buffer );
 }
 
+
+int vout_CountPictureAvailable( vout_thread_t *p_vout );
+
 static picture_t *vout_new_buffer( decoder_t *p_dec )
 {
     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
@@ -1317,14 +1320,25 @@ static picture_t *vout_new_buffer( decoder_t *p_dec )
             p_sys->p_vout->render.i_bmask = p_sys->video.i_bmask;
     }
 
-    /* Get a new picture */
-    while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
+    /* Get a new picture
+     */
+    for( p_pic = NULL; ; )
     {
         int i_pic, i_ready_pic = 0;
 
         if( p_dec->b_die || p_dec->b_error )
-        {
             return NULL;
+
+        /* The video filter chain required that there is always 1 free buffer
+         * that it will use as temporary one. It will release the temporary
+         * buffer once its work is done, so this check is safe even if we don't
+         * lock around both count() and create().
+         */
+        if( vout_CountPictureAvailable( p_sys->p_vout ) >= 2 )
+        {
+            p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 );
+            if( p_pic )
+                break;
         }
 
 #define p_pic p_dec->p_owner->p_vout->render.pp_picture[i_pic]
diff --git a/src/misc/filter_chain.c b/src/misc/filter_chain.c
index 2bf2414..5397b06 100644
--- a/src/misc/filter_chain.c
+++ b/src/misc/filter_chain.c
@@ -353,7 +353,6 @@ picture_t *filter_chain_VideoFilter( filter_chain_t *p_chain, picture_t *p_pic )
         if( p_chain->p_this->i_object_type == VLC_OBJECT_VOUT )
         {
             vout_thread_t *p_vout = (vout_thread_t*)p_chain->p_this;
-
             vlc_mutex_lock( &p_vout->picture_lock );
             if( p_pic->i_refcount )
             {
diff --git a/src/video_output/vout_pictures.c b/src/video_output/vout_pictures.c
index e19d9b6..2e98fc4 100644
--- a/src/video_output/vout_pictures.c
+++ b/src/video_output/vout_pictures.c
@@ -106,6 +106,35 @@ void vout_DatePicture( vout_thread_t *p_vout,
  * It needs locking since several pictures can be created by several producers
  * threads.
  */
+int vout_CountPictureAvailable( vout_thread_t *p_vout )
+{
+    int i_free = 0;
+    int i_pic;
+
+    vlc_mutex_lock( &p_vout->picture_lock );
+    for( i_pic = 0; i_pic < I_RENDERPICTURES; i_pic++ )
+    {
+        picture_t *p_pic = PP_RENDERPICTURE[(p_vout->render.i_last_used_pic + i_pic + 1) % I_RENDERPICTURES];
+
+        switch( p_pic->i_status )
+        {
+            case DESTROYED_PICTURE:
+                i_free++;
+                break;
+
+            case FREE_PICTURE:
+                i_free++;
+                break;
+
+            default:
+                break;
+        }
+    }
+    vlc_mutex_unlock( &p_vout->picture_lock );
+
+    return i_free;
+}
+
 picture_t *vout_CreatePicture( vout_thread_t *p_vout,
                                bool b_progressive,
                                bool b_top_field_first,




More information about the vlc-devel mailing list