* include/video.h, include/vlc_config.h, src/video_output/*: changed the
authorGildas Bazin <gbazin@videolan.org>
Tue, 19 Nov 2002 20:45:09 +0000 (20:45 +0000)
committerGildas Bazin <gbazin@videolan.org>
Tue, 19 Nov 2002 20:45:09 +0000 (20:45 +0000)
   picture buffer allocation scheme to allocate pictures from the render
   heap in a clockwise fashion instead of always picking the first available
   one from the start of the heap.
   This allows us to benefit from ffmpeg's macro-block skipping feature.
   As a side effect, we also have less chance of reusing a refrence picture
   buffer when we can't link/unlink them.

* modules/codec/ffmpeg/video.c: modified the direct rendering code to benefit
   from the macro-block skipping algorithm.
   A new flag has also been introduced in the video_output's render heap to
   forbid modifications to the render picture buffers (for instance to overlay
   subtitles).

include/video.h
include/vlc_config.h
modules/codec/ffmpeg/video.c
src/video_output/video_output.c
src/video_output/vout_pictures.c

index be29e9b..10f4f22 100644 (file)
@@ -4,7 +4,7 @@
  * includes all common video types and constants.
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: video.h,v 1.58 2002/11/11 14:39:11 sam Exp $
+ * $Id: video.h,v 1.59 2002/11/19 20:45:08 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *
@@ -102,6 +102,8 @@ struct picture_heap_t
 
     /* Real pictures */
     picture_t*      pp_picture[VOUT_MAX_PICTURES];               /* pictures */
+    int             i_last_used_pic;                /* last used pic in heap */
+    vlc_bool_t      b_allow_modify_pics;
 
     /* Stuff used for truecolor RGB planes */
     int i_rmask, i_rrshift, i_lrshift;
index dfde322..343c563 100644 (file)
  * (~1 Mbyte) before using huge values */
 #define VOUT_MAX_PICTURES               8
 
+/* Minimum number of direct pictures the video output will accept without
+ * creating additional pictures in system memory */
+#define VOUT_MIN_DIRECT_PICTURES        6
+
 /* Number of simultaneous subpictures */
 #define VOUT_MAX_SUBPICTURES            8
 
index 6719473..e3028c8 100644 (file)
@@ -2,7 +2,7 @@
  * video.c: video decoder using ffmpeg library
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: video.c,v 1.4 2002/11/10 02:47:27 fenrir Exp $
+ * $Id: video.c,v 1.5 2002/11/19 20:45:09 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -498,7 +498,7 @@ int E_( InitThread_Video )( vdec_thread_t *p_vdec )
 }
 
 /*****************************************************************************
- * DecodeThread: Called for decode one frame
+ * DecodeThread: Called to decode one frame
  *****************************************************************************
  * We have to get a frame stored in a pes, give it to ffmpeg decoder and send
  * the image to the output.
@@ -824,13 +824,12 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *avctx, int width,
 
     avctx->dr_opaque_frame = p_pic;
 
-    /* FIXME: this variable is used to determine if a macro-block to be written
+    /* This variable is used to determine if a macro-block to be written
      * can be skipped. The idea behind this is that if a macro-block hasn't
      * changed and all the frame-buffers already have the value of this
-     * macro-block, then we can skip the writting.
-     * But currently we cannot ensure this is the case, so we decide to write
-     * everything. */
-    avctx->dr_ip_buffer_count = 999;
+     * macro-block, then we don't need to write it again. */
+    avctx->dr_ip_buffer_count = p_vdec->p_vout->render.i_pictures;
+    p_vdec->p_vout->render.b_allow_modify_pics = 0;
 
     return 0;
 #endif
index 45b0ed8..2477b24 100644 (file)
@@ -5,7 +5,7 @@
  * thread, and destroy a previously oppened video output thread.
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: video_output.c,v 1.197 2002/11/13 20:51:05 sam Exp $
+ * $Id: video_output.c,v 1.198 2002/11/19 20:45:08 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *
@@ -142,6 +142,9 @@ vout_thread_t * __vout_CreateThread ( vlc_object_t *p_parent,
     p_vout->render.i_gmask    = 0;
     p_vout->render.i_bmask    = 0;
 
+    p_vout->render.i_last_used_pic = 0;
+    p_vout->render.b_allow_modify_pics = 1;
+
     /* Zero the output heap */
     I_OUTPUTPICTURES = 0;
     p_vout->output.i_width    = 0;
@@ -301,15 +304,23 @@ static int InitThread( vout_thread_t *p_vout )
          * for memcpy operations */
         p_vout->b_direct = 1;
 
-        msg_Dbg( p_vout, "direct render, mapping "
-                 "render pictures 0-%i to system pictures 1-%i",
-                 VOUT_MAX_PICTURES - 2, VOUT_MAX_PICTURES - 1 );
-
         for( i = 1; i < VOUT_MAX_PICTURES; i++ )
         {
+            if( p_vout->p_picture[ i ].i_type != DIRECT_PICTURE &&
+                I_RENDERPICTURES >= VOUT_MIN_DIRECT_PICTURES - 1 &&
+                p_vout->p_picture[ i - 1 ].i_type == DIRECT_PICTURE )
+            {
+                /* We have enough direct buffers so there's no need to
+                 * try to use system memory buffers. */
+                break;
+            }
             PP_RENDERPICTURE[ I_RENDERPICTURES ] = &p_vout->p_picture[ i ];
             I_RENDERPICTURES++;
         }
+
+        msg_Dbg( p_vout, "direct render, mapping "
+                 "render pictures 0-%i to system pictures 1-%i",
+                 VOUT_MAX_PICTURES - 2, VOUT_MAX_PICTURES - 1 );
     }
     else
     {
index fd44cad..7a999b3 100644 (file)
@@ -2,7 +2,7 @@
  * vout_pictures.c : picture management functions
  *****************************************************************************
  * Copyright (C) 2000 VideoLAN
- * $Id: vout_pictures.c,v 1.30 2002/11/10 18:04:24 sam Exp $
+ * $Id: vout_pictures.c,v 1.31 2002/11/19 20:45:09 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -118,22 +118,12 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout,
     vlc_mutex_lock( &p_vout->picture_lock );
 
     /*
-     * Look for an empty place. We start at 1 because the first
-     * directbuffer is reserved for memcpy()ed pictures.
+     * Look for an empty place in the picture heap.
      */
-    for( i_pic = 0; i_pic < I_RENDERPICTURES && p_freepic == NULL; i_pic++ )
+    for( i_pic = 0; i_pic < I_RENDERPICTURES; i_pic++ )
     {
-        p_pic = PP_RENDERPICTURE[ i_pic ];
-
-        /* If the picture we found is a memory buffer, and we have enough
-         * pictures in the stack, and we might have enough room later for
-         * a direct buffer, skip it. If no other pictures are found, the
-         * video decoder will try again later. */
-        if( p_vout->b_direct && ( p_vout->output.i_pictures > 5 )
-             && ( p_pic->i_type != DIRECT_PICTURE ) )
-        {
-            break;
-        }
+        p_pic = PP_RENDERPICTURE[(p_vout->render.i_last_used_pic + i_pic + 1)
+                                 % I_RENDERPICTURES];
 
         switch( p_pic->i_status )
         {
@@ -150,11 +140,17 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout,
                 p_pic->b_top_field_first    = b_top_field_first;
 
                 p_vout->i_heap_size++;
+                p_vout->render.i_last_used_pic =
+                    ( p_vout->render.i_last_used_pic + i_pic + 1 )
+                    % I_RENDERPICTURES;
                 vlc_mutex_unlock( &p_vout->picture_lock );
                 return( p_pic );
 
             case FREE_PICTURE:
                 /* Picture is empty and ready for allocation */
+                p_vout->render.i_last_used_pic =
+                    ( p_vout->render.i_last_used_pic + i_pic + 1 )
+                    % I_RENDERPICTURES;
                 p_freepic = p_pic;
                 break;
 
@@ -296,7 +292,7 @@ picture_t * vout_RenderPicture( vout_thread_t *p_vout, picture_t *p_pic,
 
     if( p_pic->i_type == DIRECT_PICTURE )
     {
-        if( p_pic->i_refcount )
+        if( !p_vout->render.b_allow_modify_pics || p_pic->i_refcount )
         {
             /* Picture is in a direct buffer and is still in use,
              * we need to copy it to another direct buffer before
@@ -676,4 +672,3 @@ static void CopyPicture( vout_thread_t * p_vout,
         }
     }
 }
-