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
08a73f8b
Commit
08a73f8b
authored
Apr 29, 2010
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplify the creation of subpicture with dynamic content.
parent
14054532
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
282 additions
and
190 deletions
+282
-190
include/vlc_codec.h
include/vlc_codec.h
+2
-2
include/vlc_subpicture.h
include/vlc_subpicture.h
+23
-11
modules/codec/avcodec/subtitle.c
modules/codec/avcodec/subtitle.c
+1
-1
modules/codec/cc.c
modules/codec/cc.c
+1
-1
modules/codec/cvdsub.c
modules/codec/cvdsub.c
+1
-1
modules/codec/dvbsub.c
modules/codec/dvbsub.c
+1
-1
modules/codec/kate.c
modules/codec/kate.c
+73
-69
modules/codec/libass.c
modules/codec/libass.c
+85
-66
modules/codec/spudec/parse.c
modules/codec/spudec/parse.c
+1
-1
modules/codec/subtitles/subsdec.c
modules/codec/subtitles/subsdec.c
+1
-1
modules/codec/subtitles/subsusf.c
modules/codec/subtitles/subsusf.c
+1
-1
modules/codec/svcdsub.c
modules/codec/svcdsub.c
+1
-1
modules/codec/telx.c
modules/codec/telx.c
+1
-1
modules/codec/zvbi.c
modules/codec/zvbi.c
+1
-1
modules/stream_out/transcode/spu.c
modules/stream_out/transcode/spu.c
+3
-2
src/input/decoder.c
src/input/decoder.c
+8
-5
src/osd/osd_text.c
src/osd/osd_text.c
+1
-1
src/osd/osd_widgets.c
src/osd/osd_widgets.c
+1
-1
src/video_output/video_epg.c
src/video_output/video_epg.c
+1
-1
src/video_output/video_text.c
src/video_output/video_text.c
+1
-1
src/video_output/vout_subpictures.c
src/video_output/vout_subpictures.c
+74
-21
No files found.
include/vlc_codec.h
View file @
08a73f8b
...
...
@@ -109,7 +109,7 @@ struct decoder_t
/* SPU output callbacks
* XXX use decoder_NewSubpicture and decoder_DeleteSubpicture */
subpicture_t
*
(
*
pf_spu_buffer_new
)(
decoder_t
*
);
subpicture_t
*
(
*
pf_spu_buffer_new
)(
decoder_t
*
,
const
subpicture_updater_t
*
);
void
(
*
pf_spu_buffer_del
)(
decoder_t
*
,
subpicture_t
*
);
/* Input attachments
...
...
@@ -216,7 +216,7 @@ VLC_EXPORT( void, decoder_DeleteAudioBuffer, ( decoder_t *, aout_buffer_t *p_buf
* buffer. You have to release it using decoder_DeleteSubpicture or by returning
* it to the caller as a pf_decode_sub return value.
*/
VLC_EXPORT
(
subpicture_t
*
,
decoder_NewSubpicture
,
(
decoder_t
*
)
LIBVLC_USED
);
VLC_EXPORT
(
subpicture_t
*
,
decoder_NewSubpicture
,
(
decoder_t
*
,
const
subpicture_updater_t
*
)
LIBVLC_USED
);
/**
* This function will release a subpicture created by decoder_NewSubicture.
...
...
include/vlc_subpicture.h
View file @
08a73f8b
...
...
@@ -102,6 +102,26 @@ VLC_EXPORT( void, subpicture_region_Delete, ( subpicture_region_t *p_region ) );
*/
VLC_EXPORT
(
void
,
subpicture_region_ChainDelete
,
(
subpicture_region_t
*
p_head
)
);
/**
*
*/
typedef
struct
subpicture_updater_sys_t
subpicture_updater_sys_t
;
typedef
struct
{
int
(
*
pf_validate
)(
subpicture_t
*
,
bool
has_src_changed
,
const
video_format_t
*
p_fmt_src
,
bool
has_dst_changed
,
const
video_format_t
*
p_fmt_dst
,
mtime_t
);
void
(
*
pf_update
)
(
subpicture_t
*
,
const
video_format_t
*
p_fmt_src
,
const
video_format_t
*
p_fmt_dst
,
mtime_t
);
void
(
*
pf_destroy
)
(
subpicture_t
*
);
subpicture_updater_sys_t
*
p_sys
;
}
subpicture_updater_t
;
typedef
struct
subpicture_private_t
subpicture_private_t
;
/**
* Video subtitle
*
...
...
@@ -147,25 +167,17 @@ struct subpicture_t
int
i_alpha
;
/**< transparency */
/**@}*/
/** Pointer to function that cleans up the private data of this subtitle */
void
(
*
pf_destroy
)
(
subpicture_t
*
);
/** Pointer to function that update the regions before rendering (optionnal) */
void
(
*
pf_update_regions
)(
spu_t
*
,
subpicture_t
*
,
const
video_format_t
*
,
mtime_t
);
subpicture_updater_t
updater
;
/** Private data - the subtitle plugin might want to put stuff here to
* keep track of the subpicture */
subpicture_sys_t
*
p_sys
;
/* subpicture data */
subpicture_private_t
*
p_private
;
/* Reserved to the core */
};
/**
* This function create a new empty subpicture.
*
* You must use subpicture_Delete to destroy it.
*/
VLC_EXPORT
(
subpicture_t
*
,
subpicture_New
,
(
void
)
);
VLC_EXPORT
(
subpicture_t
*
,
subpicture_New
,
(
const
subpicture_updater_t
*
)
);
/**
* This function delete a subpicture created by subpicture_New.
...
...
modules/codec/avcodec/subtitle.c
View file @
08a73f8b
...
...
@@ -239,7 +239,7 @@ static subpicture_region_t *ConvertRegionRGBA(AVSubtitleRect *ffregion)
*/
static
subpicture_t
*
ConvertSubtitle
(
decoder_t
*
dec
,
AVSubtitle
*
ffsub
,
mtime_t
pts
)
{
subpicture_t
*
spu
=
decoder_NewSubpicture
(
dec
);
subpicture_t
*
spu
=
decoder_NewSubpicture
(
dec
,
NULL
);
if
(
!
spu
)
return
NULL
;
...
...
modules/codec/cc.c
View file @
08a73f8b
...
...
@@ -327,7 +327,7 @@ static subpicture_t *Subtitle( decoder_t *p_dec, char *psz_subtitle, char *psz_h
EnsureUTF8
(
psz_html
);
/* Create the subpicture unit */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
{
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
...
...
modules/codec/cvdsub.c
View file @
08a73f8b
...
...
@@ -500,7 +500,7 @@ static subpicture_t *DecodePacket( decoder_t *p_dec, block_t *p_data )
int
i
;
/* Allocate the subpicture internal data. */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
return
NULL
;
p_spu
->
i_start
=
p_data
->
i_pts
;
...
...
modules/codec/dvbsub.c
View file @
08a73f8b
...
...
@@ -1477,7 +1477,7 @@ static subpicture_t *render( decoder_t *p_dec )
int
i_base_y
;
/* Allocate the subpicture internal data. */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
return
NULL
;
...
...
modules/codec/kate.c
View file @
08a73f8b
...
...
@@ -116,7 +116,7 @@ struct decoder_sys_t
bool
b_use_tiger
;
};
struct
subpicture_sys_t
struct
subpicture_
updater_
sys_t
{
decoder_sys_t
*
p_dec_sys
;
mtime_t
i_start
;
...
...
@@ -764,18 +764,9 @@ static void SetupText( decoder_t *p_dec, subpicture_t *p_spu, const kate_event *
static
void
TigerDestroySubpicture
(
subpicture_t
*
p_subpic
)
{
DecSysRelease
(
p_subpic
->
p_sys
->
p_dec_sys
);
DecSysRelease
(
p_subpic
->
updater
.
p_sys
->
p_dec_sys
);
free
(
p_subpic
->
updater
.
p_sys
);
}
static
void
SubpictureReleaseRegions
(
subpicture_t
*
p_subpic
)
{
if
(
p_subpic
->
p_region
)
{
subpicture_region_ChainDelete
(
p_subpic
->
p_region
);
p_subpic
->
p_region
=
NULL
;
}
}
/*
* We get premultiplied alpha, but VLC doesn't expect this, so we demultiply
* alpha to avoid double multiply (and thus thinner text than we should)).
...
...
@@ -827,66 +818,76 @@ static void PostprocessTigerImage( plane_t *p_plane, unsigned int i_width )
PROFILE_STOP
(
tiger_renderer_postprocess
);
}
/* Tiger renders can end up looking a bit crap since they get overlaid on top of
a subsampled YUV image, so there can be a fair amount of chroma bleeding.
Looks good with white though since it's all luma. Hopefully that will be the
common case. */
static
void
TigerUpdateRegions
(
spu_t
*
p_spu
,
subpicture_t
*
p_subpic
,
const
video_format_t
*
p_fmt
,
mtime_t
ts
)
static
int
TigerValidateSubpicture
(
subpicture_t
*
p_subpic
,
bool
b_fmt_src
,
const
video_format_t
*
p_fmt_src
,
bool
b_fmt_dst
,
const
video_format_t
*
p_fmt_dst
,
mtime_t
ts
)
{
decoder_sys_t
*
p_sys
=
p_subpic
->
p_sys
->
p_dec_sys
;
subpicture_region_t
*
p_r
;
video_format_t
fmt
;
plane_t
*
p_plane
;
kate_float
t
;
int
i_ret
;
decoder_sys_t
*
p_sys
=
p_subpic
->
updater
.
p_sys
->
p_dec_sys
;
VLC_UNUSED
(
p_spu
);
if
(
b_fmt_src
||
b_fmt_dst
)
return
VLC_EGENERIC
;
PROFILE_START
(
Tiger
UpdateRegions
);
PROFILE_START
(
Tiger
ValidateSubpicture
);
/* time in seconds from the start of the stream */
t
=
(
p_subpic
->
p_sys
->
i_start
+
ts
-
p_subpic
->
i_start
)
/
1000000
.
0
f
;
kate_float
t
=
(
p_subpic
->
updater
.
p_sys
->
i_start
+
ts
-
p_subpic
->
i_start
)
/
1000000
.
0
f
;
/* it is likely that the current region (if any) can be kept as is; test for this */
vlc_mutex_lock
(
&
p_sys
->
lock
);
if
(
p_subpic
->
p_region
&&
!
p_sys
->
b_dirty
&&
!
tiger_renderer_is_dirty
(
p_sys
->
p_tr
))
int
i_ret
;
if
(
p_sys
->
b_dirty
||
tiger_renderer_is_dirty
(
p_sys
->
p_tr
)
)
{
PROFILE_START
(
tiger_renderer_update1
);
i_ret
=
tiger_renderer_update
(
p_sys
->
p_tr
,
t
,
1
);
PROFILE_STOP
(
tiger_renderer_update1
);
if
(
i_ret
<
0
)
{
SubpictureReleaseRegions
(
p_subpic
);
vlc_mutex_unlock
(
&
p_sys
->
lock
);
return
;
}
if
(
!
tiger_renderer_is_dirty
(
p_sys
->
p_tr
)
)
{
/* we can keep the current region list */
PROFILE_STOP
(
TigerUpdateRegions
);
vlc_mutex_unlock
(
&
p_sys
->
lock
);
return
;
}
i_ret
=
VLC_EGENERIC
;
goto
exit
;
}
if
(
tiger_renderer_update
(
p_sys
->
p_tr
,
t
,
1
)
>=
0
&&
tiger_renderer_is_dirty
(
p_sys
->
p_tr
)
)
{
i_ret
=
VLC_EGENERIC
;
goto
exit
;
}
i_ret
=
VLC_SUCCESS
;
exit:
vlc_mutex_unlock
(
&
p_sys
->
lock
);
PROFILE_STOP
(
TigerValidateSubpicture
);
return
i_ret
;
}
/* Tiger renders can end up looking a bit crap since they get overlaid on top of
a subsampled YUV image, so there can be a fair amount of chroma bleeding.
Looks good with white though since it's all luma. Hopefully that will be the
common case. */
static
void
TigerUpdateSubpicture
(
subpicture_t
*
p_subpic
,
const
video_format_t
*
p_fmt_src
,
const
video_format_t
*
p_fmt_dst
,
mtime_t
ts
)
{
decoder_sys_t
*
p_sys
=
p_subpic
->
updater
.
p_sys
->
p_dec_sys
;
plane_t
*
p_plane
;
kate_float
t
;
int
i_ret
;
/* we have to render again, reset current region list */
SubpictureReleaseRegions
(
p_subpic
);
/* time in seconds from the start of the stream */
t
=
(
p_subpic
->
updater
.
p_sys
->
i_start
+
ts
-
p_subpic
->
i_start
)
/
1000000
.
0
f
;
PROFILE_START
(
TigerUpdateSubpicture
);
/* create a full frame region - this will also tell Tiger the size of the frame */
fmt
=
*
p_fmt
;
fmt
.
i_chroma
=
VLC_CODEC_RGBA
;
fmt
.
i_width
=
fmt
.
i_visible_width
;
fmt
.
i_height
=
fmt
.
i_visible_height
;
video_format_t
fmt
=
*
p_fmt_dst
;
fmt
.
i_chroma
=
VLC_CODEC_RGBA
;
fmt
.
i_bits_per_pixel
=
0
;
fmt
.
i_x_offset
=
fmt
.
i_y_offset
=
0
;
fmt
.
i_width
=
fmt
.
i_visible_width
=
p_fmt_src
->
i_width
;
fmt
.
i_height
=
fmt
.
i_visible_height
=
p_fmt_src
->
i_height
;
fmt
.
i_x_offset
=
fmt
.
i_y_offset
=
0
;
p_r
=
subpicture_region_New
(
&
fmt
);
subpicture_region_t
*
p_r
=
subpicture_region_New
(
&
fmt
);
if
(
!
p_r
)
{
return
;
}
p_r
->
i_x
=
0
;
p_r
->
i_y
=
0
;
...
...
@@ -921,7 +922,7 @@ static void TigerUpdateRegions( spu_t *p_spu, subpicture_t *p_subpic, const vide
p_subpic
->
p_region
=
p_r
;
p_sys
->
b_dirty
=
false
;
PROFILE_STOP
(
TigerUpdate
Regions
);
PROFILE_STOP
(
TigerUpdate
Subpicture
);
vlc_mutex_unlock
(
&
p_sys
->
lock
);
...
...
@@ -1174,9 +1175,23 @@ static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp, block_t
/* we have an event */
/* Get a new spu */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
subpicture_updater_sys_t
*
p_spu_sys
=
NULL
;
if
(
p_sys
->
b_use_tiger
)
{
p_spu_sys
=
malloc
(
sizeof
(
*
p_spu_sys
)
);
if
(
!
p_spu_sys
)
return
NULL
;
}
subpicture_updater_t
updater
=
{
.
pf_validate
=
TigerValidateSubpicture
,
.
pf_update
=
TigerUpdateSubpicture
,
.
pf_destroy
=
TigerDestroySubpicture
,
.
p_sys
=
p_spu_sys
,
};
p_spu
=
decoder_NewSubpicture
(
p_dec
,
p_sys
->
b_use_tiger
?
&
updater
:
NULL
);
if
(
!
p_spu
)
{
free
(
p_spu_sys
);
/* this will happen for lyrics as there is no vout - so no error */
/* msg_Err( p_dec, "Failed to allocate spu buffer" ); */
return
NULL
;
...
...
@@ -1190,15 +1205,8 @@ static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp, block_t
#ifdef HAVE_TIGER
if
(
p_sys
->
b_use_tiger
)
{
/* setup the structure to get our decoder struct back */
p_spu
->
p_sys
=
malloc
(
sizeof
(
subpicture_sys_t
));
if
(
!
p_spu
->
p_sys
)
{
decoder_DeleteSubpicture
(
p_dec
,
p_spu
);
return
NULL
;
}
p_spu
->
p_sys
->
p_dec_sys
=
p_sys
;
p_spu
->
p_sys
->
i_start
=
p_block
->
i_pts
;
p_spu_sys
->
p_dec_sys
=
p_sys
;
p_spu_sys
->
i_start
=
p_block
->
i_pts
;
DecSysHold
(
p_sys
);
p_spu
->
i_stop
=
__MAX
(
p_sys
->
i_max_stop
,
p_spu
->
i_stop
);
...
...
@@ -1209,10 +1217,6 @@ static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp, block_t
vlc_mutex_lock
(
&
p_sys
->
lock
);
CHECK_TIGER_RET
(
tiger_renderer_add_event
(
p_sys
->
p_tr
,
ev
->
ki
,
ev
)
);
vlc_mutex_unlock
(
&
p_sys
->
lock
);
/* hookup render/update routines */
p_spu
->
pf_update_regions
=
TigerUpdateRegions
;
p_spu
->
pf_destroy
=
TigerDestroySubpicture
;
}
else
#endif
...
...
modules/codec/libass.c
View file @
08a73f8b
...
...
@@ -74,9 +74,6 @@ vlc_module_end ()
* Local prototypes
*****************************************************************************/
static
subpicture_t
*
DecodeBlock
(
decoder_t
*
,
block_t
**
);
static
void
DestroySubpicture
(
subpicture_t
*
);
static
void
UpdateRegions
(
spu_t
*
,
subpicture_t
*
,
const
video_format_t
*
,
mtime_t
);
/* Yes libass sux with threads */
typedef
struct
...
...
@@ -109,12 +106,25 @@ struct decoder_sys_t
static
void
DecSysRelease
(
decoder_sys_t
*
p_sys
);
static
void
DecSysHold
(
decoder_sys_t
*
p_sys
);
struct
subpicture_sys_t
/* */
static
int
SubpictureValidate
(
subpicture_t
*
,
bool
,
const
video_format_t
*
,
bool
,
const
video_format_t
*
,
mtime_t
);
static
void
SubpictureUpdate
(
subpicture_t
*
,
const
video_format_t
*
,
const
video_format_t
*
,
mtime_t
);
static
void
SubpictureDestroy
(
subpicture_t
*
);
struct
subpicture_updater_sys_t
{
decoder_sys_t
*
p_dec_sys
;
void
*
p_subs_data
;
int
i_subs_len
;
mtime_t
i_pts
;
ASS_Image
*
p_img
;
};
typedef
struct
...
...
@@ -125,8 +135,7 @@ typedef struct
int
y1
;
}
rectangle_t
;
static
int
BuildRegions
(
spu_t
*
p_spu
,
rectangle_t
*
p_region
,
int
i_max_region
,
ASS_Image
*
p_img_list
,
int
i_width
,
int
i_height
);
static
void
SubpictureReleaseRegions
(
spu_t
*
p_spu
,
subpicture_t
*
p_subpic
);
static
int
BuildRegions
(
rectangle_t
*
p_region
,
int
i_max_region
,
ASS_Image
*
p_img_list
,
int
i_width
,
int
i_height
);
static
void
RegionDraw
(
subpicture_region_t
*
p_region
,
ASS_Image
*
p_img
);
static
vlc_mutex_t
libass_lock
=
VLC_STATIC_MUTEX
;
...
...
@@ -246,34 +255,41 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
return
NULL
;
}
p_spu
=
decoder_NewSubpicture
(
p_dec
);
if
(
!
p_spu
)
subpicture_updater_sys_t
*
p_spu_sys
=
malloc
(
sizeof
(
*
p_spu_sys
)
);
if
(
!
p_spu
_sys
)
{
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
block_Release
(
p_block
);
return
NULL
;
}
p_spu
->
p_sys
=
malloc
(
sizeof
(
subpicture_sys_t
));
if
(
!
p_spu
->
p_sys
)
subpicture_updater_t
updater
=
{
.
pf_validate
=
SubpictureValidate
,
.
pf_update
=
SubpictureUpdate
,
.
pf_destroy
=
SubpictureDestroy
,
.
p_sys
=
p_spu_sys
,
};
p_spu
=
decoder_NewSubpicture
(
p_dec
,
&
updater
);
if
(
!
p_spu
)
{
decoder_DeleteSubpicture
(
p_dec
,
p_spu
);
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
free
(
p_spu_sys
);
block_Release
(
p_block
);
return
NULL
;
}
p_spu
->
p_sys
->
i_subs_len
=
p_block
->
i_buffer
;
p_spu
->
p_sys
->
p_subs_data
=
malloc
(
p_block
->
i_buffer
);
if
(
!
p_spu
->
p_sys
->
p_subs_data
)
p_spu_sys
->
p_img
=
NULL
;
p_spu_sys
->
p_dec_sys
=
p_sys
;
p_spu_sys
->
i_subs_len
=
p_block
->
i_buffer
;
p_spu_sys
->
p_subs_data
=
malloc
(
p_block
->
i_buffer
);
p_spu_sys
->
i_pts
=
p_block
->
i_pts
;
if
(
!
p_spu_sys
->
p_subs_data
)
{
free
(
p_spu
->
p_sys
);
decoder_DeleteSubpicture
(
p_dec
,
p_spu
);
block_Release
(
p_block
);
return
NULL
;
}
memcpy
(
p_spu
->
p
_sys
->
p_subs_data
,
p_block
->
p_buffer
,
memcpy
(
p_spu_sys
->
p_subs_data
,
p_block
->
p_buffer
,
p_block
->
i_buffer
);
p_spu
->
p_sys
->
i_pts
=
p_block
->
i_pts
;
p_spu
->
i_start
=
p_block
->
i_pts
;
p_spu
->
i_stop
=
__MAX
(
p_sys
->
i_max_stop
,
p_block
->
i_pts
+
p_block
->
i_length
);
...
...
@@ -285,16 +301,12 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
vlc_mutex_lock
(
&
libass_lock
);
if
(
p_sys
->
p_track
)
{
ass_process_chunk
(
p_sys
->
p_track
,
p_spu
->
p_sys
->
p_subs_data
,
p_spu
->
p
_sys
->
i_subs_len
,
ass_process_chunk
(
p_sys
->
p_track
,
p_spu
_sys
->
p_subs_data
,
p_spu
_sys
->
i_subs_len
,
p_block
->
i_pts
/
1000
,
p_block
->
i_length
/
1000
);
}
vlc_mutex_unlock
(
&
libass_lock
);
p_spu
->
pf_update_regions
=
UpdateRegions
;
p_spu
->
pf_destroy
=
DestroySubpicture
;
p_spu
->
p_sys
->
p_dec_sys
=
p_sys
;
DecSysHold
(
p_sys
);
DecSysHold
(
p_sys
);
/* Keep a reference for the returned subpicture */
block_Release
(
p_block
);
...
...
@@ -304,63 +316,71 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
/****************************************************************************
*
****************************************************************************/
static
void
DestroySubpicture
(
subpicture_t
*
p_subpic
)
static
int
SubpictureValidate
(
subpicture_t
*
p_subpic
,
bool
b_fmt_src
,
const
video_format_t
*
p_fmt_src
,
bool
b_fmt_dst
,
const
video_format_t
*
p_fmt_dst
,
mtime_t
i_ts
)
{
DecSysRelease
(
p_subpic
->
p_sys
->
p_dec_sys
);
free
(
p_subpic
->
p_sys
->
p_subs_data
);
free
(
p_subpic
->
p_sys
);
}
static
void
UpdateRegions
(
spu_t
*
p_spu
,
subpicture_t
*
p_subpic
,
const
video_format_t
*
p_fmt
,
mtime_t
i_ts
)
{
decoder_sys_t
*
p_sys
=
p_subpic
->
p_sys
->
p_dec_sys
;
decoder_sys_t
*
p_sys
=
p_subpic
->
updater
.
p_sys
->
p_dec_sys
;
ass_handle_t
*
p_ass
=
p_sys
->
p_ass
;
video_format_t
fmt
;
bool
b_fmt_changed
;
vlc_mutex_lock
(
&
libass_lock
);
/* */
fmt
=
*
p_fmt
;
fmt
.
i_chroma
=
VLC_CODEC_RGBA
;
fmt
.
i_width
=
fmt
.
i_visible_width
;
fmt
.
i_height
=
fmt
.
i_visible_height
;
/* FIXME why this mix of src/dst */
video_format_t
fmt
=
*
p_fmt_dst
;
fmt
.
i_chroma
=
VLC_CODEC_RGBA
;
fmt
.
i_bits_per_pixel
=
0
;
fmt
.
i_x_offset
=
fmt
.
i_y_offset
=
0
;
b_fmt_changed
=
memcmp
(
&
fmt
,
&
p_ass
->
fmt
,
sizeof
(
fmt
)
)
!=
0
;
if
(
b_fmt_changed
)
fmt
.
i_width
=
fmt
.
i_visible_width
=
p_fmt_src
->
i_width
;
fmt
.
i_height
=
fmt
.
i_visible_height
=
p_fmt_src
->
i_height
;
fmt
.
i_x_offset
=
fmt
.
i_y_offset
=
0
;
if
(
b_fmt_src
||
b_fmt_dst
)
{
ass_set_frame_size
(
p_ass
->
p_renderer
,
fmt
.
i_width
,
fmt
.
i_height
);
#if defined( LIBASS_VERSION ) && LIBASS_VERSION >= 0x00907000
ass_set_aspect_ratio
(
p_ass
->
p_renderer
,
1
.
0
,
1
.
0
);
// TODO ?
ass_set_aspect_ratio
(
p_ass
->
p_renderer
,
1
.
0
,
1
.
0
);
// TODO ?
#else
ass_set_aspect_ratio
(
p_ass
->
p_renderer
,
1
.
0
);
// TODO ?
ass_set_aspect_ratio
(
p_ass
->
p_renderer
,
1
.
0
);
// TODO ?
#endif
p_ass
->
fmt
=
fmt
;
}
/* */
const
mtime_t
i_stream_date
=
p_subpic
->
p_sys
->
i_pts
+
(
i_ts
-
p_subpic
->
i_start
);
const
mtime_t
i_stream_date
=
p_subpic
->
updater
.
p_sys
->
i_pts
+
(
i_ts
-
p_subpic
->
i_start
);
int
i_changed
;
ASS_Image
*
p_img
=
ass_render_frame
(
p_ass
->
p_renderer
,
p_sys
->
p_track
,
i_stream_date
/
1000
,
&
i_changed
);
if
(
!
i_changed
&&
!
b_fmt_
changed
&&
if
(
!
i_changed
&&
!
b_fmt_
src
&&
!
b_fmt_dst
&&
(
p_img
!=
NULL
)
==
(
p_subpic
->
p_region
!=
NULL
)
)
{
vlc_mutex_unlock
(
&
libass_lock
);
return
;
return
VLC_SUCCESS
;
}
p_subpic
->
updater
.
p_sys
->
p_img
=
p_img
;
/* The lock is released by SubpictureUpdate */
return
VLC_EGENERIC
;
}
static
void
SubpictureUpdate
(
subpicture_t
*
p_subpic
,
const
video_format_t
*
p_fmt_src
,
const
video_format_t
*
p_fmt_dst
,
mtime_t
i_ts
)
{
decoder_sys_t
*
p_sys
=
p_subpic
->
updater
.
p_sys
->
p_dec_sys
;
ass_handle_t
*
p_ass
=
p_sys
->
p_ass
;
video_format_t
fmt
=
p_ass
->
fmt
;
ASS_Image
*
p_img
=
p_subpic
->
updater
.
p_sys
->
p_img
;
//vlc_assert_locked( &libass_lock );
/* */
p_subpic
->
i_original_picture_height
=
fmt
.
i_height
;
p_subpic
->
i_original_picture_width
=
fmt
.
i_width
;
SubpictureReleaseRegions
(
p_spu
,
p_subpic
);
/* XXX to improve efficiency we merge regions that are close minimizing
* the lost surface.
...
...
@@ -370,7 +390,7 @@ static void UpdateRegions( spu_t *p_spu, subpicture_t *p_subpic,
*/
const
int
i_max_region
=
4
;
rectangle_t
region
[
i_max_region
];
const
int
i_region
=
BuildRegions
(
p_spu
,
region
,
i_max_region
,
p_img
,
fmt
.
i_width
,
fmt
.
i_height
);
const
int
i_region
=
BuildRegions
(
region
,
i_max_region
,
p_img
,
fmt
.
i_width
,
fmt
.
i_height
);
if
(
i_region
<=
0
)
{
...
...
@@ -409,6 +429,15 @@ static void UpdateRegions( spu_t *p_spu, subpicture_t *p_subpic,
pp_region_last
=
&
r
->
p_next
;
}
vlc_mutex_unlock
(
&
libass_lock
);
}
static
void
SubpictureDestroy
(
subpicture_t
*
p_subpic
)
{
subpicture_updater_sys_t
*
p_sys
=
p_subpic
->
updater
.
p_sys
;
DecSysRelease
(
p_sys
->
p_dec_sys
);
free
(
p_sys
->
p_subs_data
);
free
(
p_sys
);
}
static
rectangle_t
r_create
(
int
x0
,
int
y0
,
int
x1
,
int
y1
)
...
...
@@ -437,13 +466,11 @@ static bool r_overlap( const rectangle_t *a, const rectangle_t *b, int i_dx, int
__MAX
(
a
->
y0
-
i_dy
,
b
->
y0
)
<
__MIN
(
a
->
y1
+
i_dy
,
b
->
y1
);
}
static
int
BuildRegions
(
spu_t
*
p_spu
,
rectangle_t
*
p_region
,
int
i_max_region
,
ASS_Image
*
p_img_list
,
int
i_width
,
int
i_height
)
static
int
BuildRegions
(
rectangle_t
*
p_region
,
int
i_max_region
,
ASS_Image
*
p_img_list
,
int
i_width
,
int
i_height
)
{
ASS_Image
*
p_tmp
;
int
i_count
;
VLC_UNUSED
(
p_spu
);
#ifdef DEBUG_REGION
int64_t
i_ck_start
=
mdate
();
#endif
...
...
@@ -629,14 +656,6 @@ static void RegionDraw( subpicture_region_t *p_region, ASS_Image *p_img )
#endif
}
static
void
SubpictureReleaseRegions
(
spu_t
*
p_spu
,
subpicture_t
*
p_subpic
)
{
VLC_UNUSED
(
p_spu
);
subpicture_region_ChainDelete
(
p_subpic
->
p_region
);
p_subpic
->
p_region
=
NULL
;
}
/* */
static
ass_handle_t
*
AssHandleHold
(
decoder_t
*
p_dec
)
{
...
...
modules/codec/spudec/parse.c
View file @
08a73f8b
...
...
@@ -101,7 +101,7 @@ subpicture_t * ParsePacket( decoder_t *p_dec )
spu_properties_t
spu_properties
;
/* Allocate the subpicture internal data. */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
return
NULL
;
p_spu
->
i_original_picture_width
=
...
...
modules/codec/subtitles/subsdec.c
View file @
08a73f8b
...
...
@@ -495,7 +495,7 @@ static subpicture_t *ParseText( decoder_t *p_dec, block_t *p_block )
}
/* Create the subpicture unit */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
{
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
...
...
modules/codec/subtitles/subsusf.c
View file @
08a73f8b
...
...
@@ -211,7 +211,7 @@ static subpicture_t *ParseText( decoder_t *p_dec, block_t *p_block )
}
/* Create the subpicture unit */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
{
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
...
...
modules/codec/svcdsub.c
View file @
08a73f8b
...
...
@@ -469,7 +469,7 @@ static subpicture_t *DecodePacket( decoder_t *p_dec, block_t *p_data )
int
i
;
/* Allocate the subpicture internal data. */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
return
NULL
;
p_spu
->
i_start
=
p_data
->
i_pts
;
...
...
modules/codec/telx.c
View file @
08a73f8b
...
...
@@ -685,7 +685,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
strcpy
(
p_sys
->
psz_prev_text
,
psz_text
);
/* Create the subpicture unit */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
{
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
...
...
modules/codec/zvbi.c
View file @
08a73f8b
...
...
@@ -455,7 +455,7 @@ static subpicture_t *Subpicture( decoder_t *p_dec, video_format_t *p_fmt,
/* If there is a page or sub to render, then we do that here */
/* Create the subpicture unit */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
{
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
...
...
modules/stream_out/transcode/spu.c
View file @
08a73f8b
...
...
@@ -34,10 +34,11 @@
#include <vlc_osd.h>
#include <assert.h>
static
subpicture_t
*
spu_new_buffer
(
decoder_t
*
p_dec
)
static
subpicture_t
*
spu_new_buffer
(
decoder_t
*
p_dec
,
const
subpicture_updater_t
*
p_upd
)
{
VLC_UNUSED
(
p_dec
);
return
subpicture_New
();
return
subpicture_New
(
p_upd
);
}
static
void
spu_del_buffer
(
decoder_t
*
p_dec
,
subpicture_t
*
p_subpic
)
...
...
src/input/decoder.c
View file @
08a73f8b
...
...
@@ -75,7 +75,7 @@ static void vout_del_buffer( decoder_t *, picture_t * );
static
void
vout_link_picture
(
decoder_t
*
,
picture_t
*
);
static
void
vout_unlink_picture
(
decoder_t
*
,
picture_t
*
);
static
subpicture_t
*
spu_new_buffer
(
decoder_t
*
);
static
subpicture_t
*
spu_new_buffer
(
decoder_t
*
,
const
subpicture_updater_t
*
);
static
void
spu_del_buffer
(
decoder_t
*
,
subpicture_t
*
);
struct
decoder_owner_sys_t
...
...
@@ -213,13 +213,15 @@ void decoder_DeleteAudioBuffer( decoder_t *p_decoder, aout_buffer_t *p_buffer )
p_decoder
->
pf_aout_buffer_del
(
p_decoder
,
p_buffer
);
}
subpicture_t
*
decoder_NewSubpicture
(
decoder_t
*
p_decoder
)
subpicture_t
*
decoder_NewSubpicture
(
decoder_t
*
p_decoder
,
const
subpicture_updater_t
*
p_dyn
)
{
subpicture_t
*
p_subpicture
=
p_decoder
->
pf_spu_buffer_new
(
p_decoder
);
subpicture_t
*
p_subpicture
=
p_decoder
->
pf_spu_buffer_new
(
p_decoder
,
p_dyn
);
if
(
!
p_subpicture
)
msg_Warn
(
p_decoder
,
"can't get output subpicture"
);
return
p_subpicture
;
}
void
decoder_DeleteSubpicture
(
decoder_t
*
p_decoder
,
subpicture_t
*
p_subpicture
)
{
p_decoder
->
pf_spu_buffer_del
(
p_decoder
,
p_subpicture
);
...
...
@@ -2382,7 +2384,8 @@ static void vout_unlink_picture( decoder_t *p_dec, picture_t *p_pic )
vout_ReleasePicture
(
p_dec
->
p_owner
->
p_vout
,
p_pic
);
}
static
subpicture_t
*
spu_new_buffer
(
decoder_t
*
p_dec
)
static
subpicture_t
*
spu_new_buffer
(
decoder_t
*
p_dec
,
const
subpicture_updater_t
*
p_updater
)
{
decoder_owner_sys_t
*
p_owner
=
p_dec
->
p_owner
;
vout_thread_t
*
p_vout
=
NULL
;
...
...
@@ -2421,7 +2424,7 @@ static subpicture_t *spu_new_buffer( decoder_t *p_dec )
p_owner
->
p_spu_vout
=
p_vout
;
}
p_subpic
=
subpicture_New
();
p_subpic
=
subpicture_New
(
p_updater
);
if
(
p_subpic
)
{
p_subpic
->
i_channel
=
p_owner
->
i_spu_channel
;
...
...
src/osd/osd_text.c
View file @
08a73f8b
...
...
@@ -78,7 +78,7 @@ int osd_ShowTextAbsolute( spu_t *p_spu_channel, int i_channel,
if
(
!
psz_string
)
return
VLC_EGENERIC
;
p_spu
=
subpicture_New
();
p_spu
=
subpicture_New
(
NULL
);
if
(
!
p_spu
)
return
VLC_EGENERIC
;
...
...
src/osd/osd_widgets.c
View file @
08a73f8b
...
...
@@ -198,7 +198,7 @@ subpicture_t *osd_CreateWidget( spu_t *p_spu, int i_channel )
VLC_UNUSED
(
p_spu
);
/* Create and initialize a subpicture */
p_subpic
=
subpicture_New
();
p_subpic
=
subpicture_New
(
NULL
);
if
(
p_subpic
==
NULL
)
return
NULL
;
p_subpic
->
i_channel
=
i_channel
;
...
...
src/video_output/video_epg.c
View file @
08a73f8b
...
...
@@ -259,7 +259,7 @@ int vout_OSDEpg( vout_thread_t *p_vout, input_item_t *p_input )
if
(
p_epg
==
NULL
)
return
VLC_EGENERIC
;
p_spu
=
subpicture_New
();
p_spu
=
subpicture_New
(
NULL
);
if
(
!
p_spu
)
{
vlc_epg_Delete
(
p_epg
);
...
...
src/video_output/video_text.c
View file @
08a73f8b
...
...
@@ -78,7 +78,7 @@ int vout_ShowTextAbsolute( vout_thread_t *p_vout, int i_channel,
if
(
!
psz_string
)
return
VLC_EGENERIC
;
p_spu
=
subpicture_New
();
p_spu
=
subpicture_New
(
NULL
);
if
(
!
p_spu
)
return
VLC_EGENERIC
;
...
...
src/video_output/vout_subpictures.c
View file @
08a73f8b
...
...
@@ -142,6 +142,10 @@ static bool spu_area_overlap( spu_area_t, spu_area_t );
#define SCALE_UNIT (1000)
static
void
SubpictureUpdate
(
subpicture_t
*
,
const
video_format_t
*
p_fmt_src
,
const
video_format_t
*
p_fmt_dst
,
mtime_t
i_ts
);
static
void
SubpictureChain
(
subpicture_t
**
pp_head
,
subpicture_t
*
p_subpic
);
static
int
SubpictureCmp
(
const
void
*
s0
,
const
void
*
s1
);
...
...
@@ -387,17 +391,9 @@ void spu_RenderSubpictures( spu_t *p_spu,
p_subpic
!=
NULL
;
p_subpic
=
p_subpic
->
p_next
)
{
if
(
p_subpic
->
pf_update_regions
)
{
video_format_t
fmt_org
=
*
p_fmt_dst
;
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
->
pf_update_regions
(
p_spu
,
p_subpic
,
&
fmt_org
,
p_subpic
->
b_subtitle
?
render_subtitle_date
:
render_osd_date
);
}
SubpictureUpdate
(
p_subpic
,
p_fmt_src
,
p_fmt_dst
,
p_subpic
->
b_subtitle
?
render_subtitle_date
:
render_osd_date
);
/* */
if
(
p_subpic
->
b_subtitle
)
...
...
@@ -702,7 +698,13 @@ void spu_OffsetSubtitleDate( spu_t *p_spu, mtime_t i_duration )
/*****************************************************************************
* subpicture_t allocation
*****************************************************************************/
subpicture_t
*
subpicture_New
(
void
)
struct
subpicture_private_t
{
video_format_t
src
;
video_format_t
dst
;
};
subpicture_t
*
subpicture_New
(
const
subpicture_updater_t
*
p_upd
)
{
subpicture_t
*
p_subpic
=
calloc
(
1
,
sizeof
(
*
p_subpic
)
);
if
(
!
p_subpic
)
...
...
@@ -714,9 +716,30 @@ subpicture_t *subpicture_New( void )
p_subpic
->
b_subtitle
=
false
;
p_subpic
->
i_alpha
=
0xFF
;
p_subpic
->
p_region
=
NULL
;
p_subpic
->
pf_destroy
=
NULL
;
p_subpic
->
p_sys
=
NULL
;
if
(
p_upd
)
{
subpicture_private_t
*
p_private
=
malloc
(
sizeof
(
*
p_private
)
);
if
(
!
p_private
)
{
free
(
p_subpic
);
return
NULL
;
}
video_format_Init
(
&
p_private
->
src
,
0
);
video_format_Init
(
&
p_private
->
dst
,
0
);
p_subpic
->
updater
=
*
p_upd
;
p_subpic
->
p_private
=
p_private
;
}
else
{
p_subpic
->
p_private
=
NULL
;
p_subpic
->
updater
.
pf_validate
=
NULL
;
p_subpic
->
updater
.
pf_update
=
NULL
;
p_subpic
->
updater
.
pf_destroy
=
NULL
;
p_subpic
->
updater
.
p_sys
=
NULL
;
}
return
p_subpic
;
}
...
...
@@ -725,10 +748,10 @@ void subpicture_Delete( subpicture_t *p_subpic )
subpicture_region_ChainDelete
(
p_subpic
->
p_region
);
p_subpic
->
p_region
=
NULL
;
if
(
p_subpic
->
pf_destroy
)
{
p_subpic
->
pf_destroy
(
p_subpic
);
}
if
(
p_subpic
->
updater
.
pf_destroy
)
p_subpic
->
updater
.
pf_destroy
(
p_subpic
);
free
(
p_subpic
->
p_private
);
free
(
p_subpic
);
}
...
...
@@ -762,7 +785,7 @@ subpicture_t *subpicture_NewFromPicture( vlc_object_t *p_obj,
if
(
!
p_pip
)
return
NULL
;
subpicture_t
*
p_subpic
=
subpicture_New
();
subpicture_t
*
p_subpic
=
subpicture_New
(
NULL
);
if
(
!
p_subpic
)
{
picture_Release
(
p_pip
);
...
...
@@ -788,6 +811,36 @@ subpicture_t *subpicture_NewFromPicture( vlc_object_t *p_obj,
return
p_subpic
;
}
static
void
SubpictureUpdate
(
subpicture_t
*
p_subpicture
,
const
video_format_t
*
p_fmt_src
,
const
video_format_t
*
p_fmt_dst
,
mtime_t
i_ts
)
{
subpicture_updater_t
*
p_upd
=
&
p_subpicture
->
updater
;
subpicture_private_t
*
p_private
=
p_subpicture
->
p_private
;
if
(
!
p_upd
->
pf_validate
)
return
;
if
(
!
p_upd
->
pf_validate
(
p_subpicture
,
!
video_format_IsSimilar
(
p_fmt_src
,
&
p_private
->
src
),
p_fmt_src
,
!
video_format_IsSimilar
(
p_fmt_dst
,
&
p_private
->
dst
),
p_fmt_dst
,
i_ts
)
)
return
;
subpicture_region_ChainDelete
(
p_subpicture
->
p_region
);
p_subpicture
->
p_region
=
NULL
;
p_upd
->
pf_update
(
p_subpicture
,
p_fmt_src
,
p_fmt_dst
,
i_ts
);
video_format_Clean
(
&
p_private
->
src
);
video_format_Clean
(
&
p_private
->
dst
);
video_format_Copy
(
&
p_private
->
src
,
p_fmt_src
);
video_format_Copy
(
&
p_private
->
dst
,
p_fmt_dst
);
}
/*****************************************************************************
* subpicture_region_t allocation
*****************************************************************************/
...
...
@@ -1835,7 +1888,7 @@ static subpicture_t *sub_new_buffer( filter_t *p_filter )
{
filter_owner_sys_t
*
p_sys
=
p_filter
->
p_owner
;
subpicture_t
*
p_subpicture
=
subpicture_New
();
subpicture_t
*
p_subpicture
=
subpicture_New
(
NULL
);
if
(
p_subpicture
)
p_subpicture
->
i_channel
=
p_sys
->
i_channel
;
return
p_subpicture
;
...
...
@@ -1849,7 +1902,7 @@ static void sub_del_buffer( filter_t *p_filter, subpicture_t *p_subpic )
static
subpicture_t
*
spu_new_buffer
(
filter_t
*
p_filter
)
{
VLC_UNUSED
(
p_filter
);
return
subpicture_New
();
return
subpicture_New
(
NULL
);
}
static
void
spu_del_buffer
(
filter_t
*
p_filter
,
subpicture_t
*
p_subpic
)
{
...
...
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