[vlc-devel] commit: Render subpictures in the right order to improve overlap support. ( Laurent Aimar )
git version control
git at videolan.org
Sat Sep 20 16:51:32 CEST 2008
vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Fri Sep 19 23:05:09 2008 +0200| [692cad3b3eb855aea24675bec42c594edccccff8] | committer: Laurent Aimar
Render subpictures in the right order to improve overlap support.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=692cad3b3eb855aea24675bec42c594edccccff8
---
include/vlc_osd.h | 1 +
include/vlc_vout.h | 1 +
src/video_output/vout_subpictures.c | 109 +++++++++++++++++++++--------------
3 files changed, 67 insertions(+), 44 deletions(-)
diff --git a/include/vlc_osd.h b/include/vlc_osd.h
index 54625ff..d1322f7 100644
--- a/include/vlc_osd.h
+++ b/include/vlc_osd.h
@@ -64,6 +64,7 @@ struct spu_t
vlc_mutex_t subpicture_lock; /**< subpicture heap lock */
subpicture_t p_subpicture[VOUT_MAX_SUBPICTURES]; /**< subpictures */
int i_channel; /**< number of subpicture channels registered */
+ int64_t i_subpicture_order; /**< number of created subpicture since spu creation */
filter_t *p_blend; /**< alpha blending module */
filter_t *p_text; /**< text renderer module */
diff --git a/include/vlc_vout.h b/include/vlc_vout.h
index 5d39e1b..377448d 100644
--- a/include/vlc_vout.h
+++ b/include/vlc_vout.h
@@ -332,6 +332,7 @@ struct subpicture_t
/** \name Type and flags
Should NOT be modified except by the vout thread */
/**@{*/
+ int64_t i_order; /** an increasing unique number */
int i_type; /**< type */
int i_status; /**< flags */
subpicture_t * p_next; /**< next subtitle to be displayed */
diff --git a/src/video_output/vout_subpictures.c b/src/video_output/vout_subpictures.c
index 6b1357e..1ed1021 100644
--- a/src/video_output/vout_subpictures.c
+++ b/src/video_output/vout_subpictures.c
@@ -85,7 +85,8 @@ spu_t *__spu_Create( vlc_object_t *p_this )
int i_index;
spu_t *p_spu = vlc_custom_create( p_this, sizeof( spu_t ),
VLC_OBJECT_GENERIC, "subpicture" );
-
+ /* */
+ p_spu->i_subpicture_order = 1;
for( i_index = 0; i_index < VOUT_MAX_SUBPICTURES; i_index++)
{
p_spu->p_subpicture[i_index].i_status = FREE_SUBPICTURE;
@@ -312,15 +313,15 @@ void spu_DisplaySubpicture( spu_t *p_spu, subpicture_t *p_subpic )
p_subpic, p_subpic->i_status );
}
- /* Remove reservation flag */
- p_subpic->i_status = READY_SUBPICTURE;
-
if( p_subpic->i_channel == DEFAULT_CHAN )
{
p_subpic->i_channel = 0xFFFF;
spu_Control( p_spu, SPU_CHANNEL_CLEAR, DEFAULT_CHAN );
p_subpic->i_channel = DEFAULT_CHAN;
}
+
+ /* Remove reservation flag */
+ p_subpic->i_status = READY_SUBPICTURE;
}
/**
@@ -366,6 +367,7 @@ subpicture_t *spu_CreateSubpicture( spu_t *p_spu )
/* Copy subpicture information, set some default values */
memset( p_subpic, 0, sizeof(subpicture_t) );
+ p_subpic->i_order = p_spu->i_subpicture_order++;
p_subpic->i_status = RESERVED_SUBPICTURE;
p_subpic->b_absolute = true;
p_subpic->b_fade = false;
@@ -1002,10 +1004,6 @@ static void SpuRenderRegion( spu_t *p_spu,
p_scale->fmt_in.video = p_region->fmt;
p_scale->fmt_out.video = p_region->fmt;
- if( p_scale->fmt_out.video.p_palette )
- *p_scale->fmt_out.video.p_palette =
- *p_region->fmt.p_palette;
-
p_scale->fmt_out.video.i_width = i_dst_width;
p_scale->fmt_out.video.i_height = i_dst_height;
@@ -1026,10 +1024,12 @@ static void SpuRenderRegion( spu_t *p_spu,
}
if( p_pic )
{
- picture_Copy( &p_region->p_cache->picture, p_pic );
+ picture_CopyPixels( &p_region->p_cache->picture, p_pic );
picture_Release( p_pic );
- p_region->p_cache->fmt = p_scale->fmt_out.video;
+ if( p_region->p_cache->fmt.p_palette )
+ *p_region->p_cache->fmt.p_palette = *p_region->fmt.p_palette;
+
/* i_x/i_y of cached region should NOT be used. I set them to
* an invalid value to catch it (assert) */
p_region->p_cache->i_x = INT_MAX;
@@ -1127,6 +1127,38 @@ exit:
}
/**
+ * This function compares two 64 bits integers.
+ * It can be used by qsort.
+ */
+static int IntegerCmp( int64_t i0, int64_t i1 )
+{
+ return i0 < i1 ? -1 : i0 > i1 ? 1 : 0;
+}
+/**
+ * This function compares 2 subpictures using the following properties
+ * (ordered by priority)
+ * 1. absolute positionning
+ * 2. start time
+ * 3. creation order
+ *
+ * It can be used by qsort.
+ *
+ * XXX spu_RenderSubpictures depends heavily on this order.
+ */
+static int SubpictureCmp( const void *s0, const void *s1 )
+{
+ subpicture_t *p_subpic0 = *(subpicture_t**)s0;
+ subpicture_t *p_subpic1 = *(subpicture_t**)s1;
+ int r;
+
+ r = IntegerCmp( !p_subpic0->b_absolute, !p_subpic1->b_absolute );
+ if( !r )
+ r = IntegerCmp( p_subpic0->i_start, p_subpic1->i_start );
+ if( !r )
+ r = IntegerCmp( p_subpic0->i_order, p_subpic1->i_order );
+ return r;
+}
+/**
* This function renders all sub picture units in the list.
*/
void spu_RenderSubpictures( spu_t *p_spu,
@@ -1138,28 +1170,21 @@ void spu_RenderSubpictures( spu_t *p_spu,
const int i_source_video_height = p_fmt_src->i_height;
const mtime_t i_current_date = mdate();
+ unsigned int i_subpicture;
+ subpicture_t *pp_subpicture[VOUT_MAX_SUBPICTURES];
+
unsigned int i_subtitle_region_count;
spu_area_t p_subtitle_area_buffer[VOUT_MAX_SUBPICTURES];
spu_area_t *p_subtitle_area;
int i_subtitle_area;
- subpicture_t *p_subpic;
-
- int i_pass;
-
/* Get lock */
vlc_mutex_lock( &p_spu->subpicture_lock );
- /* Be sure we have at least 1 picture to process */
- if( !p_subpic_list || p_subpic_list->i_status == FREE_SUBPICTURE )
- {
- vlc_mutex_unlock( &p_spu->subpicture_lock );
- return;
- }
-
- /* */
+ /* Preprocess subpictures */
+ i_subpicture = 0;
i_subtitle_region_count = 0;
- for( p_subpic = p_subpic_list;
+ for( subpicture_t * p_subpic = p_subpic_list;
p_subpic != NULL && p_subpic->i_status != FREE_SUBPICTURE; /* Check again status (as we where unlocked) */
p_subpic = p_subpic->p_next )
{
@@ -1184,8 +1209,22 @@ void spu_RenderSubpictures( spu_t *p_spu,
for( subpicture_region_t *r = p_subpic->p_region; r != NULL; r = r->p_next )
i_subtitle_region_count++;
}
+
+ /* */
+ pp_subpicture[i_subpicture++] = p_subpic;
}
+ /* Be sure we have at least 1 picture to process */
+ if( i_subpicture <= 0 )
+ {
+ vlc_mutex_unlock( &p_spu->subpicture_lock );
+ return;
+ }
+
+ /* Now order subpicture array
+ * XXX The order is *really* important for overlap subtitles positionning */
+ qsort( pp_subpicture, i_subpicture, sizeof(*pp_subpicture), SubpictureCmp );
+
/* Allocate area array for subtitle overlap */
i_subtitle_area = 0;
p_subtitle_area = p_subtitle_area_buffer;
@@ -1196,30 +1235,12 @@ void spu_RenderSubpictures( spu_t *p_spu,
if( !p_spu->p_blend )
SpuRenderCreateBlend( p_spu, p_fmt_dst->i_chroma, p_fmt_dst->i_aspect );
-
- /* Process all subpictures and regions
- * We do two pass:
- * 1. all absolute pictures
- * 2. not yet absolute subtitle pictures
- * The order is important to correctly move the non absolute picture.
- */
- for( i_pass = 0, p_subpic = p_subpic_list; ; p_subpic = p_subpic->p_next )
+ /* Process all subpictures and regions (in the right order) */
+ for( unsigned int i_index = 0; i_index < i_subpicture; i_index++ )
{
+ subpicture_t *p_subpic = pp_subpicture[i_index];
subpicture_region_t *p_region;
- if( !p_subpic || p_subpic->i_status == FREE_SUBPICTURE )
- {
- i_pass++;
- if( i_pass >= 2 )
- break;
- p_subpic = p_subpic_list;
- assert( p_subpic && p_subpic->i_status != FREE_SUBPICTURE );
- }
-
- if( ( i_pass == 0 && !p_subpic->b_absolute ) ||
- ( i_pass == 1 && p_subpic->b_absolute ) )
- continue;
-
if( !p_subpic->p_region )
continue;
More information about the vlc-devel
mailing list