Commit cf7731db authored by Laurent Aimar's avatar Laurent Aimar

More vout spu split up.

parent 338a138e
......@@ -581,212 +581,15 @@ static void SpuRenderCreateAndLoadScale( spu_t *p_spu )
p_scale->p_module = module_Need( p_spu->p_scale, "video filter2", 0, 0 );
}
void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt,
static void SpuRenderRegion( spu_t *p_spu,
picture_t *p_pic_dst, picture_t *p_pic_src,
subpicture_t *p_subpic,
int i_scale_width_orig, int i_scale_height_orig )
subpicture_t *p_subpic, subpicture_region_t *p_region,
const int i_scale_width_orig, const int i_scale_height_orig,
const int pi_subpic_x[SCALE_SIZE],
const int pi_scale_width[SCALE_SIZE],
const int pi_scale_height[SCALE_SIZE],
const video_format_t *p_fmt )
{
int i_source_video_width;
int i_source_video_height;
subpicture_t *p_subpic_v = p_subpic;
/* Get lock */
vlc_mutex_lock( &p_spu->subpicture_lock );
for( p_subpic_v = p_subpic;
p_subpic_v != NULL && p_subpic_v->i_status != FREE_SUBPICTURE;
p_subpic_v = p_subpic_v->p_next )
{
if( p_subpic_v->pf_pre_render )
{
p_subpic_v->pf_pre_render( p_fmt, p_spu, p_subpic_v, mdate() );
}
}
if( i_scale_width_orig <= 0 )
i_scale_width_orig = 1;
if( i_scale_height_orig <= 0 )
i_scale_height_orig = 1;
i_source_video_width = p_fmt->i_width * 1000 / i_scale_width_orig;
i_source_video_height = p_fmt->i_height * 1000 / i_scale_height_orig;
/* Check i_status again to make sure spudec hasn't destroyed the subpic */
while( ( p_subpic != NULL ) && ( p_subpic->i_status != FREE_SUBPICTURE ) )
{
subpicture_region_t *p_region;
int pi_scale_width[ SCALE_SIZE ];
int pi_scale_height[ SCALE_SIZE ];
int pi_subpic_x[ SCALE_SIZE ];
int k;
/* If the source video and subtitles stream agree on the size of
* the video then disregard all further references to the subtitle
* stream.
*/
if( ( i_source_video_height == p_subpic->i_original_picture_height ) &&
( i_source_video_width == p_subpic->i_original_picture_width ) )
{
p_subpic->i_original_picture_height = 0;
p_subpic->i_original_picture_width = 0;
}
for( k = 0; k < SCALE_SIZE ; k++ )
pi_subpic_x[ k ] = p_subpic->i_x;
if( p_subpic->pf_update_regions )
{
if ( p_subpic->p_region ) {
spu_DestroyRegion( p_spu, p_subpic->p_region );
}
/* TODO do not reverse the scaling that was done before calling
* spu_RenderSubpictures, just pass it along (or do it inside
* spu_RenderSubpictures) */
video_format_t fmt_org = *p_fmt;
fmt_org.i_width =
fmt_org.i_visible_width = i_source_video_width;
fmt_org.i_height =
fmt_org.i_visible_height = i_source_video_height;
p_subpic->p_region = p_region = p_subpic->pf_update_regions( &fmt_org, p_spu, p_subpic, mdate() );
}
else
{
p_region = p_subpic->p_region;
}
/* Create the blending module */
if( !p_spu->p_blend && p_region )
SpuRenderCreateBlend( p_spu, p_fmt->i_chroma, p_fmt->i_aspect );
/* Load the text rendering module; it is possible there is a
* text region somewhere in the subpicture other than the first
* element in the region list, so just load it anyway as we'll
* probably want it sooner or later. */
if( !p_spu->p_text && p_region )
SpuRenderCreateAndLoadText( p_spu, p_fmt->i_width, p_fmt->i_height );
if( p_spu->p_text )
{
subpicture_region_t *p_text_region = p_subpic->p_region;
/* Only overwrite the size fields if the region is still in
* pre-rendered TEXT format. We have to traverse the subregion
* list because if more than one subregion is present, the text
* region isn't guarentteed to be the first in the list, and
* only text regions use this flag. All of this effort assists
* with the rescaling of text that has been rendered at native
* resolution, rather than video resolution.
*/
while( p_text_region &&
( p_text_region->fmt.i_chroma != VLC_FOURCC('T','E','X','T') ) )
{
p_text_region = p_text_region->p_next;
}
if( p_text_region &&
( ( p_text_region->i_align & SUBPICTURE_RENDERED ) == 0 ) )
{
if( (p_subpic->i_original_picture_height > 0) &&
(p_subpic->i_original_picture_width > 0) )
{
p_spu->p_text->fmt_out.video.i_width =
p_spu->p_text->fmt_out.video.i_visible_width =
p_subpic->i_original_picture_width;
p_spu->p_text->fmt_out.video.i_height =
p_spu->p_text->fmt_out.video.i_visible_height =
p_subpic->i_original_picture_height;
}
else
{
p_spu->p_text->fmt_out.video.i_width =
p_spu->p_text->fmt_out.video.i_visible_width =
p_fmt->i_width;
p_spu->p_text->fmt_out.video.i_height =
p_spu->p_text->fmt_out.video.i_visible_height =
p_fmt->i_height;
}
}
}
pi_scale_width[ SCALE_DEFAULT ] = i_scale_width_orig;
pi_scale_height[ SCALE_DEFAULT ] = i_scale_height_orig;
if( p_spu->p_text )
{
pi_scale_width[ SCALE_TEXT ] = ( p_fmt->i_width * 1000 ) /
p_spu->p_text->fmt_out.video.i_width;
pi_scale_height[ SCALE_TEXT ] = ( p_fmt->i_height * 1000 ) /
p_spu->p_text->fmt_out.video.i_height;
}
/* If we have an explicit size plane to render to, then turn off
* the fontsize rescaling.
*/
if( (p_subpic->i_original_picture_height > 0) &&
(p_subpic->i_original_picture_width > 0) )
{
i_scale_width_orig = 1000;
i_scale_height_orig = 1000;
}
for( k = 0; k < SCALE_SIZE ; k++ )
{
/* Case of both width and height being specified has been dealt
* with above by instead rendering to an output pane of the
* explicit dimensions specified - we don't need to scale it.
*/
if( (p_subpic->i_original_picture_height > 0) &&
(p_subpic->i_original_picture_width <= 0) )
{
pi_scale_height[ k ] = pi_scale_height[ k ] * i_source_video_height /
p_subpic->i_original_picture_height;
pi_scale_width[ k ] = pi_scale_width[ k ] * i_source_video_height /
p_subpic->i_original_picture_height;
}
}
/* Set default subpicture aspect ratio */
if( p_region && p_region->fmt.i_aspect &&
( !p_region->fmt.i_sar_num || !p_region->fmt.i_sar_den ) )
{
p_region->fmt.i_sar_den = p_region->fmt.i_aspect;
p_region->fmt.i_sar_num = VOUT_ASPECT_FACTOR;
}
if( p_region &&
( !p_region->fmt.i_sar_num || !p_region->fmt.i_sar_den ) )
{
p_region->fmt.i_sar_den = p_fmt->i_sar_den;
p_region->fmt.i_sar_num = p_fmt->i_sar_num;
}
/* Take care of the aspect ratio */
if( p_region &&
( ( p_region->fmt.i_sar_num * p_fmt->i_sar_den ) !=
( p_region->fmt.i_sar_den * p_fmt->i_sar_num ) ) )
{
for( k = 0; k < SCALE_SIZE ; k++ )
{
pi_scale_width[ k ] = pi_scale_width[ k ] *
(int64_t)p_region->fmt.i_sar_num * p_fmt->i_sar_den /
p_region->fmt.i_sar_den / p_fmt->i_sar_num;
pi_subpic_x[ k ] = p_subpic->i_x * pi_scale_width[ k ] / 1000;
}
}
/* Load the scaling module */
if( !p_spu->p_scale &&
((((pi_scale_width[ SCALE_TEXT ] > 0) || (pi_scale_height[ SCALE_TEXT ] > 0)) &&
((pi_scale_width[ SCALE_TEXT ] != 1000) || (pi_scale_height[ SCALE_TEXT ] != 1000))) ||
(((pi_scale_width[ SCALE_DEFAULT ] > 0) || (pi_scale_height[ SCALE_DEFAULT ] > 0)) &&
((pi_scale_width[ SCALE_DEFAULT ] != 1000) || (pi_scale_height[ SCALE_DEFAULT ] != 1000)))) )
{
SpuRenderCreateAndLoadScale( p_spu );
}
while( p_region )
{
video_format_t orig_fmt = p_region->fmt;
bool b_rerender_text = false;
int i_fade_alpha = 255;
......@@ -1095,10 +898,222 @@ void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt,
p_region->fmt = orig_fmt;
p_region->i_align &= ~SUBPICTURE_RENDERED;
}
p_region = p_region->p_next;
}
void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt,
picture_t *p_pic_dst, picture_t *p_pic_src,
subpicture_t *p_subpic,
int i_scale_width_orig, int i_scale_height_orig )
{
int i_source_video_width;
int i_source_video_height;
subpicture_t *p_subpic_v;
/* Get lock */
vlc_mutex_lock( &p_spu->subpicture_lock );
for( p_subpic_v = p_subpic;
p_subpic_v != NULL && p_subpic_v->i_status != FREE_SUBPICTURE;
p_subpic_v = p_subpic_v->p_next )
{
if( p_subpic_v->pf_pre_render )
{
p_subpic_v->pf_pre_render( p_fmt, p_spu, p_subpic_v, mdate() );
}
}
if( i_scale_width_orig <= 0 )
i_scale_width_orig = 1;
if( i_scale_height_orig <= 0 )
i_scale_height_orig = 1;
i_source_video_width = p_fmt->i_width * 1000 / i_scale_width_orig;
i_source_video_height = p_fmt->i_height * 1000 / i_scale_height_orig;
/* Check i_status again to make sure spudec hasn't destroyed the subpic */
for( ; ( p_subpic != NULL ) && ( p_subpic->i_status != FREE_SUBPICTURE ); p_subpic = p_subpic->p_next )
{
subpicture_region_t *p_region;
int pi_scale_width[ SCALE_SIZE ];
int pi_scale_height[ SCALE_SIZE ];
int pi_subpic_x[ SCALE_SIZE ];
int k;
/* If the source video and subtitles stream agree on the size of
* the video then disregard all further references to the subtitle
* stream.
*/
if( ( i_source_video_height == p_subpic->i_original_picture_height ) &&
( i_source_video_width == p_subpic->i_original_picture_width ) )
{
p_subpic->i_original_picture_height = 0;
p_subpic->i_original_picture_width = 0;
}
for( k = 0; k < SCALE_SIZE ; k++ )
pi_subpic_x[ k ] = p_subpic->i_x;
if( p_subpic->pf_update_regions )
{
if ( p_subpic->p_region ) {
spu_DestroyRegion( p_spu, p_subpic->p_region );
}
/* TODO do not reverse the scaling that was done before calling
* spu_RenderSubpictures, just pass it along (or do it inside
* spu_RenderSubpictures) */
video_format_t fmt_org = *p_fmt;
fmt_org.i_width =
fmt_org.i_visible_width = i_source_video_width;
fmt_org.i_height =
fmt_org.i_visible_height = i_source_video_height;
p_subpic->p_region = p_region = p_subpic->pf_update_regions( &fmt_org, p_spu, p_subpic, mdate() );
}
else
{
p_region = p_subpic->p_region;
}
/* Create the blending module */
if( !p_spu->p_blend && p_region )
SpuRenderCreateBlend( p_spu, p_fmt->i_chroma, p_fmt->i_aspect );
/* Load the text rendering module; it is possible there is a
* text region somewhere in the subpicture other than the first
* element in the region list, so just load it anyway as we'll
* probably want it sooner or later. */
if( !p_spu->p_text && p_region )
SpuRenderCreateAndLoadText( p_spu, p_fmt->i_width, p_fmt->i_height );
if( p_spu->p_text )
{
subpicture_region_t *p_text_region = p_subpic->p_region;
/* Only overwrite the size fields if the region is still in
* pre-rendered TEXT format. We have to traverse the subregion
* list because if more than one subregion is present, the text
* region isn't guarentteed to be the first in the list, and
* only text regions use this flag. All of this effort assists
* with the rescaling of text that has been rendered at native
* resolution, rather than video resolution.
*/
while( p_text_region &&
( p_text_region->fmt.i_chroma != VLC_FOURCC('T','E','X','T') ) )
{
p_text_region = p_text_region->p_next;
}
if( p_text_region &&
( ( p_text_region->i_align & SUBPICTURE_RENDERED ) == 0 ) )
{
if( (p_subpic->i_original_picture_height > 0) &&
(p_subpic->i_original_picture_width > 0) )
{
p_spu->p_text->fmt_out.video.i_width =
p_spu->p_text->fmt_out.video.i_visible_width =
p_subpic->i_original_picture_width;
p_spu->p_text->fmt_out.video.i_height =
p_spu->p_text->fmt_out.video.i_visible_height =
p_subpic->i_original_picture_height;
}
else
{
p_spu->p_text->fmt_out.video.i_width =
p_spu->p_text->fmt_out.video.i_visible_width =
p_fmt->i_width;
p_spu->p_text->fmt_out.video.i_height =
p_spu->p_text->fmt_out.video.i_visible_height =
p_fmt->i_height;
}
}
}
pi_scale_width[ SCALE_DEFAULT ] = i_scale_width_orig;
pi_scale_height[ SCALE_DEFAULT ] = i_scale_height_orig;
if( p_spu->p_text )
{
pi_scale_width[ SCALE_TEXT ] = ( p_fmt->i_width * 1000 ) /
p_spu->p_text->fmt_out.video.i_width;
pi_scale_height[ SCALE_TEXT ] = ( p_fmt->i_height * 1000 ) /
p_spu->p_text->fmt_out.video.i_height;
}
/* If we have an explicit size plane to render to, then turn off
* the fontsize rescaling.
*/
if( (p_subpic->i_original_picture_height > 0) &&
(p_subpic->i_original_picture_width > 0) )
{
/* FIXME That seems so wrong */
i_scale_width_orig = 1000;
i_scale_height_orig = 1000;
/* It is probably that :
pi_scale_width[ SCALE_DEFAULT ] = i_scale_width_orig * i_source_video_width / p_subpic->i_original_picture_width;
pi_scale_height[ SCALE_DEFAULT ] = i_scale_height_orig * i_source_video_height / p_subpic->i_original_picture_height;
*/
}
for( k = 0; k < SCALE_SIZE ; k++ )
{
/* Case of both width and height being specified has been dealt
* with above by instead rendering to an output pane of the
* explicit dimensions specified - we don't need to scale it.
*/
if( (p_subpic->i_original_picture_height > 0) &&
(p_subpic->i_original_picture_width <= 0) )
{
pi_scale_height[ k ] = pi_scale_height[ k ] * i_source_video_height /
p_subpic->i_original_picture_height;
pi_scale_width[ k ] = pi_scale_width[ k ] * i_source_video_height /
p_subpic->i_original_picture_height;
}
}
/* Set default subpicture aspect ratio */
if( p_region && p_region->fmt.i_aspect &&
( !p_region->fmt.i_sar_num || !p_region->fmt.i_sar_den ) )
{
p_region->fmt.i_sar_den = p_region->fmt.i_aspect;
p_region->fmt.i_sar_num = VOUT_ASPECT_FACTOR;
}
if( p_region &&
( !p_region->fmt.i_sar_num || !p_region->fmt.i_sar_den ) )
{
p_region->fmt.i_sar_den = p_fmt->i_sar_den;
p_region->fmt.i_sar_num = p_fmt->i_sar_num;
}
/* Take care of the aspect ratio */
if( p_region &&
( ( p_region->fmt.i_sar_num * p_fmt->i_sar_den ) !=
( p_region->fmt.i_sar_den * p_fmt->i_sar_num ) ) )
{
for( k = 0; k < SCALE_SIZE ; k++ )
{
pi_scale_width[ k ] = pi_scale_width[ k ] *
(int64_t)p_region->fmt.i_sar_num * p_fmt->i_sar_den /
p_region->fmt.i_sar_den / p_fmt->i_sar_num;
pi_subpic_x[ k ] = p_subpic->i_x * pi_scale_width[ k ] / 1000;
}
}
/* Load the scaling module */
if( !p_spu->p_scale &&
((((pi_scale_width[ SCALE_TEXT ] > 0) || (pi_scale_height[ SCALE_TEXT ] > 0)) &&
((pi_scale_width[ SCALE_TEXT ] != 1000) || (pi_scale_height[ SCALE_TEXT ] != 1000))) ||
(((pi_scale_width[ SCALE_DEFAULT ] > 0) || (pi_scale_height[ SCALE_DEFAULT ] > 0)) &&
((pi_scale_width[ SCALE_DEFAULT ] != 1000) || (pi_scale_height[ SCALE_DEFAULT ] != 1000)))) )
{
SpuRenderCreateAndLoadScale( p_spu );
}
p_subpic = p_subpic->p_next;
for( ; p_region != NULL; p_region = p_region->p_next )
SpuRenderRegion( p_spu, p_pic_dst, p_pic_src,
p_subpic, p_region, i_scale_width_orig, i_scale_height_orig,
pi_subpic_x, pi_scale_width, pi_scale_height,
p_fmt );
}
vlc_mutex_unlock( &p_spu->subpicture_lock );
......
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