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 @@
* 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;
......
......@@ -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
......
......@@ -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
......
......@@ -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
{
......
......@@ -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,
}
}
}
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