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).
* includes all common video types and constants.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* 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>
*
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
/* Real pictures */
picture_t* pp_picture[VOUT_MAX_PICTURES]; /* pictures */
/* 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;
/* Stuff used for truecolor RGB planes */
int i_rmask, i_rrshift, i_lrshift;
* (~1 Mbyte) before using huge values */
#define VOUT_MAX_PICTURES 8
* (~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
/* Number of simultaneous subpictures */
#define VOUT_MAX_SUBPICTURES 8
* video.c: video decoder using ffmpeg library
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* 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>
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com>
}
/*****************************************************************************
}
/*****************************************************************************
- * 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.
*****************************************************************************
* We have to get a frame stored in a pes, give it to ffmpeg decoder and send
* the image to the output.
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
* changed and all the frame-buffers already have the value of this
* 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;
* thread, and destroy a previously oppened video output thread.
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* 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>
*
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
p_vout->render.i_gmask = 0;
p_vout->render.i_bmask = 0;
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;
/* Zero the output heap */
I_OUTPUTPICTURES = 0;
p_vout->output.i_width = 0;
* for memcpy operations */
p_vout->b_direct = 1;
* 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++ )
{
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++;
}
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 );
* vout_pictures.c : picture management functions
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* 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>
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
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
- * 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 )
{
switch( p_pic->i_status )
{
p_pic->b_top_field_first = b_top_field_first;
p_vout->i_heap_size++;
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 */
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;
p_freepic = p_pic;
break;
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,
* we need to copy it to another direct buffer before
{
/* Picture is in a direct buffer and is still in use,
* we need to copy it to another direct buffer before