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
...
@@ -109,7 +109,7 @@ struct decoder_t
/* SPU output callbacks
/* SPU output callbacks
* XXX use decoder_NewSubpicture and decoder_DeleteSubpicture */
* 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
*
);
void
(
*
pf_spu_buffer_del
)(
decoder_t
*
,
subpicture_t
*
);
/* Input attachments
/* Input attachments
...
@@ -216,7 +216,7 @@ VLC_EXPORT( void, decoder_DeleteAudioBuffer, ( decoder_t *, aout_buffer_t *p_buf
...
@@ -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
* buffer. You have to release it using decoder_DeleteSubpicture or by returning
* it to the caller as a pf_decode_sub return value.
* 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.
* 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 ) );
...
@@ -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
)
);
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
* Video subtitle
*
*
...
@@ -147,25 +167,17 @@ struct subpicture_t
...
@@ -147,25 +167,17 @@ struct subpicture_t
int
i_alpha
;
/**< transparency */
int
i_alpha
;
/**< transparency */
/**@}*/
/**@}*/
/** Pointer to function that cleans up the private data of this subtitle */
subpicture_updater_t
updater
;
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
);
/** Private data - the subtitle plugin might want to put stuff here to
subpicture_private_t
*
p_private
;
/* Reserved to the core */
* keep track of the subpicture */
subpicture_sys_t
*
p_sys
;
/* subpicture data */
};
};
/**
/**
* This function create a new empty subpicture.
* This function create a new empty subpicture.
*
*
* You must use subpicture_Delete to destroy it.
* 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.
* 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)
...
@@ -239,7 +239,7 @@ static subpicture_region_t *ConvertRegionRGBA(AVSubtitleRect *ffregion)
*/
*/
static
subpicture_t
*
ConvertSubtitle
(
decoder_t
*
dec
,
AVSubtitle
*
ffsub
,
mtime_t
pts
)
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
)
if
(
!
spu
)
return
NULL
;
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
...
@@ -327,7 +327,7 @@ static subpicture_t *Subtitle( decoder_t *p_dec, char *psz_subtitle, char *psz_h
EnsureUTF8
(
psz_html
);
EnsureUTF8
(
psz_html
);
/* Create the subpicture unit */
/* Create the subpicture unit */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
if
(
!
p_spu
)
{
{
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
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 )
...
@@ -500,7 +500,7 @@ static subpicture_t *DecodePacket( decoder_t *p_dec, block_t *p_data )
int
i
;
int
i
;
/* Allocate the subpicture internal data. */
/* Allocate the subpicture internal data. */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
return
NULL
;
if
(
!
p_spu
)
return
NULL
;
p_spu
->
i_start
=
p_data
->
i_pts
;
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 )
...
@@ -1477,7 +1477,7 @@ static subpicture_t *render( decoder_t *p_dec )
int
i_base_y
;
int
i_base_y
;
/* Allocate the subpicture internal data. */
/* Allocate the subpicture internal data. */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
if
(
!
p_spu
)
return
NULL
;
return
NULL
;
...
...
modules/codec/kate.c
View file @
08a73f8b
...
@@ -116,7 +116,7 @@ struct decoder_sys_t
...
@@ -116,7 +116,7 @@ struct decoder_sys_t
bool
b_use_tiger
;
bool
b_use_tiger
;
};
};
struct
subpicture_sys_t
struct
subpicture_
updater_
sys_t
{
{
decoder_sys_t
*
p_dec_sys
;
decoder_sys_t
*
p_dec_sys
;
mtime_t
i_start
;
mtime_t
i_start
;
...
@@ -764,18 +764,9 @@ static void SetupText( decoder_t *p_dec, subpicture_t *p_spu, const kate_event *
...
@@ -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
)
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
* 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)).
* 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 )
...
@@ -827,66 +818,76 @@ static void PostprocessTigerImage( plane_t *p_plane, unsigned int i_width )
PROFILE_STOP
(
tiger_renderer_postprocess
);
PROFILE_STOP
(
tiger_renderer_postprocess
);
}
}
/* Tiger renders can end up looking a bit crap since they get overlaid on top of
static
int
TigerValidateSubpicture
(
subpicture_t
*
p_subpic
,
a subsampled YUV image, so there can be a fair amount of chroma bleeding.
bool
b_fmt_src
,
const
video_format_t
*
p_fmt_src
,
Looks good with white though since it's all luma. Hopefully that will be the
bool
b_fmt_dst
,
const
video_format_t
*
p_fmt_dst
,
common case. */
mtime_t
ts
)
static
void
TigerUpdateRegions
(
spu_t
*
p_spu
,
subpicture_t
*
p_subpic
,
const
video_format_t
*
p_fmt
,
mtime_t
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
;
subpicture_region_t
*
p_r
;
video_format_t
fmt
;
plane_t
*
p_plane
;
kate_float
t
;
int
i_ret
;
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 */
/* 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 */
/* it is likely that the current region (if any) can be kept as is; test for this */
vlc_mutex_lock
(
&
p_sys
->
lock
);
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
=
VLC_EGENERIC
;
i_ret
=
tiger_renderer_update
(
p_sys
->
p_tr
,
t
,
1
);
goto
exit
;
PROFILE_STOP
(
tiger_renderer_update1
);
}
if
(
i_ret
<
0
)
if
(
tiger_renderer_update
(
p_sys
->
p_tr
,
t
,
1
)
>=
0
&&
{
tiger_renderer_is_dirty
(
p_sys
->
p_tr
)
)
SubpictureReleaseRegions
(
p_subpic
);
{
vlc_mutex_unlock
(
&
p_sys
->
lock
);
i_ret
=
VLC_EGENERIC
;
return
;
goto
exit
;
}
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_SUCCESS
;
exit:
vlc_mutex_unlock
(
&
p_sys
->
lock
);
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 */
/* time in seconds from the start of the stream */
SubpictureReleaseRegions
(
p_subpic
);
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 */
/* create a full frame region - this will also tell Tiger the size of the frame */
fmt
=
*
p_fmt
;
video_format_t
fmt
=
*
p_fmt_dst
;
fmt
.
i_chroma
=
VLC_CODEC_RGBA
;
fmt
.
i_chroma
=
VLC_CODEC_RGBA
;
fmt
.
i_width
=
fmt
.
i_visible_width
;
fmt
.
i_height
=
fmt
.
i_visible_height
;
fmt
.
i_bits_per_pixel
=
0
;
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
)
if
(
!
p_r
)
{
return
;
return
;
}
p_r
->
i_x
=
0
;
p_r
->
i_x
=
0
;
p_r
->
i_y
=
0
;
p_r
->
i_y
=
0
;
...
@@ -921,7 +922,7 @@ static void TigerUpdateRegions( spu_t *p_spu, subpicture_t *p_subpic, const vide
...
@@ -921,7 +922,7 @@ static void TigerUpdateRegions( spu_t *p_spu, subpicture_t *p_subpic, const vide
p_subpic
->
p_region
=
p_r
;
p_subpic
->
p_region
=
p_r
;
p_sys
->
b_dirty
=
false
;
p_sys
->
b_dirty
=
false
;
PROFILE_STOP
(
TigerUpdate
Regions
);
PROFILE_STOP
(
TigerUpdate
Subpicture
);
vlc_mutex_unlock
(
&
p_sys
->
lock
);
vlc_mutex_unlock
(
&
p_sys
->
lock
);
...
@@ -1174,9 +1175,23 @@ static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp, block_t
...
@@ -1174,9 +1175,23 @@ static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp, block_t
/* we have an event */
/* we have an event */
/* Get a new spu */
/* 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
)
if
(
!
p_spu
)
{
{
free
(
p_spu_sys
);
/* this will happen for lyrics as there is no vout - so no error */
/* this will happen for lyrics as there is no vout - so no error */
/* msg_Err( p_dec, "Failed to allocate spu buffer" ); */
/* msg_Err( p_dec, "Failed to allocate spu buffer" ); */
return
NULL
;
return
NULL
;
...
@@ -1190,15 +1205,8 @@ static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp, block_t
...
@@ -1190,15 +1205,8 @@ static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp, block_t
#ifdef HAVE_TIGER
#ifdef HAVE_TIGER
if
(
p_sys
->
b_use_tiger
)
if
(
p_sys
->
b_use_tiger
)
{
{
/* setup the structure to get our decoder struct back */
p_spu_sys
->
p_dec_sys
=
p_sys
;
p_spu
->
p_sys
=
malloc
(
sizeof
(
subpicture_sys_t
));
p_spu_sys
->
i_start
=
p_block
->
i_pts
;
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
;
DecSysHold
(
p_sys
);
DecSysHold
(
p_sys
);
p_spu
->
i_stop
=
__MAX
(
p_sys
->
i_max_stop
,
p_spu
->
i_stop
);
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
...
@@ -1209,10 +1217,6 @@ static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp, block_t
vlc_mutex_lock
(
&
p_sys
->
lock
);
vlc_mutex_lock
(
&
p_sys
->
lock
);
CHECK_TIGER_RET
(
tiger_renderer_add_event
(
p_sys
->
p_tr
,
ev
->
ki
,
ev
)
);
CHECK_TIGER_RET
(
tiger_renderer_add_event
(
p_sys
->
p_tr
,
ev
->
ki
,
ev
)
);
vlc_mutex_unlock
(
&
p_sys
->
lock
);
vlc_mutex_unlock
(
&
p_sys
->
lock
);
/* hookup render/update routines */
p_spu
->
pf_update_regions
=
TigerUpdateRegions
;
p_spu
->
pf_destroy
=
TigerDestroySubpicture
;
}
}
else
else
#endif
#endif
...
...
modules/codec/libass.c
View file @
08a73f8b
...
@@ -74,9 +74,6 @@ vlc_module_end ()
...
@@ -74,9 +74,6 @@ vlc_module_end ()
* Local prototypes
* Local prototypes
*****************************************************************************/
*****************************************************************************/
static
subpicture_t
*
DecodeBlock
(
decoder_t
*
,
block_t
**
);
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 */
/* Yes libass sux with threads */
typedef
struct
typedef
struct
...
@@ -109,12 +106,25 @@ struct decoder_sys_t
...
@@ -109,12 +106,25 @@ struct decoder_sys_t
static
void
DecSysRelease
(
decoder_sys_t
*
p_sys
);
static
void
DecSysRelease
(
decoder_sys_t
*
p_sys
);
static
void
DecSysHold
(
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
;
decoder_sys_t
*
p_dec_sys
;
void
*
p_subs_data
;
void
*
p_subs_data
;
int
i_subs_len
;
int
i_subs_len
;
mtime_t
i_pts
;
mtime_t
i_pts
;
ASS_Image
*
p_img
;
};
};
typedef
struct
typedef
struct
...
@@ -125,8 +135,7 @@ typedef struct
...
@@ -125,8 +135,7 @@ typedef struct
int
y1
;
int
y1
;
}
rectangle_t
;
}
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
int
BuildRegions
(
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
void
RegionDraw
(
subpicture_region_t
*
p_region
,
ASS_Image
*
p_img
);
static
void
RegionDraw
(
subpicture_region_t
*
p_region
,
ASS_Image
*
p_img
);
static
vlc_mutex_t
libass_lock
=
VLC_STATIC_MUTEX
;
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 )
...
@@ -246,34 +255,41 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
return
NULL
;
return
NULL
;
}
}
p_spu
=
decoder_NewSubpicture
(
p_dec
);
subpicture_updater_sys_t
*
p_spu_sys
=
malloc
(
sizeof
(
*
p_spu_sys
)
);
if
(
!
p_spu
)
if
(
!
p_spu
_sys
)
{
{
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
block_Release
(
p_block
);
block_Release
(
p_block
);
return
NULL
;
return
NULL
;
}
}
p_spu
->
p_sys
=
malloc
(
sizeof
(
subpicture_sys_t
));
subpicture_updater_t
updater
=
{
if
(
!
p_spu
->
p_sys
)
.
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
);
block_Release
(
p_block
);
return
NULL
;
return
NULL
;
}
}
p_spu
->
p_sys
->
i_subs_len
=
p_block
->
i_buffer
;
p_spu_sys
->
p_img
=
NULL
;
p_spu
->
p_sys
->
p_subs_data
=
malloc
(
p_block
->
i_buffer
);
p_spu_sys
->
p_dec_sys
=
p_sys
;
if
(
!
p_spu
->
p_sys
->
p_subs_data
)
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
);
decoder_DeleteSubpicture
(
p_dec
,
p_spu
);
block_Release
(
p_block
);
block_Release
(
p_block
);
return
NULL
;
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_block
->
i_buffer
);
p_spu
->
p_sys
->
i_pts
=
p_block
->
i_pts
;
p_spu
->
i_start
=
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
);
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 )
...
@@ -285,16 +301,12 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
vlc_mutex_lock
(
&
libass_lock
);
vlc_mutex_lock
(
&
libass_lock
);
if
(
p_sys
->
p_track
)
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
);
p_block
->
i_pts
/
1000
,
p_block
->
i_length
/
1000
);
}
}
vlc_mutex_unlock
(
&
libass_lock
);
vlc_mutex_unlock
(
&
libass_lock
);
p_spu
->
pf_update_regions
=
UpdateRegions
;
DecSysHold
(
p_sys
);
/* Keep a reference for the returned subpicture */
p_spu
->
pf_destroy
=
DestroySubpicture
;
p_spu
->
p_sys
->
p_dec_sys
=
p_sys
;
DecSysHold
(
p_sys
);
block_Release
(
p_block
);
block_Release
(
p_block
);
...
@@ -304,63 +316,71 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_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
);
decoder_sys_t
*
p_sys
=
p_subpic
->
updater
.
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
;
ass_handle_t
*
p_ass
=
p_sys
->
p_ass
;
ass_handle_t
*
p_ass
=
p_sys
->
p_ass
;
video_format_t
fmt
;
bool
b_fmt_changed
;
vlc_mutex_lock
(
&
libass_lock
);
vlc_mutex_lock
(
&
libass_lock
);
/* */
/* FIXME why this mix of src/dst */
fmt
=
*
p_fmt
;
video_format_t
fmt
=
*
p_fmt_dst
;
fmt
.
i_chroma
=
VLC_CODEC_RGBA
;
fmt
.
i_chroma
=
VLC_CODEC_RGBA
;
fmt
.
i_width
=
fmt
.
i_visible_width
;
fmt
.
i_height
=
fmt
.
i_visible_height
;
fmt
.
i_bits_per_pixel
=
0
;
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
;
b_fmt_changed
=
memcmp
(
&
fmt
,
&
p_ass
->
fmt
,
sizeof
(
fmt
)
)
!=
0
;
fmt
.
i_height
=
if
(
b_fmt_changed
)
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
);
ass_set_frame_size
(
p_ass
->
p_renderer
,
fmt
.
i_width
,
fmt
.
i_height
);
#if defined( LIBASS_VERSION ) && LIBASS_VERSION >= 0x00907000
#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
#else
ass_set_aspect_ratio
(
p_ass
->
p_renderer
,
1
.
0
);
// TODO ?
ass_set_aspect_ratio
(
p_ass
->
p_renderer
,
1
.
0
);
// TODO ?
#endif
#endif
p_ass
->
fmt
=
fmt
;
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
;
int
i_changed
;
ASS_Image
*
p_img
=
ass_render_frame
(
p_ass
->
p_renderer
,
p_sys
->
p_track
,
ASS_Image
*
p_img
=
ass_render_frame
(
p_ass
->
p_renderer
,
p_sys
->
p_track
,
i_stream_date
/
1000
,
&
i_changed
);
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
)
)
(
p_img
!=
NULL
)
==
(
p_subpic
->
p_region
!=
NULL
)
)
{
{
vlc_mutex_unlock
(
&
libass_lock
);
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_height
=
fmt
.
i_height
;
p_subpic
->
i_original_picture_width
=
fmt
.
i_width
;
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
/* XXX to improve efficiency we merge regions that are close minimizing
* the lost surface.
* the lost surface.
...
@@ -370,7 +390,7 @@ static void UpdateRegions( spu_t *p_spu, subpicture_t *p_subpic,
...
@@ -370,7 +390,7 @@ static void UpdateRegions( spu_t *p_spu, subpicture_t *p_subpic,
*/
*/
const
int
i_max_region
=
4
;
const
int
i_max_region
=
4
;
rectangle_t
region
[
i_max_region
];
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
)
if
(
i_region
<=
0
)
{
{
...
@@ -409,6 +429,15 @@ static void UpdateRegions( spu_t *p_spu, subpicture_t *p_subpic,
...
@@ -409,6 +429,15 @@ static void UpdateRegions( spu_t *p_spu, subpicture_t *p_subpic,
pp_region_last
=
&
r
->
p_next
;
pp_region_last
=
&
r
->
p_next
;
}
}
vlc_mutex_unlock
(
&
libass_lock
);
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
)
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
...
@@ -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
);
__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
;
ASS_Image
*
p_tmp
;
int
i_count
;
int
i_count
;
VLC_UNUSED
(
p_spu
);
#ifdef DEBUG_REGION
#ifdef DEBUG_REGION
int64_t
i_ck_start
=
mdate
();
int64_t
i_ck_start
=
mdate
();
#endif
#endif
...
@@ -629,14 +656,6 @@ static void RegionDraw( subpicture_region_t *p_region, ASS_Image *p_img )
...
@@ -629,14 +656,6 @@ static void RegionDraw( subpicture_region_t *p_region, ASS_Image *p_img )
#endif
#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
)
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 )
...
@@ -101,7 +101,7 @@ subpicture_t * ParsePacket( decoder_t *p_dec )
spu_properties_t
spu_properties
;
spu_properties_t
spu_properties
;
/* Allocate the subpicture internal data. */
/* Allocate the subpicture internal data. */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
return
NULL
;
if
(
!
p_spu
)
return
NULL
;
p_spu
->
i_original_picture_width
=
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 )
...
@@ -495,7 +495,7 @@ static subpicture_t *ParseText( decoder_t *p_dec, block_t *p_block )
}
}
/* Create the subpicture unit */
/* Create the subpicture unit */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
if
(
!
p_spu
)
{
{
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
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 )
...
@@ -211,7 +211,7 @@ static subpicture_t *ParseText( decoder_t *p_dec, block_t *p_block )
}
}
/* Create the subpicture unit */
/* Create the subpicture unit */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
if
(
!
p_spu
)
{
{
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
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 )
...
@@ -469,7 +469,7 @@ static subpicture_t *DecodePacket( decoder_t *p_dec, block_t *p_data )
int
i
;
int
i
;
/* Allocate the subpicture internal data. */
/* Allocate the subpicture internal data. */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
return
NULL
;
if
(
!
p_spu
)
return
NULL
;
p_spu
->
i_start
=
p_data
->
i_pts
;
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 )
...
@@ -685,7 +685,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
strcpy
(
p_sys
->
psz_prev_text
,
psz_text
);
strcpy
(
p_sys
->
psz_prev_text
,
psz_text
);
/* Create the subpicture unit */
/* Create the subpicture unit */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
if
(
!
p_spu
)
{
{
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
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,
...
@@ -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 */
/* If there is a page or sub to render, then we do that here */
/* Create the subpicture unit */
/* Create the subpicture unit */
p_spu
=
decoder_NewSubpicture
(
p_dec
);
p_spu
=
decoder_NewSubpicture
(
p_dec
,
NULL
);
if
(
!
p_spu
)
if
(
!
p_spu
)
{
{
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
msg_Warn
(
p_dec
,
"can't get spu buffer"
);
...
...
modules/stream_out/transcode/spu.c
View file @
08a73f8b
...
@@ -34,10 +34,11 @@
...
@@ -34,10 +34,11 @@
#include <vlc_osd.h>
#include <vlc_osd.h>
#include <assert.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
);
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
)
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 * );
...
@@ -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_link_picture
(
decoder_t
*
,
picture_t
*
);
static
void
vout_unlink_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
*
);
static
void
spu_del_buffer
(
decoder_t
*
,
subpicture_t
*
);
struct
decoder_owner_sys_t
struct
decoder_owner_sys_t
...
@@ -213,13 +213,15 @@ void decoder_DeleteAudioBuffer( decoder_t *p_decoder, aout_buffer_t *p_buffer )
...
@@ -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
);
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
)
if
(
!
p_subpicture
)
msg_Warn
(
p_decoder
,
"can't get output subpicture"
);
msg_Warn
(
p_decoder
,
"can't get output subpicture"
);
return
p_subpicture
;
return
p_subpicture
;
}
}
void
decoder_DeleteSubpicture
(
decoder_t
*
p_decoder
,
subpicture_t
*
p_subpicture
)
void
decoder_DeleteSubpicture
(
decoder_t
*
p_decoder
,
subpicture_t
*
p_subpicture
)
{
{
p_decoder
->
pf_spu_buffer_del
(
p_decoder
,
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 )
...
@@ -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
);
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
;
decoder_owner_sys_t
*
p_owner
=
p_dec
->
p_owner
;
vout_thread_t
*
p_vout
=
NULL
;
vout_thread_t
*
p_vout
=
NULL
;
...
@@ -2421,7 +2424,7 @@ static subpicture_t *spu_new_buffer( decoder_t *p_dec )
...
@@ -2421,7 +2424,7 @@ static subpicture_t *spu_new_buffer( decoder_t *p_dec )
p_owner
->
p_spu_vout
=
p_vout
;
p_owner
->
p_spu_vout
=
p_vout
;
}
}
p_subpic
=
subpicture_New
();
p_subpic
=
subpicture_New
(
p_updater
);
if
(
p_subpic
)
if
(
p_subpic
)
{
{
p_subpic
->
i_channel
=
p_owner
->
i_spu_channel
;
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,
...
@@ -78,7 +78,7 @@ int osd_ShowTextAbsolute( spu_t *p_spu_channel, int i_channel,
if
(
!
psz_string
)
return
VLC_EGENERIC
;
if
(
!
psz_string
)
return
VLC_EGENERIC
;
p_spu
=
subpicture_New
();
p_spu
=
subpicture_New
(
NULL
);
if
(
!
p_spu
)
if
(
!
p_spu
)
return
VLC_EGENERIC
;
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 )
...
@@ -198,7 +198,7 @@ subpicture_t *osd_CreateWidget( spu_t *p_spu, int i_channel )
VLC_UNUSED
(
p_spu
);
VLC_UNUSED
(
p_spu
);
/* Create and initialize a subpicture */
/* Create and initialize a subpicture */
p_subpic
=
subpicture_New
();
p_subpic
=
subpicture_New
(
NULL
);
if
(
p_subpic
==
NULL
)
return
NULL
;
if
(
p_subpic
==
NULL
)
return
NULL
;
p_subpic
->
i_channel
=
i_channel
;
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 )
...
@@ -259,7 +259,7 @@ int vout_OSDEpg( vout_thread_t *p_vout, input_item_t *p_input )
if
(
p_epg
==
NULL
)
if
(
p_epg
==
NULL
)
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
p_spu
=
subpicture_New
();
p_spu
=
subpicture_New
(
NULL
);
if
(
!
p_spu
)
if
(
!
p_spu
)
{
{
vlc_epg_Delete
(
p_epg
);
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,
...
@@ -78,7 +78,7 @@ int vout_ShowTextAbsolute( vout_thread_t *p_vout, int i_channel,
if
(
!
psz_string
)
return
VLC_EGENERIC
;
if
(
!
psz_string
)
return
VLC_EGENERIC
;
p_spu
=
subpicture_New
();
p_spu
=
subpicture_New
(
NULL
);
if
(
!
p_spu
)
if
(
!
p_spu
)
return
VLC_EGENERIC
;
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 );
...
@@ -142,6 +142,10 @@ static bool spu_area_overlap( spu_area_t, spu_area_t );
#define SCALE_UNIT (1000)
#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
void
SubpictureChain
(
subpicture_t
**
pp_head
,
subpicture_t
*
p_subpic
);
static
int
SubpictureCmp
(
const
void
*
s0
,
const
void
*
s1
);
static
int
SubpictureCmp
(
const
void
*
s0
,
const
void
*
s1
);
...
@@ -387,17 +391,9 @@ void spu_RenderSubpictures( spu_t *p_spu,
...
@@ -387,17 +391,9 @@ void spu_RenderSubpictures( spu_t *p_spu,
p_subpic
!=
NULL
;
p_subpic
!=
NULL
;
p_subpic
=
p_subpic
->
p_next
)
p_subpic
=
p_subpic
->
p_next
)
{
{
if
(
p_subpic
->
pf_update_regions
)
SubpictureUpdate
(
p_subpic
,
{
p_fmt_src
,
p_fmt_dst
,
video_format_t
fmt_org
=
*
p_fmt_dst
;
p_subpic
->
b_subtitle
?
render_subtitle_date
:
render_osd_date
);
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
);
}
/* */
/* */
if
(
p_subpic
->
b_subtitle
)
if
(
p_subpic
->
b_subtitle
)
...
@@ -702,7 +698,13 @@ void spu_OffsetSubtitleDate( spu_t *p_spu, mtime_t i_duration )
...
@@ -702,7 +698,13 @@ void spu_OffsetSubtitleDate( spu_t *p_spu, mtime_t i_duration )
/*****************************************************************************
/*****************************************************************************
* subpicture_t allocation
* 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
)
);
subpicture_t
*
p_subpic
=
calloc
(
1
,
sizeof
(
*
p_subpic
)
);
if
(
!
p_subpic
)
if
(
!
p_subpic
)
...
@@ -714,9 +716,30 @@ subpicture_t *subpicture_New( void )
...
@@ -714,9 +716,30 @@ subpicture_t *subpicture_New( void )
p_subpic
->
b_subtitle
=
false
;
p_subpic
->
b_subtitle
=
false
;
p_subpic
->
i_alpha
=
0xFF
;
p_subpic
->
i_alpha
=
0xFF
;
p_subpic
->
p_region
=
NULL
;
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
;
return
p_subpic
;
}
}
...
@@ -725,10 +748,10 @@ void subpicture_Delete( subpicture_t *p_subpic )
...
@@ -725,10 +748,10 @@ void subpicture_Delete( subpicture_t *p_subpic )
subpicture_region_ChainDelete
(
p_subpic
->
p_region
);
subpicture_region_ChainDelete
(
p_subpic
->
p_region
);
p_subpic
->
p_region
=
NULL
;
p_subpic
->
p_region
=
NULL
;
if
(
p_subpic
->
pf_destroy
)
if
(
p_subpic
->
updater
.
pf_destroy
)
{
p_subpic
->
updater
.
pf_destroy
(
p_subpic
);
p_subpic
->
pf_destroy
(
p_subpic
);
}
free
(
p_subpic
->
p_private
);
free
(
p_subpic
);
free
(
p_subpic
);
}
}
...
@@ -762,7 +785,7 @@ subpicture_t *subpicture_NewFromPicture( vlc_object_t *p_obj,
...
@@ -762,7 +785,7 @@ subpicture_t *subpicture_NewFromPicture( vlc_object_t *p_obj,
if
(
!
p_pip
)
if
(
!
p_pip
)
return
NULL
;
return
NULL
;
subpicture_t
*
p_subpic
=
subpicture_New
();
subpicture_t
*
p_subpic
=
subpicture_New
(
NULL
);
if
(
!
p_subpic
)
if
(
!
p_subpic
)
{
{
picture_Release
(
p_pip
);
picture_Release
(
p_pip
);
...
@@ -788,6 +811,36 @@ subpicture_t *subpicture_NewFromPicture( vlc_object_t *p_obj,
...
@@ -788,6 +811,36 @@ subpicture_t *subpicture_NewFromPicture( vlc_object_t *p_obj,
return
p_subpic
;
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
* subpicture_region_t allocation
*****************************************************************************/
*****************************************************************************/
...
@@ -1835,7 +1888,7 @@ static subpicture_t *sub_new_buffer( filter_t *p_filter )
...
@@ -1835,7 +1888,7 @@ static subpicture_t *sub_new_buffer( filter_t *p_filter )
{
{
filter_owner_sys_t
*
p_sys
=
p_filter
->
p_owner
;
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
)
if
(
p_subpicture
)
p_subpicture
->
i_channel
=
p_sys
->
i_channel
;
p_subpicture
->
i_channel
=
p_sys
->
i_channel
;
return
p_subpicture
;
return
p_subpicture
;
...
@@ -1849,7 +1902,7 @@ static void sub_del_buffer( filter_t *p_filter, subpicture_t *p_subpic )
...
@@ -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
)
static
subpicture_t
*
spu_new_buffer
(
filter_t
*
p_filter
)
{
{
VLC_UNUSED
(
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
)
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