/src/ffmpeg/libavformat/subtitles.h
Line | Count | Source |
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 | | #ifndef AVFORMAT_SUBTITLES_H |
22 | | #define AVFORMAT_SUBTITLES_H |
23 | | |
24 | | #include <stdint.h> |
25 | | #include <stddef.h> |
26 | | #include "avformat.h" |
27 | | #include "libavutil/bprint.h" |
28 | | #include "avio_internal.h" |
29 | | |
30 | | enum sub_sort { |
31 | | SUB_SORT_TS_POS = 0, ///< sort by timestamps, then position |
32 | | SUB_SORT_POS_TS, ///< sort by position, then timestamps |
33 | | }; |
34 | | |
35 | | enum ff_utf_type { |
36 | | FF_UTF_8, // or other 8 bit encodings |
37 | | FF_UTF16LE, |
38 | | FF_UTF16BE, |
39 | | }; |
40 | | |
41 | | typedef struct { |
42 | | int type; |
43 | | AVIOContext *pb; |
44 | | unsigned char buf[8]; |
45 | | int buf_pos, buf_len; |
46 | | FFIOContext buf_pb; |
47 | | } FFTextReader; |
48 | | |
49 | | /** |
50 | | * Initialize the FFTextReader from the given AVIOContext. This function will |
51 | | * read some bytes from pb, and test for UTF-8 or UTF-16 BOMs. Further accesses |
52 | | * to FFTextReader will read more data from pb. |
53 | | * If s is not NULL, the user will be warned if a UTF-16 conversion takes place. |
54 | | * |
55 | | * The purpose of FFTextReader is to transparently convert read data to UTF-8 |
56 | | * if the stream had a UTF-16 BOM. |
57 | | * |
58 | | * @param s Pointer to provide av_log context |
59 | | * @param r object which will be initialized |
60 | | * @param pb stream to read from (referenced as long as FFTextReader is in use) |
61 | | */ |
62 | | void ff_text_init_avio(void *s, FFTextReader *r, AVIOContext *pb); |
63 | | |
64 | | /** |
65 | | * Similar to ff_text_init_avio(), but sets it up to read from a bounded buffer. |
66 | | * |
67 | | * @param r object which will be initialized |
68 | | * @param buf buffer to read from (referenced as long as FFTextReader is in use) |
69 | | * @param size size of buf |
70 | | */ |
71 | | void ff_text_init_buf(FFTextReader *r, const void *buf, size_t size); |
72 | | |
73 | | /** |
74 | | * Return the byte position of the next byte returned by ff_text_r8(). For |
75 | | * UTF-16 source streams, this will return the original position, but it will |
76 | | * be incorrect if a codepoint was only partially read with ff_text_r8(). |
77 | | */ |
78 | | int64_t ff_text_pos(FFTextReader *r); |
79 | | |
80 | | /** |
81 | | * Return the next byte. The return value is always 0 - 255. Returns 0 on EOF. |
82 | | * If the source stream is UTF-16, this reads from the stream converted to |
83 | | * UTF-8. On invalid UTF-16, 0 is returned. |
84 | | */ |
85 | | int ff_text_r8(FFTextReader *r); |
86 | | |
87 | | /** |
88 | | * Return non-zero if EOF was reached. |
89 | | */ |
90 | | int ff_text_eof(FFTextReader *r); |
91 | | |
92 | | /** |
93 | | * Like ff_text_r8(), but don't remove the byte from the buffer. |
94 | | */ |
95 | | int ff_text_peek_r8(FFTextReader *r); |
96 | | |
97 | | /** |
98 | | * Read the given number of bytes (in UTF-8). On error or EOF, \0 bytes are |
99 | | * written. |
100 | | */ |
101 | | void ff_text_read(FFTextReader *r, char *buf, size_t size); |
102 | | |
103 | | typedef struct { |
104 | | AVPacket **subs; ///< array of subtitles packets |
105 | | int nb_subs; ///< number of subtitles packets |
106 | | int allocated_size; ///< allocated size for subs |
107 | | int current_sub_idx; ///< current position for the read packet callback |
108 | | enum sub_sort sort; ///< sort method to use when finalizing subtitles |
109 | | int keep_duplicates; ///< set to 1 to keep duplicated subtitle events |
110 | | } FFDemuxSubtitlesQueue; |
111 | | |
112 | | /** |
113 | | * Insert a new subtitle event. |
114 | | * |
115 | | * @param event the subtitle line (not zero terminated) or NULL on not yet available event |
116 | | * @param len the length of the event (in strlen() sense, so without '\0') |
117 | | * @param merge set to 1 if the current event should be concatenated with the |
118 | | * previous one instead of adding a new entry, 0 otherwise |
119 | | */ |
120 | | AVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q, |
121 | | const uint8_t *event, size_t len, int merge); |
122 | | |
123 | | /** |
124 | | * Same as ff_subtitles_queue_insert but takes an AVBPrint input. |
125 | | * Avoids common errors like handling incomplete AVBPrint. |
126 | | */ |
127 | | AVPacket *ff_subtitles_queue_insert_bprint(FFDemuxSubtitlesQueue *q, |
128 | | const AVBPrint *event, int merge); |
129 | | /** |
130 | | * Set missing durations, sort subtitles by PTS (and then byte position), and |
131 | | * drop duplicated events. |
132 | | */ |
133 | | void ff_subtitles_queue_finalize(void *log_ctx, FFDemuxSubtitlesQueue *q); |
134 | | |
135 | | /** |
136 | | * Generic read_packet() callback for subtitles demuxers using this queue |
137 | | * system. |
138 | | */ |
139 | | int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt); |
140 | | |
141 | | /** |
142 | | * Update current_sub_idx to emulate a seek. Except the first parameter, it |
143 | | * matches FFInputFormat->read_seek2 prototypes. |
144 | | */ |
145 | | int ff_subtitles_queue_seek(FFDemuxSubtitlesQueue *q, AVFormatContext *s, int stream_index, |
146 | | int64_t min_ts, int64_t ts, int64_t max_ts, int flags); |
147 | | |
148 | | /** |
149 | | * Remove and destroy all the subtitles packets. |
150 | | */ |
151 | | void ff_subtitles_queue_clean(FFDemuxSubtitlesQueue *q); |
152 | | |
153 | | int ff_subtitles_read_packet(AVFormatContext *s, AVPacket *pkt); |
154 | | |
155 | | int ff_subtitles_read_seek(AVFormatContext *s, int stream_index, |
156 | | int64_t min_ts, int64_t ts, int64_t max_ts, int flags); |
157 | | |
158 | | int ff_subtitles_read_close(AVFormatContext *s); |
159 | | |
160 | | /** |
161 | | * SMIL helper to load next chunk ("<...>" or untagged content) in buf. |
162 | | * |
163 | | * @param c cached character, to avoid a backward seek |
164 | | * @return size of chunk or error, e.g. AVERROR(ENOMEM) on incomplete buf |
165 | | */ |
166 | | int ff_smil_extract_next_text_chunk(FFTextReader *tr, AVBPrint *buf, char *c); |
167 | | |
168 | | /** |
169 | | * SMIL helper to point on the value of an attribute in the given tag. |
170 | | * |
171 | | * @param s SMIL tag ("<...>") |
172 | | * @param attr the attribute to look for |
173 | | */ |
174 | | const char *ff_smil_get_attr_ptr(const char *s, const char *attr); |
175 | | |
176 | | /** |
177 | | * @brief Same as ff_subtitles_read_text_chunk(), but read from an AVIOContext. |
178 | | */ |
179 | | av_warn_unused_result |
180 | | int ff_subtitles_read_chunk(AVIOContext *pb, AVBPrint *buf); |
181 | | |
182 | | /** |
183 | | * @brief Read a subtitles chunk from FFTextReader. |
184 | | * |
185 | | * A chunk is defined by a multiline "event", ending with a second line break. |
186 | | * The trailing line breaks are trimmed. CRLF are supported. |
187 | | * Example: "foo\r\nbar\r\n\r\nnext" will print "foo\r\nbar" into buf, and pb |
188 | | * will focus on the 'n' of the "next" string. |
189 | | * |
190 | | * @param tr I/O context |
191 | | * @param buf an initialized buf where the chunk is written |
192 | | * @return 0 on success, error value otherwise, e.g. AVERROR(ENOMEM) if buf is incomplete |
193 | | * |
194 | | * @note buf is cleared before writing into it. |
195 | | */ |
196 | | av_warn_unused_result |
197 | | int ff_subtitles_read_text_chunk(FFTextReader *tr, AVBPrint *buf); |
198 | | |
199 | | /** |
200 | | * Get the number of characters to increment to jump to the next line, or to |
201 | | * the end of the string. |
202 | | * The function handles the following line breaks schemes: |
203 | | * LF, CRLF (MS), or standalone CR (old MacOS). |
204 | | */ |
205 | | static av_always_inline int ff_subtitles_next_line(const char *ptr) |
206 | 10.2M | { |
207 | 10.2M | int n = strcspn(ptr, "\r\n"); |
208 | 10.2M | ptr += n; |
209 | 12.7M | while (*ptr == '\r') { |
210 | 2.51M | ptr++; |
211 | 2.51M | n++; |
212 | 2.51M | } |
213 | 10.2M | if (*ptr == '\n') |
214 | 8.36M | n++; |
215 | 10.2M | return n; |
216 | 10.2M | } Unexecuted instantiation: aqtitledec.c:ff_subtitles_next_line Unexecuted instantiation: assdec.c:ff_subtitles_next_line img2dec.c:ff_subtitles_next_line Line | Count | Source | 206 | 59.9k | { | 207 | 59.9k | int n = strcspn(ptr, "\r\n"); | 208 | 59.9k | ptr += n; | 209 | 115k | while (*ptr == '\r') { | 210 | 55.7k | ptr++; | 211 | 55.7k | n++; | 212 | 55.7k | } | 213 | 59.9k | if (*ptr == '\n') | 214 | 48.3k | n++; | 215 | 59.9k | return n; | 216 | 59.9k | } |
jacosubdec.c:ff_subtitles_next_line Line | Count | Source | 206 | 24.3k | { | 207 | 24.3k | int n = strcspn(ptr, "\r\n"); | 208 | 24.3k | ptr += n; | 209 | 42.7k | while (*ptr == '\r') { | 210 | 18.4k | ptr++; | 211 | 18.4k | n++; | 212 | 18.4k | } | 213 | 24.3k | if (*ptr == '\n') | 214 | 8.18k | n++; | 215 | 24.3k | return n; | 216 | 24.3k | } |
Unexecuted instantiation: lrcdec.c:ff_subtitles_next_line Unexecuted instantiation: mccdec.c:ff_subtitles_next_line microdvddec.c:ff_subtitles_next_line Line | Count | Source | 206 | 838 | { | 207 | 838 | int n = strcspn(ptr, "\r\n"); | 208 | 838 | ptr += n; | 209 | 2.63k | while (*ptr == '\r') { | 210 | 1.79k | ptr++; | 211 | 1.79k | n++; | 212 | 1.79k | } | 213 | 838 | if (*ptr == '\n') | 214 | 417 | n++; | 215 | 838 | return n; | 216 | 838 | } |
Unexecuted instantiation: mpeg.c:ff_subtitles_next_line mpl2dec.c:ff_subtitles_next_line Line | Count | Source | 206 | 749 | { | 207 | 749 | int n = strcspn(ptr, "\r\n"); | 208 | 749 | ptr += n; | 209 | 2.60k | while (*ptr == '\r') { | 210 | 1.85k | ptr++; | 211 | 1.85k | n++; | 212 | 1.85k | } | 213 | 749 | if (*ptr == '\n') | 214 | 107 | n++; | 215 | 749 | return n; | 216 | 749 | } |
mpsubdec.c:ff_subtitles_next_line Line | Count | Source | 206 | 6.46M | { | 207 | 6.46M | int n = strcspn(ptr, "\r\n"); | 208 | 6.46M | ptr += n; | 209 | 8.74M | while (*ptr == '\r') { | 210 | 2.27M | ptr++; | 211 | 2.27M | n++; | 212 | 2.27M | } | 213 | 6.46M | if (*ptr == '\n') | 214 | 4.65M | n++; | 215 | 6.46M | return n; | 216 | 6.46M | } |
Unexecuted instantiation: pjsdec.c:ff_subtitles_next_line Unexecuted instantiation: rcwtdec.c:ff_subtitles_next_line Unexecuted instantiation: realtextdec.c:ff_subtitles_next_line Unexecuted instantiation: samidec.c:ff_subtitles_next_line Unexecuted instantiation: sccdec.c:ff_subtitles_next_line Unexecuted instantiation: srtdec.c:ff_subtitles_next_line stldec.c:ff_subtitles_next_line Line | Count | Source | 206 | 3.66M | { | 207 | 3.66M | int n = strcspn(ptr, "\r\n"); | 208 | 3.66M | ptr += n; | 209 | 3.82M | while (*ptr == '\r') { | 210 | 162k | ptr++; | 211 | 162k | n++; | 212 | 162k | } | 213 | 3.66M | if (*ptr == '\n') | 214 | 3.64M | n++; | 215 | 3.66M | return n; | 216 | 3.66M | } |
Unexecuted instantiation: subtitles.c:ff_subtitles_next_line Unexecuted instantiation: subviewer1dec.c:ff_subtitles_next_line Unexecuted instantiation: subviewerdec.c:ff_subtitles_next_line Unexecuted instantiation: tedcaptionsdec.c:ff_subtitles_next_line Unexecuted instantiation: vplayerdec.c:ff_subtitles_next_line Unexecuted instantiation: webvttdec.c:ff_subtitles_next_line |
217 | | |
218 | | /** |
219 | | * Read a line of text. Discards line ending characters. |
220 | | * The function handles the following line breaks schemes: |
221 | | * LF, CRLF (MS), or standalone CR (old MacOS). |
222 | | * |
223 | | * Returns the number of bytes written to buf. Always writes a terminating 0, |
224 | | * similar as with snprintf. |
225 | | * |
226 | | * @note returns a negative error code if a \0 byte is found |
227 | | */ |
228 | | ptrdiff_t ff_subtitles_read_line(FFTextReader *tr, char *buf, size_t size); |
229 | | |
230 | | #endif /* AVFORMAT_SUBTITLES_H */ |