FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
realtextdec.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2012 Clément Bœsch
3
*
4
* This file is part of FFmpeg.
5
*
6
* FFmpeg is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* FFmpeg is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with FFmpeg; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
*/
20
21
/**
22
* @file
23
* RealText subtitle demuxer
24
* @see http://service.real.com/help/library/guides/ProductionGuide/prodguide/htmfiles/realtext.htm
25
*/
26
27
#include "
avformat.h
"
28
#include "
internal.h
"
29
#include "
subtitles.h
"
30
#include "
libavutil/avstring.h
"
31
#include "
libavutil/bprint.h
"
32
#include "
libavutil/intreadwrite.h
"
33
34
typedef
struct
{
35
FFDemuxSubtitlesQueue
q
;
36
}
RealTextContext
;
37
38
static
int
realtext_probe
(
AVProbeData
*p)
39
{
40
char
buf
[7];
41
FFTextReader
tr;
42
ff_text_init_buf
(&tr, p->
buf
, p->
buf_size
);
43
ff_text_read
(&tr, buf,
sizeof
(buf));
44
45
return
!
av_strncasecmp
(buf,
"<window"
, 7) ?
AVPROBE_SCORE_EXTENSION
: 0;
46
}
47
48
static
int
read_ts
(
const
char
*
s
)
49
{
50
int
hh, mm, ss, ms;
51
52
if
(sscanf(s,
"%u:%u:%u.%u"
, &hh, &mm, &ss, &ms) == 4)
return
(hh*3600 + mm*60 + ss) * 100 + ms;
53
if
(sscanf(s,
"%u:%u:%u"
, &hh, &mm, &ss ) == 3)
return
(hh*3600 + mm*60 + ss) * 100;
54
if
(sscanf(s,
"%u:%u.%u"
, &mm, &ss, &ms) == 3)
return
( mm*60 + ss) * 100 + ms;
55
if
(sscanf(s,
"%u:%u"
, &mm, &ss ) == 2)
return
( mm*60 + ss) * 100;
56
if
(sscanf(s,
"%u.%u"
, &ss, &ms) == 2)
return
( ss) * 100 + ms;
57
return
strtol(s,
NULL
, 10) * 100;
58
}
59
60
static
int
realtext_read_header
(
AVFormatContext
*
s
)
61
{
62
RealTextContext
*rt = s->
priv_data
;
63
AVStream
*st =
avformat_new_stream
(s,
NULL
);
64
AVBPrint
buf
;
65
char
c
= 0;
66
int
res = 0,
duration
=
read_ts
(
"60"
);
// default duration is 60 seconds
67
FFTextReader
tr;
68
ff_text_init_avio
(s, &tr, s->
pb
);
69
70
if
(!st)
71
return
AVERROR
(ENOMEM);
72
avpriv_set_pts_info
(st, 64, 1, 100);
73
st->
codec
->
codec_type
=
AVMEDIA_TYPE_SUBTITLE
;
74
st->
codec
->
codec_id
=
AV_CODEC_ID_REALTEXT
;
75
76
av_bprint_init
(&buf, 0,
AV_BPRINT_SIZE_UNLIMITED
);
77
78
while
(!
ff_text_eof
(&tr)) {
79
AVPacket
*sub;
80
const
int64_t pos =
ff_text_pos
(&tr) - (c != 0);
81
int
n
=
ff_smil_extract_next_text_chunk
(&tr, &buf, &c);
82
83
if
(n == 0)
84
break
;
85
86
if
(!
av_strncasecmp
(buf.str,
"<window"
, 7)) {
87
/* save header to extradata */
88
const
char
*p =
ff_smil_get_attr_ptr
(buf.str,
"duration"
);
89
90
if
(p)
91
duration
=
read_ts
(p);
92
st->
codec
->
extradata
=
av_strdup
(buf.str);
93
if
(!st->
codec
->
extradata
) {
94
res =
AVERROR
(ENOMEM);
95
goto
end
;
96
}
97
st->
codec
->
extradata_size
= buf.len + 1;
98
}
else
{
99
/* if we just read a <time> tag, introduce a new event, otherwise merge
100
* with the previous one */
101
int
merge
= !
av_strncasecmp
(buf.str,
"<time"
, 5) ? 0 : 1;
102
sub =
ff_subtitles_queue_insert
(&rt->
q
, buf.str, buf.len, merge);
103
if
(!sub) {
104
res =
AVERROR
(ENOMEM);
105
goto
end
;
106
}
107
if
(!merge) {
108
const
char
*begin =
ff_smil_get_attr_ptr
(buf.str,
"begin"
);
109
const
char
*
end
=
ff_smil_get_attr_ptr
(buf.str,
"end"
);
110
111
sub->
pos
= pos;
112
sub->
pts
= begin ?
read_ts
(begin) : 0;
113
sub->
duration
= end ? (
read_ts
(end) - sub->
pts
) :
duration
;
114
}
115
}
116
av_bprint_clear
(&buf);
117
}
118
ff_subtitles_queue_finalize
(&rt->
q
);
119
120
end
:
121
av_bprint_finalize
(&buf,
NULL
);
122
return
res;
123
}
124
125
static
int
realtext_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
126
{
127
RealTextContext
*rt = s->
priv_data
;
128
return
ff_subtitles_queue_read_packet
(&rt->
q
, pkt);
129
}
130
131
static
int
realtext_read_seek
(
AVFormatContext
*
s
,
int
stream_index,
132
int64_t min_ts, int64_t ts, int64_t max_ts,
int
flags
)
133
{
134
RealTextContext
*rt = s->
priv_data
;
135
return
ff_subtitles_queue_seek
(&rt->
q
, s, stream_index,
136
min_ts, ts, max_ts, flags);
137
}
138
139
static
int
realtext_read_close
(
AVFormatContext
*
s
)
140
{
141
RealTextContext
*rt = s->
priv_data
;
142
ff_subtitles_queue_clean
(&rt->
q
);
143
return
0;
144
}
145
146
AVInputFormat
ff_realtext_demuxer
= {
147
.
name
=
"realtext"
,
148
.long_name =
NULL_IF_CONFIG_SMALL
(
"RealText subtitle format"
),
149
.priv_data_size =
sizeof
(
RealTextContext
),
150
.
read_probe
=
realtext_probe
,
151
.
read_header
=
realtext_read_header
,
152
.
read_packet
=
realtext_read_packet
,
153
.read_seek2 =
realtext_read_seek
,
154
.
read_close
=
realtext_read_close
,
155
.extensions =
"rt"
,
156
};
Generated on Sun Mar 8 2015 02:34:59 for FFmpeg by
1.8.2