From a2acda80709dce29084b0dd0ce131e6edbbb3fe2 Mon Sep 17 00:00:00 2001 From: Gildas Bazin Date: Tue, 19 Nov 2002 20:45:09 +0000 Subject: [PATCH] * 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). --- include/video.h | 4 +++- include/vlc_config.h | 4 ++++ modules/codec/ffmpeg/video.c | 13 ++++++------- src/video_output/video_output.c | 21 ++++++++++++++++----- src/video_output/vout_pictures.c | 29 ++++++++++++----------------- 5 files changed, 41 insertions(+), 30 deletions(-) diff --git a/include/video.h b/include/video.h index be29e9be7e..10f4f228aa 100644 --- a/include/video.h +++ b/include/video.h @@ -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 * @@ -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; diff --git a/include/vlc_config.h b/include/vlc_config.h index dfde322fbe..343c5638cc 100644 --- a/include/vlc_config.h +++ b/include/vlc_config.h @@ -175,6 +175,10 @@ * (~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 diff --git a/modules/codec/ffmpeg/video.c b/modules/codec/ffmpeg/video.c index 6719473d6e..e3028c87cf 100644 --- a/modules/codec/ffmpeg/video.c +++ b/modules/codec/ffmpeg/video.c @@ -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 * Gildas Bazin @@ -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 diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index 45b0ed823c..2477b2470d 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -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 * @@ -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 { diff --git a/src/video_output/vout_pictures.c b/src/video_output/vout_pictures.c index fd44cad8b0..7a999b344c 100644 --- a/src/video_output/vout_pictures.c +++ b/src/video_output/vout_pictures.c @@ -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 * Samuel Hocevar @@ -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, } } } - -- 2.39.2