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
6a63bcae
Commit
6a63bcae
authored
Mar 21, 2014
by
Francois Cartegnie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
codec: add tx3g spu
parent
2a60d695
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
538 additions
and
6 deletions
+538
-6
NEWS
NEWS
+1
-0
include/vlc_fourcc.h
include/vlc_fourcc.h
+1
-0
modules/MODULES_LIST
modules/MODULES_LIST
+1
-0
modules/codec/Makefile.am
modules/codec/Makefile.am
+2
-0
modules/codec/substext.h
modules/codec/substext.h
+186
-6
modules/codec/substx3g.c
modules/codec/substx3g.c
+346
-0
po/POTFILES.in
po/POTFILES.in
+1
-0
No files found.
NEWS
View file @
6a63bcae
...
@@ -25,6 +25,7 @@ Decoder:
...
@@ -25,6 +25,7 @@ Decoder:
* OpenMax IL improvements, notably for RaspberryPi
* OpenMax IL improvements, notably for RaspberryPi
* Fix channel ordering of LPCM codec in m2ts files
* Fix channel ordering of LPCM codec in m2ts files
* New jpeg image decoder
* New jpeg image decoder
* Add tx3g subtitles decoder
Encoder:
Encoder:
* Support for MPEG-2 encoding using x262
* Support for MPEG-2 encoding using x262
...
...
include/vlc_fourcc.h
View file @
6a63bcae
...
@@ -416,6 +416,7 @@
...
@@ -416,6 +416,7 @@
#define VLC_CODEC_USF VLC_FOURCC('u','s','f',' ')
#define VLC_CODEC_USF VLC_FOURCC('u','s','f',' ')
#define VLC_CODEC_OGT VLC_FOURCC('o','g','t',' ')
#define VLC_CODEC_OGT VLC_FOURCC('o','g','t',' ')
#define VLC_CODEC_CVD VLC_FOURCC('c','v','d',' ')
#define VLC_CODEC_CVD VLC_FOURCC('c','v','d',' ')
#define VLC_CODEC_TX3G VLC_FOURCC('t','x','3','g')
/* Blu-ray Presentation Graphics */
/* Blu-ray Presentation Graphics */
#define VLC_CODEC_BD_PG VLC_FOURCC('b','d','p','g')
#define VLC_CODEC_BD_PG VLC_FOURCC('b','d','p','g')
/* EBU STL (TECH. 3264-E) */
/* EBU STL (TECH. 3264-E) */
...
...
modules/MODULES_LIST
View file @
6a63bcae
...
@@ -344,6 +344,7 @@ $Id$
...
@@ -344,6 +344,7 @@ $Id$
* stream_out_transcode: audio & video transcoder
* stream_out_transcode: audio & video transcoder
* subsdec: a codec to output textual subtitles
* subsdec: a codec to output textual subtitles
* subsdelay: subtitles delay filter
* subsdelay: subtitles delay filter
* substx3g: tx3g styled subtitles decoder
* subsusf: a demuxer for USF subtitles
* subsusf: a demuxer for USF subtitles
* subtitle: a demuxer for subtitle files
* subtitle: a demuxer for subtitle files
* svcdsub: SVCD subtitles decoder
* svcdsub: SVCD subtitles decoder
...
...
modules/codec/Makefile.am
View file @
6a63bcae
...
@@ -183,6 +183,8 @@ endif
...
@@ -183,6 +183,8 @@ endif
EXTRA_LTLIBRARIES
+=
libzvbi_plugin.la
EXTRA_LTLIBRARIES
+=
libzvbi_plugin.la
codec_LTLIBRARIES
+=
$(LTLIBzvbi)
codec_LTLIBRARIES
+=
$(LTLIBzvbi)
libsubstx3g_plugin_la_SOURCES
=
codec/substx3g.c codec/substext.h
codec_LTLIBRARIES
+=
libsubstx3g_plugin.la
### Xiph ###
### Xiph ###
...
...
modules/codec/substext.h
View file @
6a63bcae
#include <vlc_strings.h>
typedef
struct
{
bool
b_set
;
unsigned
int
i_value
;
}
subpicture_updater_sys_option_t
;
typedef
struct
segment_t
segment_t
;
typedef
struct
{
uint8_t
i_fontsize
;
uint32_t
i_color
;
//ARGB
uint8_t
i_flags
;
}
segment_style_t
;
struct
segment_t
{
char
*
psz_string
;
unsigned
int
i_size
;
segment_t
*
p_next
;
/* styles applied to that segment */
segment_style_t
styles
;
};
struct
subpicture_updater_sys_t
{
struct
subpicture_updater_sys_t
{
char
*
text
;
char
*
text
;
char
*
html
;
char
*
html
;
segment_t
*
p_htmlsegments
;
int
align
;
int
align
;
int
x
;
int
x
;
int
y
;
int
y
;
int
i_font_height_percent
;
int
i_font_height_percent
;
int
i_font_height_abs_to_src
;
bool
is_fixed
;
bool
is_fixed
;
int
fixed_width
;
int
fixed_width
;
int
fixed_height
;
int
fixed_height
;
bool
renderbg
;
bool
renderbg
;
/* styling */
subpicture_updater_sys_option_t
style_flags
;
subpicture_updater_sys_option_t
font_color
;
subpicture_updater_sys_option_t
background_color
;
int16_t
i_alpha
;
int16_t
i_drop_shadow
;
int16_t
i_drop_shadow_alpha
;
};
};
static
void
SegmentFree
(
segment_t
*
p_segment
)
{
if
(
p_segment
)
{
free
(
p_segment
->
psz_string
);
free
(
p_segment
);
}
}
static
void
MakeHtmlNewLines
(
char
**
ppsz_src
)
{
unsigned
int
i_nlcount
=
0
;
unsigned
i_len
=
strlen
(
*
ppsz_src
);
if
(
i_len
==
0
)
return
;
for
(
unsigned
i
=
0
;
i
<
i_len
;
i
++
)
if
(
(
*
ppsz_src
)[
i
]
==
'\n'
)
i_nlcount
++
;
if
(
!
i_nlcount
)
return
;
char
*
psz_dst
=
malloc
(
i_len
+
1
+
(
i_nlcount
*
4
)
);
char
*
ptr
=
psz_dst
;
for
(
unsigned
i
=
0
;
i
<
i_len
;
i
++
)
{
if
(
(
*
ppsz_src
)[
i
]
==
'\n'
)
{
strcpy
(
ptr
,
"<br/>"
);
ptr
+=
5
;
}
else
{
*
ptr
++
=
(
*
ppsz_src
)[
i
];
}
}
*
ptr
=
0
;
free
(
*
ppsz_src
);
*
ppsz_src
=
psz_dst
;
}
static
void
HtmlAppend
(
char
**
ppsz_dst
,
const
char
*
psz_src
,
const
segment_style_t
*
p_styles
,
const
float
f_scale
)
{
if
(
!
ppsz_dst
)
return
;
int
i_ignore
;
VLC_UNUSED
(
i_ignore
);
char
*
psz_subtext
=
NULL
;
char
*
psz_text
=
NULL
;
char
*
psz_fontsize
=
NULL
;
char
*
psz_color
=
NULL
;
char
*
psz_encoded
=
convert_xml_special_chars
(
psz_src
);
if
(
!
psz_encoded
)
return
;
MakeHtmlNewLines
(
&
psz_encoded
);
if
(
p_styles
->
i_color
&
0xFF000000
)
//ARGB
i_ignore
=
asprintf
(
&
psz_color
,
" color=
\"
#%6x
\"
"
,
p_styles
->
i_color
&
0x00FFFFFF
);
if
(
p_styles
->
i_fontsize
>
0
&&
f_scale
>
0
)
i_ignore
=
asprintf
(
&
psz_fontsize
,
" size=
\"
%u
\"
"
,
(
unsigned
)
(
f_scale
*
p_styles
->
i_fontsize
)
);
i_ignore
=
asprintf
(
&
psz_subtext
,
"%s%s%s%s%s%s%s"
,
(
p_styles
->
i_flags
&
STYLE_UNDERLINE
)
?
"<u>"
:
""
,
(
p_styles
->
i_flags
&
STYLE_BOLD
)
?
"<b>"
:
""
,
(
p_styles
->
i_flags
&
STYLE_ITALIC
)
?
"<i>"
:
""
,
psz_encoded
,
(
p_styles
->
i_flags
&
STYLE_ITALIC
)
?
"</i>"
:
""
,
(
p_styles
->
i_flags
&
STYLE_BOLD
)
?
"</b>"
:
""
,
(
p_styles
->
i_flags
&
STYLE_UNDERLINE
)
?
"</u>"
:
""
);
if
(
psz_color
||
psz_fontsize
)
{
i_ignore
=
asprintf
(
&
psz_text
,
"<font%s%s>%s</font>"
,
psz_color
?
psz_color
:
""
,
psz_fontsize
?
psz_fontsize
:
""
,
psz_subtext
);
free
(
psz_subtext
);
}
else
{
psz_text
=
psz_subtext
;
}
free
(
psz_fontsize
);
free
(
psz_color
);
if
(
*
ppsz_dst
)
{
char
*
psz_dst
=
*
ppsz_dst
;
i_ignore
=
asprintf
(
ppsz_dst
,
"%s%s"
,
psz_dst
,
psz_text
);
free
(
psz_dst
);
free
(
psz_text
);
}
else
*
ppsz_dst
=
psz_text
;
}
static
char
*
SegmentsToHtml
(
segment_t
*
p_head
,
const
float
f_scale
)
{
char
*
psz_dst
=
NULL
;
char
*
psz_ret
=
NULL
;
while
(
p_head
)
{
HtmlAppend
(
&
psz_dst
,
p_head
->
psz_string
,
&
p_head
->
styles
,
f_scale
);
p_head
=
p_head
->
p_next
;
}
int
i_ignore
=
asprintf
(
&
psz_ret
,
"<text>%s</text>"
,
psz_dst
);
VLC_UNUSED
(
i_ignore
);
free
(
psz_dst
);
return
psz_ret
;
}
static
int
SubpictureTextValidate
(
subpicture_t
*
subpic
,
static
int
SubpictureTextValidate
(
subpicture_t
*
subpic
,
bool
has_src_changed
,
const
video_format_t
*
fmt_src
,
bool
has_src_changed
,
const
video_format_t
*
fmt_src
,
bool
has_dst_changed
,
const
video_format_t
*
fmt_dst
,
bool
has_dst_changed
,
const
video_format_t
*
fmt_dst
,
...
@@ -59,7 +205,13 @@ static void SubpictureTextUpdate(subpicture_t *subpic,
...
@@ -59,7 +205,13 @@ static void SubpictureTextUpdate(subpicture_t *subpic,
return
;
return
;
r
->
psz_text
=
sys
->
text
?
strdup
(
sys
->
text
)
:
NULL
;
r
->
psz_text
=
sys
->
text
?
strdup
(
sys
->
text
)
:
NULL
;
r
->
psz_html
=
sys
->
html
?
strdup
(
sys
->
html
)
:
NULL
;
if
(
sys
->
p_htmlsegments
)
r
->
psz_html
=
SegmentsToHtml
(
sys
->
p_htmlsegments
,
(
float
)
fmt_dst
->
i_height
/
fmt_src
->
i_height
);
else
if
(
sys
->
html
)
r
->
psz_html
=
strdup
(
sys
->
html
);
else
r
->
psz_html
=
NULL
;
r
->
i_align
=
sys
->
align
;
r
->
i_align
=
sys
->
align
;
r
->
b_renderbg
=
sys
->
renderbg
;
r
->
b_renderbg
=
sys
->
renderbg
;
if
(
!
sys
->
is_fixed
)
{
if
(
!
sys
->
is_fixed
)
{
...
@@ -84,16 +236,38 @@ static void SubpictureTextUpdate(subpicture_t *subpic,
...
@@ -84,16 +236,38 @@ static void SubpictureTextUpdate(subpicture_t *subpic,
r
->
i_y
=
sys
->
y
*
fmt_dst
->
i_height
/
sys
->
fixed_height
;
r
->
i_y
=
sys
->
y
*
fmt_dst
->
i_height
/
sys
->
fixed_height
;
}
}
if
(
sys
->
i_font_height_percent
!=
0
)
if
(
sys
->
i_font_height_percent
||
sys
->
i_alpha
||
sys
->
style_flags
.
b_set
||
sys
->
font_color
.
b_set
||
sys
->
background_color
.
b_set
)
{
{
r
->
p_style
=
text_style_New
();
r
->
p_style
=
text_style_New
();
if
(
r
->
p_style
)
if
(
!
r
->
p_style
)
return
;
if
(
sys
->
i_font_height_abs_to_src
)
sys
->
i_font_height_percent
=
sys
->
i_font_height_abs_to_src
*
100
/
fmt_src
->
i_visible_height
;
if
(
sys
->
i_font_height_percent
)
{
{
r
->
p_style
->
i_font_size
=
sys
->
i_font_height_percent
*
r
->
p_style
->
i_font_size
=
sys
->
i_font_height_percent
*
subpic
->
i_original_picture_height
/
100
;
subpic
->
i_original_picture_height
/
100
;
r
->
p_style
->
i_font_color
=
0xffffff
;
r
->
p_style
->
i_font_color
=
0xffffff
;
r
->
p_style
->
i_font_alpha
=
0xff
;
r
->
p_style
->
i_font_alpha
=
0xff
;
}
}
if
(
sys
->
style_flags
.
b_set
)
r
->
p_style
->
i_style_flags
=
sys
->
style_flags
.
i_value
;
if
(
sys
->
font_color
.
b_set
)
r
->
p_style
->
i_font_color
=
sys
->
font_color
.
i_value
;
if
(
sys
->
background_color
.
b_set
)
r
->
p_style
->
i_background_color
=
sys
->
background_color
.
i_value
;
if
(
sys
->
i_alpha
)
r
->
p_style
->
i_font_alpha
=
sys
->
i_alpha
;
if
(
sys
->
i_drop_shadow
)
r
->
p_style
->
i_shadow_width
=
sys
->
i_drop_shadow
;
if
(
sys
->
i_drop_shadow_alpha
)
r
->
p_style
->
i_shadow_alpha
=
sys
->
i_drop_shadow_alpha
;
}
}
}
}
static
void
SubpictureTextDestroy
(
subpicture_t
*
subpic
)
static
void
SubpictureTextDestroy
(
subpicture_t
*
subpic
)
...
@@ -102,6 +276,12 @@ static void SubpictureTextDestroy(subpicture_t *subpic)
...
@@ -102,6 +276,12 @@ static void SubpictureTextDestroy(subpicture_t *subpic)
free
(
sys
->
text
);
free
(
sys
->
text
);
free
(
sys
->
html
);
free
(
sys
->
html
);
while
(
sys
->
p_htmlsegments
)
{
segment_t
*
p_segment
=
sys
->
p_htmlsegments
;
sys
->
p_htmlsegments
=
sys
->
p_htmlsegments
->
p_next
;
SegmentFree
(
p_segment
);
}
free
(
sys
);
free
(
sys
);
}
}
...
...
modules/codec/substx3g.c
0 → 100644
View file @
6a63bcae
/*****************************************************************************
* substx3gsub.c : MP4 tx3g subtitles decoder
*****************************************************************************
* Copyright (C) 2014 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_codec.h>
#include <vlc_sout.h>
#include "substext.h"
/*****************************************************************************
* Module descriptor.
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
);
static
subpicture_t
*
Decode
(
decoder_t
*
,
block_t
**
);
vlc_module_begin
()
set_description
(
N_
(
"tx3g subtitles decoder"
)
)
set_shortname
(
N_
(
"tx3g subtitles"
)
)
set_capability
(
"decoder"
,
100
)
set_category
(
CAT_INPUT
)
set_subcategory
(
SUBCAT_INPUT_SCODEC
)
set_callbacks
(
Open
,
NULL
)
vlc_module_end
()
/****************************************************************************
* Local structs
****************************************************************************/
/*****************************************************************************
* Open: probe the decoder and return score
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
)
{
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
if
(
p_dec
->
fmt_in
.
i_codec
!=
VLC_CODEC_TX3G
)
return
VLC_EGENERIC
;
p_dec
->
pf_decode_sub
=
Decode
;
p_dec
->
fmt_out
.
i_cat
=
SPU_ES
;
p_dec
->
fmt_out
.
i_codec
=
0
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Local:
*****************************************************************************/
#define FONT_FACE_BOLD 0x1
#define FONT_FACE_ITALIC 0x2
#define FONT_FACE_UNDERLINE 0x4
static
int
ConvertFlags
(
int
i_atomflags
)
{
int
i_vlcstyles_flags
=
0
;
if
(
i_atomflags
&
FONT_FACE_BOLD
)
i_vlcstyles_flags
|=
STYLE_BOLD
;
else
if
(
i_atomflags
&
FONT_FACE_ITALIC
)
i_vlcstyles_flags
|=
STYLE_ITALIC
;
else
if
(
i_atomflags
&
FONT_FACE_UNDERLINE
)
i_vlcstyles_flags
|=
STYLE_UNDERLINE
;
return
i_vlcstyles_flags
;
}
static
void
SegmentDoSplit
(
segment_t
*
p_segment
,
uint16_t
i_start
,
uint16_t
i_end
,
segment_t
**
pp_segment_left
,
segment_t
**
pp_segment_middle
,
segment_t
**
pp_segment_right
)
{
segment_t
*
p_segment_left
=
*
pp_segment_left
;
segment_t
*
p_segment_right
=
*
pp_segment_right
;
segment_t
*
p_segment_middle
=
*
pp_segment_middle
;
p_segment_left
=
p_segment_middle
=
p_segment_right
=
NULL
;
if
(
(
p_segment
->
i_size
-
i_start
<
1
)
||
(
p_segment
->
i_size
-
i_end
<
1
)
)
return
;
if
(
i_start
>
0
)
{
p_segment_left
=
calloc
(
1
,
sizeof
(
segment_t
)
);
if
(
!
p_segment_left
)
goto
error
;
memcpy
(
&
p_segment_left
->
styles
,
&
p_segment
->
styles
,
sizeof
(
segment_style_t
)
);
p_segment_left
->
psz_string
=
strndup
(
p_segment
->
psz_string
,
i_start
);
p_segment_left
->
i_size
=
strlen
(
p_segment_left
->
psz_string
);
}
p_segment_middle
=
calloc
(
1
,
sizeof
(
segment_t
)
);
if
(
!
p_segment_middle
)
goto
error
;
memcpy
(
&
p_segment_middle
->
styles
,
&
p_segment
->
styles
,
sizeof
(
segment_style_t
)
);
p_segment_middle
->
psz_string
=
strndup
(
p_segment
->
psz_string
+
i_start
,
i_end
-
i_start
+
1
);
p_segment_middle
->
i_size
=
strlen
(
p_segment_middle
->
psz_string
);
if
(
i_end
<
(
p_segment
->
i_size
-
1
)
)
{
p_segment_right
=
calloc
(
1
,
sizeof
(
segment_t
)
);
if
(
!
p_segment_right
)
goto
error
;
memcpy
(
&
p_segment_right
->
styles
,
&
p_segment
->
styles
,
sizeof
(
segment_style_t
)
);
p_segment_right
->
psz_string
=
strndup
(
p_segment
->
psz_string
+
i_end
+
1
,
p_segment
->
i_size
-
i_end
-
1
);
p_segment_right
->
i_size
=
strlen
(
p_segment_right
->
psz_string
);
}
if
(
p_segment_left
)
p_segment_left
->
p_next
=
p_segment_middle
;
if
(
p_segment_right
)
p_segment_middle
->
p_next
=
p_segment_right
;
*
pp_segment_left
=
p_segment_left
;
*
pp_segment_middle
=
p_segment_middle
;
*
pp_segment_right
=
p_segment_right
;
return
;
error:
SegmentFree
(
p_segment_left
);
SegmentFree
(
p_segment_middle
);
SegmentFree
(
p_segment_right
);
}
static
bool
SegmentSplit
(
segment_t
*
p_prev
,
segment_t
**
pp_segment
,
const
uint16_t
i_start
,
const
uint16_t
i_end
,
const
segment_style_t
*
p_styles
)
{
segment_t
*
p_segment_left
=
NULL
,
*
p_segment_middle
=
NULL
,
*
p_segment_right
=
NULL
;
if
(
(
*
pp_segment
)
->
i_size
==
0
)
return
false
;
if
(
i_start
>
i_end
)
return
false
;
if
(
(
size_t
)(
i_end
-
i_start
)
>
(
*
pp_segment
)
->
i_size
-
1
)
return
false
;
if
(
i_end
>
(
*
pp_segment
)
->
i_size
-
1
)
return
false
;
SegmentDoSplit
(
*
pp_segment
,
i_start
,
i_end
,
&
p_segment_left
,
&
p_segment_middle
,
&
p_segment_right
);
if
(
!
p_segment_middle
)
{
/* Failed */
SegmentFree
(
p_segment_left
);
SegmentFree
(
p_segment_right
);
return
false
;
}
segment_t
*
p_next
=
(
*
pp_segment
)
->
p_next
;
SegmentFree
(
*
pp_segment
);
*
pp_segment
=
(
p_segment_left
)
?
p_segment_left
:
p_segment_middle
;
if
(
p_prev
)
p_prev
->
p_next
=
*
pp_segment
;
if
(
p_segment_right
)
p_segment_right
->
p_next
=
p_next
;
else
p_segment_middle
->
p_next
=
p_next
;
p_segment_middle
->
styles
=
*
p_styles
;
return
true
;
}
/* Creates a new segment using the given style and split existing ones according
to the start & end offsets */
static
void
ApplySegmentStyle
(
segment_t
**
pp_segment
,
const
uint16_t
i_absstart
,
const
uint16_t
i_absend
,
const
segment_style_t
*
p_styles
)
{
/* find the matching segment */
uint16_t
i_curstart
=
0
;
segment_t
*
p_prev
=
NULL
;
segment_t
*
p_cur
=
*
pp_segment
;
while
(
p_cur
)
{
uint16_t
i_curend
=
i_curstart
+
p_cur
->
i_size
-
1
;
if
(
(
i_absstart
>=
i_curstart
)
&&
(
i_absend
<=
i_curend
)
)
{
/* segment found */
if
(
!
SegmentSplit
(
p_prev
,
&
p_cur
,
i_absstart
-
i_curstart
,
i_absend
-
i_curstart
,
p_styles
)
)
return
;
if
(
!
p_prev
)
*
pp_segment
=
p_cur
;
break
;
}
else
{
i_curstart
+=
p_cur
->
i_size
;
p_prev
=
p_cur
;
p_cur
=
p_cur
->
p_next
;
}
}
}
/*****************************************************************************
* Decode:
*****************************************************************************/
static
subpicture_t
*
Decode
(
decoder_t
*
p_dec
,
block_t
**
pp_block
)
{
block_t
*
p_block
;
subpicture_t
*
p_spu
=
NULL
;
if
(
(
pp_block
==
NULL
)
||
(
*
pp_block
==
NULL
)
)
return
NULL
;
p_block
=
*
pp_block
;
*
pp_block
=
NULL
;
if
(
(
p_block
->
i_flags
&
(
BLOCK_FLAG_DISCONTINUITY
|
BLOCK_FLAG_CORRUPTED
)
)
||
p_block
->
i_buffer
<
sizeof
(
uint16_t
)
)
{
block_Release
(
p_block
);
return
NULL
;
}
uint8_t
*
p_buf
=
p_block
->
p_buffer
;
/* Read our raw string and create the styled segment for HTML */
uint16_t
i_psz_length
=
GetWBE
(
p_buf
);
char
*
psz_subtitle
=
malloc
(
i_psz_length
+
1
);
if
(
!
psz_subtitle
)
return
NULL
;
memcpy
(
psz_subtitle
,
p_block
->
p_buffer
+
sizeof
(
uint16_t
),
i_psz_length
);
psz_subtitle
[
i_psz_length
]
=
'\0'
;
p_buf
+=
i_psz_length
+
sizeof
(
uint16_t
);
for
(
uint16_t
i
=
0
;
i
<
i_psz_length
;
i
++
)
if
(
psz_subtitle
[
i
]
==
'\r'
)
psz_subtitle
[
i
]
=
'\n'
;
segment_t
*
p_segment
=
calloc
(
1
,
sizeof
(
segment_t
)
);
if
(
!
p_segment
)
{
free
(
psz_subtitle
);
return
NULL
;
}
p_segment
->
psz_string
=
strdup
(
psz_subtitle
);
p_segment
->
i_size
=
strlen
(
psz_subtitle
);
if
(
p_dec
->
fmt_in
.
subs
.
p_style
)
{
p_segment
->
styles
.
i_color
=
p_dec
->
fmt_in
.
subs
.
p_style
->
i_font_color
;
p_segment
->
styles
.
i_color
|=
p_dec
->
fmt_in
.
subs
.
p_style
->
i_font_alpha
<<
24
;
if
(
p_dec
->
fmt_in
.
subs
.
p_style
->
i_style_flags
)
p_segment
->
styles
.
i_flags
=
p_dec
->
fmt_in
.
subs
.
p_style
->
i_style_flags
;
p_segment
->
styles
.
i_fontsize
=
p_dec
->
fmt_in
.
subs
.
p_style
->
i_font_size
;
}
if
(
!
p_segment
->
psz_string
)
{
SegmentFree
(
p_segment
);
free
(
psz_subtitle
);
return
NULL
;
}
/* Create the subpicture unit */
p_spu
=
decoder_NewSubpictureText
(
p_dec
);
if
(
!
p_spu
)
{
free
(
psz_subtitle
);
SegmentFree
(
p_segment
);
return
NULL
;
}
subpicture_updater_sys_t
*
p_spu_sys
=
p_spu
->
updater
.
p_sys
;
/* Parse our styles */
while
(
(
size_t
)(
p_buf
-
p_block
->
p_buffer
)
+
8
<
p_block
->
i_buffer
)
{
uint32_t
i_atomsize
=
GetDWBE
(
p_buf
);
vlc_fourcc_t
i_atomtype
=
VLC_FOURCC
(
p_buf
[
4
],
p_buf
[
5
],
p_buf
[
6
],
p_buf
[
7
]);
p_buf
+=
8
;
switch
(
i_atomtype
)
{
case
VLC_FOURCC
(
's'
,
't'
,
'y'
,
'l'
):
{
if
(
(
size_t
)(
p_buf
-
p_block
->
p_buffer
)
<
14
)
break
;
uint16_t
i_nbrecords
=
GetWBE
(
p_buf
);
uint16_t
i_cur_record
=
0
;
p_buf
+=
2
;
while
(
i_cur_record
++
<
i_nbrecords
)
{
if
(
(
size_t
)(
p_buf
-
p_block
->
p_buffer
)
<
12
)
break
;
uint16_t
i_start
=
__MIN
(
GetWBE
(
p_buf
),
i_psz_length
-
1
);
uint16_t
i_end
=
__MIN
(
GetWBE
(
p_buf
+
2
),
i_psz_length
-
1
);
segment_style_t
style
;
style
.
i_flags
=
ConvertFlags
(
p_buf
[
6
]
);
style
.
i_fontsize
=
p_buf
[
7
];
style
.
i_color
=
GetDWBE
(
p_buf
+
8
)
>>
8
;
// RGBA -> ARGB
style
.
i_color
|=
(
GetDWBE
(
p_buf
+
8
)
&
0xFF
)
<<
24
;
ApplySegmentStyle
(
&
p_segment
,
i_start
,
i_end
,
&
style
);
if
(
i_nbrecords
==
1
)
{
if
(
p_buf
[
6
]
)
{
p_spu_sys
->
style_flags
.
i_value
=
ConvertFlags
(
p_buf
[
6
]
);
p_spu_sys
->
style_flags
.
b_set
=
true
;
}
p_spu_sys
->
i_font_height_abs_to_src
=
p_buf
[
7
];
p_spu_sys
->
font_color
.
i_value
=
GetDWBE
(
p_buf
+
8
)
>>
8
;
// RGBA -> ARGB
p_spu_sys
->
font_color
.
i_value
|=
(
GetDWBE
(
p_buf
+
8
)
&
0xFF
)
<<
24
;
p_spu_sys
->
font_color
.
b_set
=
true
;
}
p_buf
+=
12
;
}
}
break
;
case
VLC_FOURCC
(
'd'
,
'r'
,
'p'
,
'o'
):
if
(
(
size_t
)(
p_buf
-
p_block
->
p_buffer
)
<
4
)
break
;
p_spu_sys
->
i_drop_shadow
=
__MAX
(
GetWBE
(
p_buf
),
GetWBE
(
p_buf
+
2
)
);
break
;
case
VLC_FOURCC
(
'd'
,
'r'
,
'p'
,
't'
):
if
(
(
size_t
)(
p_buf
-
p_block
->
p_buffer
)
<
2
)
break
;
p_spu_sys
->
i_drop_shadow_alpha
=
GetWBE
(
p_buf
);
break
;
default:
break
;
}
p_buf
+=
i_atomsize
;
}
p_spu
->
i_start
=
p_block
->
i_pts
;
p_spu
->
i_stop
=
p_block
->
i_pts
+
p_block
->
i_length
;
p_spu
->
b_ephemer
=
(
p_block
->
i_length
==
0
);
p_spu
->
b_absolute
=
false
;
p_spu_sys
->
align
=
SUBPICTURE_ALIGN_BOTTOM
;
p_spu_sys
->
text
=
psz_subtitle
;
p_spu_sys
->
p_htmlsegments
=
p_segment
;
block_Release
(
p_block
);
return
p_spu
;
}
po/POTFILES.in
View file @
6a63bcae
...
@@ -399,6 +399,7 @@ modules/codec/spudec/spudec.h
...
@@ -399,6 +399,7 @@ modules/codec/spudec/spudec.h
modules/codec/stl.c
modules/codec/stl.c
modules/codec/subsdec.c
modules/codec/subsdec.c
modules/codec/subsusf.c
modules/codec/subsusf.c
modules/codec/substx3g.c
modules/codec/svcdsub.c
modules/codec/svcdsub.c
modules/codec/t140.c
modules/codec/t140.c
modules/codec/telx.c
modules/codec/telx.c
...
...
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