Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
692cad3b
Commit
692cad3b
authored
Sep 19, 2008
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Render subpictures in the right order to improve overlap support.
parent
aef00257
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
67 additions
and
44 deletions
+67
-44
include/vlc_osd.h
include/vlc_osd.h
+1
-0
include/vlc_vout.h
include/vlc_vout.h
+1
-0
src/video_output/vout_subpictures.c
src/video_output/vout_subpictures.c
+65
-44
No files found.
include/vlc_osd.h
View file @
692cad3b
...
@@ -64,6 +64,7 @@ struct spu_t
...
@@ -64,6 +64,7 @@ struct spu_t
vlc_mutex_t
subpicture_lock
;
/**< subpicture heap lock */
vlc_mutex_t
subpicture_lock
;
/**< subpicture heap lock */
subpicture_t
p_subpicture
[
VOUT_MAX_SUBPICTURES
];
/**< subpictures */
subpicture_t
p_subpicture
[
VOUT_MAX_SUBPICTURES
];
/**< subpictures */
int
i_channel
;
/**< number of subpicture channels registered */
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_blend
;
/**< alpha blending module */
filter_t
*
p_text
;
/**< text renderer module */
filter_t
*
p_text
;
/**< text renderer module */
...
...
include/vlc_vout.h
View file @
692cad3b
...
@@ -332,6 +332,7 @@ struct subpicture_t
...
@@ -332,6 +332,7 @@ struct subpicture_t
/** \name Type and flags
/** \name Type and flags
Should NOT be modified except by the vout thread */
Should NOT be modified except by the vout thread */
/**@{*/
/**@{*/
int64_t
i_order
;
/** an increasing unique number */
int
i_type
;
/**< type */
int
i_type
;
/**< type */
int
i_status
;
/**< flags */
int
i_status
;
/**< flags */
subpicture_t
*
p_next
;
/**< next subtitle to be displayed */
subpicture_t
*
p_next
;
/**< next subtitle to be displayed */
...
...
src/video_output/vout_subpictures.c
View file @
692cad3b
...
@@ -85,7 +85,8 @@ spu_t *__spu_Create( vlc_object_t *p_this )
...
@@ -85,7 +85,8 @@ spu_t *__spu_Create( vlc_object_t *p_this )
int
i_index
;
int
i_index
;
spu_t
*
p_spu
=
vlc_custom_create
(
p_this
,
sizeof
(
spu_t
),
spu_t
*
p_spu
=
vlc_custom_create
(
p_this
,
sizeof
(
spu_t
),
VLC_OBJECT_GENERIC
,
"subpicture"
);
VLC_OBJECT_GENERIC
,
"subpicture"
);
/* */
p_spu
->
i_subpicture_order
=
1
;
for
(
i_index
=
0
;
i_index
<
VOUT_MAX_SUBPICTURES
;
i_index
++
)
for
(
i_index
=
0
;
i_index
<
VOUT_MAX_SUBPICTURES
;
i_index
++
)
{
{
p_spu
->
p_subpicture
[
i_index
].
i_status
=
FREE_SUBPICTURE
;
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 )
...
@@ -312,15 +313,15 @@ void spu_DisplaySubpicture( spu_t *p_spu, subpicture_t *p_subpic )
p_subpic
,
p_subpic
->
i_status
);
p_subpic
,
p_subpic
->
i_status
);
}
}
/* Remove reservation flag */
p_subpic
->
i_status
=
READY_SUBPICTURE
;
if
(
p_subpic
->
i_channel
==
DEFAULT_CHAN
)
if
(
p_subpic
->
i_channel
==
DEFAULT_CHAN
)
{
{
p_subpic
->
i_channel
=
0xFFFF
;
p_subpic
->
i_channel
=
0xFFFF
;
spu_Control
(
p_spu
,
SPU_CHANNEL_CLEAR
,
DEFAULT_CHAN
);
spu_Control
(
p_spu
,
SPU_CHANNEL_CLEAR
,
DEFAULT_CHAN
);
p_subpic
->
i_channel
=
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 )
...
@@ -366,6 +367,7 @@ subpicture_t *spu_CreateSubpicture( spu_t *p_spu )
/* Copy subpicture information, set some default values */
/* Copy subpicture information, set some default values */
memset
(
p_subpic
,
0
,
sizeof
(
subpicture_t
)
);
memset
(
p_subpic
,
0
,
sizeof
(
subpicture_t
)
);
p_subpic
->
i_order
=
p_spu
->
i_subpicture_order
++
;
p_subpic
->
i_status
=
RESERVED_SUBPICTURE
;
p_subpic
->
i_status
=
RESERVED_SUBPICTURE
;
p_subpic
->
b_absolute
=
true
;
p_subpic
->
b_absolute
=
true
;
p_subpic
->
b_fade
=
false
;
p_subpic
->
b_fade
=
false
;
...
@@ -1002,10 +1004,6 @@ static void SpuRenderRegion( spu_t *p_spu,
...
@@ -1002,10 +1004,6 @@ static void SpuRenderRegion( spu_t *p_spu,
p_scale
->
fmt_in
.
video
=
p_region
->
fmt
;
p_scale
->
fmt_in
.
video
=
p_region
->
fmt
;
p_scale
->
fmt_out
.
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_width
=
i_dst_width
;
p_scale
->
fmt_out
.
video
.
i_height
=
i_dst_height
;
p_scale
->
fmt_out
.
video
.
i_height
=
i_dst_height
;
...
@@ -1026,10 +1024,12 @@ static void SpuRenderRegion( spu_t *p_spu,
...
@@ -1026,10 +1024,12 @@ static void SpuRenderRegion( spu_t *p_spu,
}
}
if
(
p_pic
)
if
(
p_pic
)
{
{
picture_Copy
(
&
p_region
->
p_cache
->
picture
,
p_pic
);
picture_Copy
Pixels
(
&
p_region
->
p_cache
->
picture
,
p_pic
);
picture_Release
(
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
/* i_x/i_y of cached region should NOT be used. I set them to
* an invalid value to catch it (assert) */
* an invalid value to catch it (assert) */
p_region
->
p_cache
->
i_x
=
INT_MAX
;
p_region
->
p_cache
->
i_x
=
INT_MAX
;
...
@@ -1126,6 +1126,38 @@ exit:
...
@@ -1126,6 +1126,38 @@ exit:
p_region
->
fmt
=
fmt_original
;
p_region
->
fmt
=
fmt_original
;
}
}
/**
* 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.
* This function renders all sub picture units in the list.
*/
*/
...
@@ -1138,28 +1170,21 @@ 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
int
i_source_video_height
=
p_fmt_src
->
i_height
;
const
mtime_t
i_current_date
=
mdate
();
const
mtime_t
i_current_date
=
mdate
();
unsigned
int
i_subpicture
;
subpicture_t
*
pp_subpicture
[
VOUT_MAX_SUBPICTURES
];
unsigned
int
i_subtitle_region_count
;
unsigned
int
i_subtitle_region_count
;
spu_area_t
p_subtitle_area_buffer
[
VOUT_MAX_SUBPICTURES
];
spu_area_t
p_subtitle_area_buffer
[
VOUT_MAX_SUBPICTURES
];
spu_area_t
*
p_subtitle_area
;
spu_area_t
*
p_subtitle_area
;
int
i_subtitle_area
;
int
i_subtitle_area
;
subpicture_t
*
p_subpic
;
int
i_pass
;
/* Get lock */
/* Get lock */
vlc_mutex_lock
(
&
p_spu
->
subpicture_lock
);
vlc_mutex_lock
(
&
p_spu
->
subpicture_lock
);
/* Be sure we have at least 1 picture to process */
/* Preprocess subpictures */
if
(
!
p_subpic_list
||
p_subpic_list
->
i_status
==
FREE_SUBPICTURE
)
i_subpicture
=
0
;
{
vlc_mutex_unlock
(
&
p_spu
->
subpicture_lock
);
return
;
}
/* */
i_subtitle_region_count
=
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
!=
NULL
&&
p_subpic
->
i_status
!=
FREE_SUBPICTURE
;
/* Check again status (as we where unlocked) */
p_subpic
=
p_subpic
->
p_next
)
p_subpic
=
p_subpic
->
p_next
)
{
{
...
@@ -1184,8 +1209,22 @@ void spu_RenderSubpictures( spu_t *p_spu,
...
@@ -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
)
for
(
subpicture_region_t
*
r
=
p_subpic
->
p_region
;
r
!=
NULL
;
r
=
r
->
p_next
)
i_subtitle_region_count
++
;
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 */
/* Allocate area array for subtitle overlap */
i_subtitle_area
=
0
;
i_subtitle_area
=
0
;
p_subtitle_area
=
p_subtitle_area_buffer
;
p_subtitle_area
=
p_subtitle_area_buffer
;
...
@@ -1196,30 +1235,12 @@ void spu_RenderSubpictures( spu_t *p_spu,
...
@@ -1196,30 +1235,12 @@ void spu_RenderSubpictures( spu_t *p_spu,
if
(
!
p_spu
->
p_blend
)
if
(
!
p_spu
->
p_blend
)
SpuRenderCreateBlend
(
p_spu
,
p_fmt_dst
->
i_chroma
,
p_fmt_dst
->
i_aspect
);
SpuRenderCreateBlend
(
p_spu
,
p_fmt_dst
->
i_chroma
,
p_fmt_dst
->
i_aspect
);
/* Process all subpictures and regions (in the right order) */
/* Process all subpictures and regions
for
(
unsigned
int
i_index
=
0
;
i_index
<
i_subpicture
;
i_index
++
)
* 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
)
{
{
subpicture_t
*
p_subpic
=
pp_subpicture
[
i_index
];
subpicture_region_t
*
p_region
;
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
)
if
(
!
p_subpic
->
p_region
)
continue
;
continue
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment