[vlc-commits] transcode: replace PICTURE_RING_BUFFER with picture_fifo_t

Jean-Paul Saman git at videolan.org
Wed May 2 10:39:15 CEST 2012


vlc | branch: master | Jean-Paul Saman <jean-paul.saman at m2x.nl> | Tue Mar 27 10:16:15 2012 +0200| [0cdf8d8673bea62dd68937ec8037b860cac8ea66] | committer: Jean-Paul Saman

transcode: replace PICTURE_RING_BUFFER with picture_fifo_t

The PICTURE_RING_BUFFER used a fixed size, which when running out of available pictures
produces visible artefacts in the encoded stream. Allocating a new picture and keeping
track of them in a fifo is much simpler (in the multiple threads encoding scenario) and
solves the ring buffer overrun.

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

 modules/stream_out/transcode/transcode.h |    7 +---
 modules/stream_out/transcode/video.c     |   54 ++++++++++--------------------
 2 files changed, 20 insertions(+), 41 deletions(-)

diff --git a/modules/stream_out/transcode/transcode.h b/modules/stream_out/transcode/transcode.h
index 816413a..5db1e13 100644
--- a/modules/stream_out/transcode/transcode.h
+++ b/modules/stream_out/transcode/transcode.h
@@ -9,9 +9,7 @@
 #include <vlc_es.h>
 #include <vlc_codec.h>
 
-
-#define PICTURE_RING_SIZE 64
-#define SUBPICTURE_RING_SIZE 20
+#include <vlc_picture_fifo.h>
 
 #define MASTER_SYNC_MAX_DRIFT 100000
 
@@ -22,8 +20,7 @@ struct sout_stream_sys_t
     vlc_mutex_t     lock_out;
     vlc_cond_t      cond;
     bool            b_abort;
-    picture_t *     pp_pics[PICTURE_RING_SIZE];
-    int             i_first_pic, i_last_pic;
+    picture_fifo_t *pp_pics;
     vlc_thread_t    thread;
 
     /* Audio */
diff --git a/modules/stream_out/transcode/video.c b/modules/stream_out/transcode/video.c
index ed9138c..97f88ea 100644
--- a/modules/stream_out/transcode/video.c
+++ b/modules/stream_out/transcode/video.c
@@ -62,23 +62,6 @@ static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
 
 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
 {
-    sout_stream_sys_t *p_ssys = p_dec->p_owner->p_sys;
-    if( p_ssys->i_threads >= 1 )
-    {
-        int i_first_pic = p_ssys->i_first_pic;
-
-        if( p_ssys->i_first_pic != p_ssys->i_last_pic )
-        {
-            /* Encoder still has stuff to encode, wait to clear-up the list */
-            while( p_ssys->i_first_pic == i_first_pic )
-            {
-#warning THERE IS DEFINITELY A BUG! LOCKING IS INSUFFICIENT!
-                msleep( 10000 );
-                barrier ();
-            }
-        }
-    }
-
     p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
     return picture_NewFromFormat( &p_dec->fmt_out.video );
 }
@@ -120,7 +103,8 @@ static void* EncoderThread( void *obj )
         block_t *p_block;
 
         vlc_mutex_lock( &p_sys->lock_out );
-        while( !p_sys->b_abort && p_sys->i_last_pic == p_sys->i_first_pic )
+        while( !p_sys->b_abort &&
+               (p_pic = picture_fifo_Pop( p_sys->pp_pics )) == NULL )
             vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
 
         if( p_sys->b_abort )
@@ -128,9 +112,6 @@ static void* EncoderThread( void *obj )
             vlc_mutex_unlock( &p_sys->lock_out );
             break;
         }
-
-        p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
-        p_sys->i_first_pic %= PICTURE_RING_SIZE;
         vlc_mutex_unlock( &p_sys->lock_out );
 
         p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
@@ -142,12 +123,6 @@ static void* EncoderThread( void *obj )
         picture_Release( p_pic );
     }
 
-    while( p_sys->i_last_pic != p_sys->i_first_pic )
-    {
-        p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
-        p_sys->i_first_pic %= PICTURE_RING_SIZE;
-        picture_Release( p_pic );
-    }
     block_ChainRelease( p_sys->p_buffers );
 
     vlc_restorecancel (canc);
@@ -249,16 +224,22 @@ int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
         p_sys->id_video = id;
         vlc_mutex_init( &p_sys->lock_out );
         vlc_cond_init( &p_sys->cond );
-        memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
-        p_sys->i_first_pic = 0;
-        p_sys->i_last_pic = 0;
+        p_sys->pp_pics = picture_fifo_New();
+        if( p_sys->pp_pics == NULL )
+        {
+            msg_Err( p_stream, "cannot create picture fifo" );
+            module_unneed( id->p_decoder, id->p_decoder->p_module );
+            id->p_decoder->p_module = NULL;
+            free( id->p_decoder->p_owner );
+            return VLC_ENOMEM;
+        }
         p_sys->p_buffers = NULL;
-        p_sys->b_abort = 0;
+        p_sys->b_abort = false;
         if( vlc_clone( &p_sys->thread, EncoderThread, p_sys, i_priority ) )
         {
             msg_Err( p_stream, "cannot spawn encoder thread" );
             module_unneed( id->p_decoder, id->p_decoder->p_module );
-            id->p_decoder->p_module = 0;
+            id->p_decoder->p_module = NULL;
             free( id->p_decoder->p_owner );
             return VLC_EGENERIC;
         }
@@ -550,6 +531,9 @@ void transcode_video_close( sout_stream_t *p_stream,
         vlc_join( p_stream->p_sys->thread, NULL );
         vlc_mutex_destroy( &p_stream->p_sys->lock_out );
         vlc_cond_destroy( &p_stream->p_sys->cond );
+
+        picture_fifo_Delete( p_stream->p_sys->pp_pics );
+        p_stream->p_sys->pp_pics = NULL;
     }
 
     /* Close decoder */
@@ -768,14 +752,12 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_t *id,
         else
         {
             vlc_mutex_lock( &p_sys->lock_out );
-            p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
-            p_sys->i_last_pic %= PICTURE_RING_SIZE;
+            picture_fifo_Push( p_sys->pp_pics, p_pic );
             *out = p_sys->p_buffers;
             p_sys->p_buffers = NULL;
             if( p_pic2 != NULL )
             {
-                p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
-                p_sys->i_last_pic %= PICTURE_RING_SIZE;
+                picture_fifo_Push( p_sys->pp_pics, p_pic2 );
             }
             vlc_cond_signal( &p_sys->cond );
             vlc_mutex_unlock( &p_sys->lock_out );



More information about the vlc-commits mailing list