Commit 8f801815 authored by Gildas Bazin's avatar Gildas Bazin

* include/video_output.h, include/vlc_video.h, src/video_output/*:

   + When dealing with slow direct buffers, use a temporary picture to overlay subtitles (avoids slow reads during alpha-blending).
* modules/video_output/directx/directx.c: signal slow picture buffers.
parent 165acf14
...@@ -123,7 +123,7 @@ struct vout_thread_t ...@@ -123,7 +123,7 @@ struct vout_thread_t
/**@}*/ /**@}*/
/* Picture and subpicture heaps */ /* Picture and subpicture heaps */
picture_t p_picture[2*VOUT_MAX_PICTURES]; /**< pictures */ picture_t p_picture[2*VOUT_MAX_PICTURES+1]; /**< pictures */
subpicture_t p_subpicture[VOUT_MAX_PICTURES]; /**< subpictures */ subpicture_t p_subpicture[VOUT_MAX_PICTURES]; /**< subpictures */
subpicture_t *p_default_channel; /**< subpicture in the default subpicture_t *p_default_channel; /**< subpicture in the default
channel */ channel */
......
...@@ -74,6 +74,7 @@ struct picture_t ...@@ -74,6 +74,7 @@ struct picture_t
* @{*/ * @{*/
int i_status; /**< picture flags */ int i_status; /**< picture flags */
int i_type; /**< is picture a direct buffer ? */ int i_type; /**< is picture a direct buffer ? */
vlc_bool_t b_slow; /**< is picture in slow memory ? */
int i_matrix_coefficients; /**< in YUV type, encoding type */ int i_matrix_coefficients; /**< in YUV type, encoding type */
/**@}*/ /**@}*/
......
...@@ -1533,6 +1533,7 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -1533,6 +1533,7 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
{ {
p_pic[i].i_status = DESTROYED_PICTURE; p_pic[i].i_status = DESTROYED_PICTURE;
p_pic[i].i_type = DIRECT_PICTURE; p_pic[i].i_type = DIRECT_PICTURE;
p_pic[i].b_slow = VLC_TRUE;
p_pic[i].pf_lock = DirectXLockSurface; p_pic[i].pf_lock = DirectXLockSurface;
p_pic[i].pf_unlock = DirectXUnlockSurface; p_pic[i].pf_unlock = DirectXUnlockSurface;
PP_OUTPUTPICTURE[i] = &p_pic[i]; PP_OUTPUTPICTURE[i] = &p_pic[i];
......
...@@ -236,12 +236,13 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, ...@@ -236,12 +236,13 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent,
/* Initialize pictures and subpictures - translation tables and functions /* Initialize pictures and subpictures - translation tables and functions
* will be initialized later in InitThread */ * will be initialized later in InitThread */
for( i_index = 0; i_index < 2 * VOUT_MAX_PICTURES; i_index++) for( i_index = 0; i_index < 2 * VOUT_MAX_PICTURES + 1; i_index++)
{ {
p_vout->p_picture[i_index].pf_lock = NULL; p_vout->p_picture[i_index].pf_lock = NULL;
p_vout->p_picture[i_index].pf_unlock = NULL; p_vout->p_picture[i_index].pf_unlock = NULL;
p_vout->p_picture[i_index].i_status = FREE_PICTURE; p_vout->p_picture[i_index].i_status = FREE_PICTURE;
p_vout->p_picture[i_index].i_type = EMPTY_PICTURE; p_vout->p_picture[i_index].i_type = EMPTY_PICTURE;
p_vout->p_picture[i_index].b_slow = 0;
} }
for( i_index = 0; i_index < VOUT_MAX_SUBPICTURES; i_index++) for( i_index = 0; i_index < VOUT_MAX_SUBPICTURES; i_index++)
...@@ -1114,7 +1115,7 @@ static void EndThread( vout_thread_t *p_vout ) ...@@ -1114,7 +1115,7 @@ static void EndThread( vout_thread_t *p_vout )
} }
/* Destroy all remaining pictures */ /* Destroy all remaining pictures */
for( i_index = 0; i_index < 2 * VOUT_MAX_PICTURES; i_index++ ) for( i_index = 0; i_index < 2 * VOUT_MAX_PICTURES + 1; i_index++ )
{ {
if ( p_vout->p_picture[i_index].i_type == MEMORY_PICTURE ) if ( p_vout->p_picture[i_index].i_type == MEMORY_PICTURE )
{ {
......
...@@ -178,6 +178,7 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout, ...@@ -178,6 +178,7 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout,
/* Copy picture information, set some default values */ /* Copy picture information, set some default values */
p_freepic->i_status = RESERVED_PICTURE; p_freepic->i_status = RESERVED_PICTURE;
p_freepic->i_type = MEMORY_PICTURE; p_freepic->i_type = MEMORY_PICTURE;
p_freepic->b_slow = 0;
p_freepic->i_refcount = 0; p_freepic->i_refcount = 0;
p_freepic->b_force = 0; p_freepic->b_force = 0;
...@@ -346,9 +347,41 @@ picture_t * vout_RenderPicture( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -346,9 +347,41 @@ picture_t * vout_RenderPicture( vout_thread_t *p_vout, picture_t *p_pic,
return NULL; return NULL;
} }
CopyPicture( p_vout, p_pic, PP_OUTPUTPICTURE[0] ); if( p_subpic == NULL ||
( p_vout->render.b_allow_modify_pics && !p_pic->i_refcount ) )
{
vout_RenderSubPictures( p_vout, p_pic, p_subpic );
CopyPicture( p_vout, p_pic, PP_OUTPUTPICTURE[0] );
}
else if( PP_OUTPUTPICTURE[0]->b_slow )
{
/* The picture buffer is in slow memory. We'll use
* the "2 * VOUT_MAX_PICTURES + 1" picture as a temporary
* one for subpictures rendering. */
picture_t *p_tmp_pic = &p_vout->p_picture[2 * VOUT_MAX_PICTURES];
if( p_tmp_pic->i_status == FREE_PICTURE )
{
vout_AllocatePicture( VLC_OBJECT(p_vout),
p_tmp_pic, p_vout->render.i_chroma,
p_vout->render.i_width,
p_vout->render.i_height,
p_vout->render.i_aspect );
p_tmp_pic->i_type = MEMORY_PICTURE;
p_tmp_pic->i_status = RESERVED_PICTURE;
}
CopyPicture( p_vout, p_pic, p_tmp_pic );
vout_RenderSubPictures( p_vout, p_tmp_pic, p_subpic );
vout_RenderSubPictures( p_vout, PP_OUTPUTPICTURE[0], p_subpic ); CopyPicture( p_vout, p_tmp_pic, PP_OUTPUTPICTURE[0] );
}
else
{
CopyPicture( p_vout, p_pic, PP_OUTPUTPICTURE[0] );
vout_RenderSubPictures( p_vout, PP_OUTPUTPICTURE[0], p_subpic );
}
if( PP_OUTPUTPICTURE[0]->pf_unlock ) if( PP_OUTPUTPICTURE[0]->pf_unlock )
PP_OUTPUTPICTURE[0]->pf_unlock( p_vout, PP_OUTPUTPICTURE[0] ); PP_OUTPUTPICTURE[0]->pf_unlock( p_vout, PP_OUTPUTPICTURE[0] );
...@@ -361,15 +394,47 @@ picture_t * vout_RenderPicture( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -361,15 +394,47 @@ picture_t * vout_RenderPicture( vout_thread_t *p_vout, picture_t *p_pic,
* well. This usually means software YUV, or hardware YUV with a * well. This usually means software YUV, or hardware YUV with a
* different chroma. */ * different chroma. */
if( p_vout->p_picture[0].pf_lock ) if( p_subpic != NULL && p_vout->p_picture[0].b_slow )
if( p_vout->p_picture[0].pf_lock( p_vout, &p_vout->p_picture[0] ) ) {
return NULL; /* The picture buffer is in slow memory. We'll use
* the "2 * VOUT_MAX_PICTURES + 1" picture as a temporary
* one for subpictures rendering. */
picture_t *p_tmp_pic = &p_vout->p_picture[2 * VOUT_MAX_PICTURES];
if( p_tmp_pic->i_status == FREE_PICTURE )
{
vout_AllocatePicture( VLC_OBJECT(p_vout),
p_tmp_pic, p_vout->output.i_chroma,
p_vout->output.i_width,
p_vout->output.i_height,
p_vout->output.i_aspect );
p_tmp_pic->i_type = MEMORY_PICTURE;
p_tmp_pic->i_status = RESERVED_PICTURE;
}
/* Convert image to the first direct buffer */
p_vout->chroma.pf_convert( p_vout, p_pic, p_tmp_pic );
/* Render subpictures on the first direct buffer */
vout_RenderSubPictures( p_vout, p_tmp_pic, p_subpic );
if( p_vout->p_picture[0].pf_lock )
if( p_vout->p_picture[0].pf_lock( p_vout, &p_vout->p_picture[0] ) )
return NULL;
CopyPicture( p_vout, p_tmp_pic, &p_vout->p_picture[0] );
}
else
{
if( p_vout->p_picture[0].pf_lock )
if( p_vout->p_picture[0].pf_lock( p_vout, &p_vout->p_picture[0] ) )
return NULL;
/* Convert image to the first direct buffer */ /* Convert image to the first direct buffer */
p_vout->chroma.pf_convert( p_vout, p_pic, &p_vout->p_picture[0] ); p_vout->chroma.pf_convert( p_vout, p_pic, &p_vout->p_picture[0] );
/* Render subpictures on the first direct buffer */ /* Render subpictures on the first direct buffer */
vout_RenderSubPictures( p_vout, &p_vout->p_picture[0], p_subpic ); vout_RenderSubPictures( p_vout, &p_vout->p_picture[0], p_subpic );
}
if( p_vout->p_picture[0].pf_unlock ) if( p_vout->p_picture[0].pf_unlock )
p_vout->p_picture[0].pf_unlock( p_vout, &p_vout->p_picture[0] ); p_vout->p_picture[0].pf_unlock( p_vout, &p_vout->p_picture[0] );
......
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