Commit a2acda80 authored by Gildas Bazin's avatar Gildas Bazin

* include/video.h, include/vlc_config.h, src/video_output/*: changed the
   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).
parent 4a8ce8ac
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* includes all common video types and constants. * includes all common video types and constants.
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* *
...@@ -102,6 +102,8 @@ struct picture_heap_t ...@@ -102,6 +102,8 @@ struct picture_heap_t
/* Real pictures */ /* Real pictures */
picture_t* pp_picture[VOUT_MAX_PICTURES]; /* 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 */ /* Stuff used for truecolor RGB planes */
int i_rmask, i_rrshift, i_lrshift; int i_rmask, i_rrshift, i_lrshift;
......
...@@ -175,6 +175,10 @@ ...@@ -175,6 +175,10 @@
* (~1 Mbyte) before using huge values */ * (~1 Mbyte) before using huge values */
#define VOUT_MAX_PICTURES 8 #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 */ /* Number of simultaneous subpictures */
#define VOUT_MAX_SUBPICTURES 8 #define VOUT_MAX_SUBPICTURES 8
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* video.c: video decoder using ffmpeg library * video.c: video decoder using ffmpeg library
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com> * Gildas Bazin <gbazin@netcourrier.com>
...@@ -498,7 +498,7 @@ int E_( InitThread_Video )( vdec_thread_t *p_vdec ) ...@@ -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 * We have to get a frame stored in a pes, give it to ffmpeg decoder and send
* the image to the output. * the image to the output.
...@@ -824,13 +824,12 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *avctx, int width, ...@@ -824,13 +824,12 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *avctx, int width,
avctx->dr_opaque_frame = p_pic; 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 * 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 * changed and all the frame-buffers already have the value of this
* macro-block, then we can skip the writting. * macro-block, then we don't need to write it again. */
* But currently we cannot ensure this is the case, so we decide to write avctx->dr_ip_buffer_count = p_vdec->p_vout->render.i_pictures;
* everything. */ p_vdec->p_vout->render.b_allow_modify_pics = 0;
avctx->dr_ip_buffer_count = 999;
return 0; return 0;
#endif #endif
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* thread, and destroy a previously oppened video output thread. * thread, and destroy a previously oppened video output thread.
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2001 VideoLAN * 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> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* *
...@@ -142,6 +142,9 @@ vout_thread_t * __vout_CreateThread ( vlc_object_t *p_parent, ...@@ -142,6 +142,9 @@ vout_thread_t * __vout_CreateThread ( vlc_object_t *p_parent,
p_vout->render.i_gmask = 0; p_vout->render.i_gmask = 0;
p_vout->render.i_bmask = 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 */ /* Zero the output heap */
I_OUTPUTPICTURES = 0; I_OUTPUTPICTURES = 0;
p_vout->output.i_width = 0; p_vout->output.i_width = 0;
...@@ -301,15 +304,23 @@ static int InitThread( vout_thread_t *p_vout ) ...@@ -301,15 +304,23 @@ static int InitThread( vout_thread_t *p_vout )
* for memcpy operations */ * for memcpy operations */
p_vout->b_direct = 1; 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++ ) 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 ]; PP_RENDERPICTURE[ I_RENDERPICTURES ] = &p_vout->p_picture[ i ];
I_RENDERPICTURES++; 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 else
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vout_pictures.c : picture management functions * vout_pictures.c : picture management functions
***************************************************************************** *****************************************************************************
* Copyright (C) 2000 VideoLAN * 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> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -118,22 +118,12 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout, ...@@ -118,22 +118,12 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout,
vlc_mutex_lock( &p_vout->picture_lock ); vlc_mutex_lock( &p_vout->picture_lock );
/* /*
* Look for an empty place. We start at 1 because the first * Look for an empty place in the picture heap.
* directbuffer is reserved for memcpy()ed pictures.
*/ */
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 ]; p_pic = PP_RENDERPICTURE[(p_vout->render.i_last_used_pic + i_pic + 1)
% I_RENDERPICTURES];
/* 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;
}
switch( p_pic->i_status ) switch( p_pic->i_status )
{ {
...@@ -150,11 +140,17 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout, ...@@ -150,11 +140,17 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout,
p_pic->b_top_field_first = b_top_field_first; p_pic->b_top_field_first = b_top_field_first;
p_vout->i_heap_size++; 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 ); vlc_mutex_unlock( &p_vout->picture_lock );
return( p_pic ); return( p_pic );
case FREE_PICTURE: case FREE_PICTURE:
/* Picture is empty and ready for allocation */ /* 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; p_freepic = p_pic;
break; break;
...@@ -296,7 +292,7 @@ picture_t * vout_RenderPicture( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -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_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, /* Picture is in a direct buffer and is still in use,
* we need to copy it to another direct buffer before * we need to copy it to another direct buffer before
...@@ -676,4 +672,3 @@ static void CopyPicture( vout_thread_t * p_vout, ...@@ -676,4 +672,3 @@ static void CopyPicture( vout_thread_t * p_vout,
} }
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment