FFmpeg
Loading...
Searching...
No Matches
mccdec.c
Go to the documentation of this file.
1/*
2 * MCC subtitle demuxer
3 * Copyright (c) 2020 Paul B Mahol
4 * Copyright (c) 2025 Jacob Lifshay
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "avformat.h"
24#include "demux.h"
25#include "internal.h"
27#include "libavcodec/codec_id.h"
30#include "libavutil/avstring.h"
31#include "libavutil/avutil.h"
32#include "libavutil/error.h"
33#include "libavutil/internal.h"
34#include "libavutil/log.h"
35#include "libavutil/macros.h"
36#include "libavutil/opt.h"
37#include "libavutil/rational.h"
38#include "libavutil/timecode.h"
39#include "subtitles.h"
40#include <inttypes.h>
41#include <stdbool.h>
42#include <string.h>
43
49
50static int mcc_probe(const AVProbeData *p)
51{
52 char buf[28];
53 FFTextReader tr;
54
55 ff_text_init_buf(&tr, p->buf, p->buf_size);
56
57 while (ff_text_peek_r8(&tr) == '\r' || ff_text_peek_r8(&tr) == '\n')
58 ff_text_r8(&tr);
59
60 ff_text_read(&tr, buf, sizeof(buf));
61
62 if (!memcmp(buf, "File Format=MacCaption_MCC V", 28))
63 return AVPROBE_SCORE_MAX;
64
65 return 0;
66}
67
68static int convert(uint8_t x)
69{
70 if (x >= 'a')
71 x -= 87;
72 else if (x >= 'A')
73 x -= 55;
74 else
75 x -= '0';
76 return x;
77}
78
79typedef struct alias {
80 uint8_t key;
81 int len;
82 const char *value;
83} alias;
84
85#define CCPAD "\xFA\x0\x0"
86#define CCPAD3 CCPAD CCPAD CCPAD
87
89
90static const alias aliases[20] = {
91 // clang-format off
92 { .key = 16, .len = 3, .value = cc_pad, },
93 { .key = 17, .len = 6, .value = cc_pad, },
94 { .key = 18, .len = 9, .value = cc_pad, },
95 { .key = 19, .len = 12, .value = cc_pad, },
96 { .key = 20, .len = 15, .value = cc_pad, },
97 { .key = 21, .len = 18, .value = cc_pad, },
98 { .key = 22, .len = 21, .value = cc_pad, },
99 { .key = 23, .len = 24, .value = cc_pad, },
100 { .key = 24, .len = 27, .value = cc_pad, },
101 { .key = 25, .len = 3, .value = "\xFB\x80\x80", },
102 { .key = 26, .len = 3, .value = "\xFC\x80\x80", },
103 { .key = 27, .len = 3, .value = "\xFD\x80\x80", },
104 { .key = 28, .len = 2, .value = "\x96\x69", },
105 { .key = 29, .len = 2, .value = "\x61\x01", },
106 { .key = 30, .len = 3, .value = "\xFC\x80\x80", },
107 { .key = 31, .len = 3, .value = "\xFC\x80\x80", },
108 { .key = 32, .len = 4, .value = "\xE1\x00\x00\x00", },
109 { .key = 33, .len = 0, .value = NULL, },
110 { .key = 34, .len = 0, .value = NULL, },
111 { .key = 35, .len = 1, .value = "\x0", },
112 // clang-format on
113};
114
120
121static int time_tracker_init(TimeTracker *tt, AVStream *st, AVRational rate, void *log_ctx)
122{
123 *tt = (TimeTracker){ .last_ts = 0 };
124 int ret = av_timecode_init(&tt->timecode, rate, rate.den == 1001 ? AV_TIMECODE_FLAG_DROPFRAME : 0, 0, log_ctx);
125 if (ret < 0)
126 return ret;
127 // wrap pts values at 24hr ourselves since they can be bigger than fits in an int
128 AVTimecode twenty_four_hr;
129 ret = av_timecode_init_from_components(&twenty_four_hr, rate, tt->timecode.flags, 24, 0, 0, 0, log_ctx);
130 if (ret < 0)
131 return ret;
132 tt->twenty_four_hr = twenty_four_hr.start;
133 // timecode uses reciprocal of timebase
134 avpriv_set_pts_info(st, 64, rate.den, rate.num);
135 return 0;
136}
137
138typedef struct MCCTimecode {
139 unsigned hh, mm, ss, ff, field, line_number;
141
142static int time_tracker_set_time(TimeTracker *tt, const MCCTimecode *tc, void *log_ctx)
143{
144 AVTimecode last = tt->timecode;
145 int ret = av_timecode_init_from_components(&tt->timecode, last.rate, last.flags, tc->hh, tc->mm, tc->ss, tc->ff, log_ctx);
146 if (ret < 0) {
147 tt->timecode = last;
148 return ret;
149 }
150 tt->last_ts -= last.start;
151 tt->last_ts += tt->timecode.start;
152 if (tt->timecode.start < last.start)
153 tt->last_ts += tt->twenty_four_hr;
154 return 0;
155}
156
161
163 { .rate = { .num = 24, .den = 1 }, .str = "24" },
164 { .rate = { .num = 25, .den = 1 }, .str = "25" },
165 { .rate = { .num = 30000, .den = 1001 }, .str = "30DF" },
166 { .rate = { .num = 30, .den = 1 }, .str = "30" },
167 { .rate = { .num = 50, .den = 1 }, .str = "50" },
168 { .rate = { .num = 60000, .den = 1001 }, .str = "60DF" },
169 { .rate = { .num = 60, .den = 1 }, .str = "60" },
170};
171
172static int parse_time_code_rate(AVFormatContext *s, AVStream *st, TimeTracker *tt, const char *time_code_rate)
173{
174 for (size_t i = 0; i < FF_ARRAY_ELEMS(valid_time_code_rates); i++) {
175 const char *after;
176 if (av_stristart(time_code_rate, valid_time_code_rates[i].str, &after) != 0) {
177 bool bad_after = false;
178 for (; *after; after++) {
179 if (!av_isspace(*after)) {
180 bad_after = true;
181 break;
182 }
183 }
184 if (bad_after)
185 continue;
187 }
188 }
189 av_log(s, AV_LOG_FATAL, "invalid mcc time code rate: %s", time_code_rate);
190 return AVERROR_INVALIDDATA;
191}
192
193static int mcc_parse_time_code_part(char **line_left, unsigned *value, unsigned max, const char *after_set)
194{
195 *value = 0;
196 if (!av_isdigit(**line_left))
197 return AVERROR_INVALIDDATA;
198 while (av_isdigit(**line_left)) {
199 unsigned digit = **line_left - '0';
200 *value = *value * 10 + digit;
201 ++*line_left;
202 if (*value > max)
203 return AVERROR_INVALIDDATA;
204 }
205 unsigned char after = **line_left;
206 if (!after || !strchr(after_set, after))
207 return AVERROR_INVALIDDATA;
208 ++*line_left;
209 return after;
210}
211
212static int mcc_parse_time_code(char **line_left, MCCTimecode *tc)
213{
214 *tc = (MCCTimecode){ .field = 0, .line_number = 9 };
215 int ret = mcc_parse_time_code_part(line_left, &tc->hh, 23, ":");
216 if (ret < 0)
217 return ret;
218 ret = mcc_parse_time_code_part(line_left, &tc->mm, 59, ":");
219 if (ret < 0)
220 return ret;
221 ret = mcc_parse_time_code_part(line_left, &tc->ss, 59, ":;");
222 if (ret < 0)
223 return ret;
224 ret = mcc_parse_time_code_part(line_left, &tc->ff, 59, ".\t");
225 if (ret < 0)
226 return ret;
227 if (ret == '.') {
228 ret = mcc_parse_time_code_part(line_left, &tc->field, 1, ",\t");
229 if (ret < 0)
230 return ret;
231 if (ret == ',') {
232 ret = mcc_parse_time_code_part(line_left, &tc->line_number, 0xFFFF, "\t");
233 if (ret < 0)
234 return ret;
235 }
236 }
237 if (ret != '\t')
238 return AVERROR_INVALIDDATA;
239 return 0;
240}
241
243{
244 MCCContext *mcc = s->priv_data;
246 int64_t pos;
247 AVSmpte436mCodedAnc coded_anc = {
248 .payload_sample_coding = AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA,
249 };
250 char line[4096];
251 FFTextReader tr;
252 int ret = 0;
253
254 ff_text_init_avio(s, &tr, s->pb);
255
256 if (!st)
257 return AVERROR(ENOMEM);
258 if (mcc->eia608_extract) {
261 } else {
264 av_dict_set(&st->metadata, "data_type", "vbi_vanc_smpte_436M", 0);
265 }
266
267 TimeTracker tt;
268 ret = time_tracker_init(&tt, st, (AVRational){ .num = 30, .den = 1 }, s);
269 if (ret < 0)
270 return ret;
271
272 while (!ff_text_eof(&tr)) {
273 pos = ff_text_pos(&tr);
274 ff_subtitles_read_line(&tr, line, sizeof(line));
275 if (!strncmp(line, "File Format=MacCaption_MCC V", 28))
276 continue;
277 if (!strncmp(line, "//", 2))
278 continue;
279 if (!strncmp(line, "Time Code Rate=", 15)) {
280 ret = parse_time_code_rate(s, st, &tt, line + 15);
281 if (ret < 0)
282 return ret;
283 continue;
284 }
285 if (strchr(line, '='))
286 continue; // skip attributes
287 char *line_left = line;
288 while (av_isspace(*line_left))
289 line_left++;
290 if (!*line_left) // skip empty lines
291 continue;
292 MCCTimecode tc;
293 ret = mcc_parse_time_code(&line_left, &tc);
294 if (ret < 0) {
295 av_log(s, AV_LOG_ERROR, "can't parse mcc time code");
296 continue;
297 }
298
300 ret = time_tracker_set_time(&tt, &tc, s);
301 if (ret < 0)
302 continue;
303 bool merge = last_pts == tt.last_ts;
304
305 coded_anc.line_number = tc.line_number;
307
310
311 while (*line_left) {
312 uint8_t v = convert(*line_left++);
313
314 if (v >= 16 && v <= 35) {
315 int idx = v - 16;
316 if (aliases[idx].len)
318 } else {
319 uint8_t vv;
320
321 if (!*line_left)
322 break;
323 vv = convert(*line_left++);
324 bytestream2_put_byte(&pb, vv | (v << 4));
325 }
326 }
327 if (pb.eof)
328 continue;
329 // remove trailing ANC checksum byte (not to be confused with the CDP checksum byte),
330 // it's not included in 8-bit sample encodings. see section 6.2 (page 14) of:
331 // https://pub.smpte.org/latest/st436/s436m-2006.pdf
332 bytestream2_seek_p(&pb, -1, SEEK_CUR);
334 if (coded_anc.payload_sample_count == 0)
335 continue; // ignore if too small
336 // add padding to align to 4 bytes
337 while (!pb.eof && bytestream2_tell_p(&pb) % 4)
338 bytestream2_put_byte(&pb, 0);
339 if (pb.eof)
340 continue;
342
343 AVPacket *sub;
344 if (mcc->eia608_extract) {
347 &anc, coded_anc.payload_sample_coding, coded_anc.payload_sample_count, coded_anc.payload, s)
348 < 0)
349 continue;
350 // reuse line
351 int cc_count = av_smpte_291m_anc_8bit_extract_cta_708(&anc, line, s);
352 if (cc_count < 0) // continue if error or if it's not a closed captions packet
353 continue;
354 int len = cc_count * 3;
355
356 sub = ff_subtitles_queue_insert(&mcc->q, line, len, merge);
357 if (!sub)
358 return AVERROR(ENOMEM);
359 } else {
360 sub = ff_subtitles_queue_insert(&mcc->q, NULL, 0, merge);
361 if (!sub)
362 return AVERROR(ENOMEM);
363
364 ret = av_smpte_436m_anc_append(sub, 1, &coded_anc);
365 if (ret < 0)
366 return ret;
367 }
368
369 sub->pos = pos;
370 sub->pts = tt.last_ts;
371 sub->duration = 1;
372 continue;
373 }
374
376
377 return ret;
378}
379
381{
382 MCCContext *mcc = s->priv_data;
383 return ff_subtitles_queue_read_packet(&mcc->q, pkt);
384}
385
386static int mcc_read_seek(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
387{
388 MCCContext *mcc = s->priv_data;
389 return ff_subtitles_queue_seek(&mcc->q, s, stream_index, min_ts, ts, max_ts, flags);
390}
391
393{
394 MCCContext *mcc = s->priv_data;
396 return 0;
397}
398
399#define OFFSET(x) offsetof(MCCContext, x)
400#define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
401// clang-format off
402static const AVOption mcc_options[] = {
403 { "eia608_extract", "extract EIA-608/708 captions from VANC packets", OFFSET(eia608_extract), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, SD },
404 { NULL },
405};
406// clang-format on
407
408static const AVClass mcc_class = {
409 .class_name = "mcc demuxer",
410 .item_name = av_default_item_name,
411 .option = mcc_options,
412 .version = LIBAVUTIL_VERSION_INT,
413 .category = AV_CLASS_CATEGORY_DEMUXER,
414};
415
417 .p.name = "mcc",
418 .p.long_name = NULL_IF_CONFIG_SMALL("MacCaption"),
419 .p.extensions = "mcc",
420 .p.priv_class = &mcc_class,
421 .priv_data_size = sizeof(MCCContext),
422 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
426 .read_seek2 = mcc_read_seek,
428};
const FFInputFormat ff_mcc_demuxer
Definition mccdec.c:416
#define attribute_nonstring
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:834
Main libavformat public API header.
#define AVPROBE_SCORE_MAX
maximum score
Definition avformat.h:483
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Convenience header that includes libavutil's core.
static av_always_inline int bytestream2_tell_p(const PutByteContext *p)
Definition bytestream.h:197
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition bytestream.h:147
static av_always_inline int bytestream2_seek_p(PutByteContext *p, int offset, int whence)
Definition bytestream.h:236
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition bytestream.h:286
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define SD
static int read_probe(const AVProbeData *p)
Definition cdg.c:30
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
#define max(a, b)
static int64_t last_pts
#define FF_INFMT_FLAG_INIT_CLEANUP
For an FFInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition demux.h:35
static AVPacket * pkt
error code definitions
double value
Definition eval.c:102
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
@ AV_CODEC_ID_EIA_608
Definition codec_id.h:576
@ AV_CODEC_ID_SMPTE_436M_ANC
Definition codec_id.h:610
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition log.h:204
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
@ AVMEDIA_TYPE_SUBTITLE
Definition avutil.h:203
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition avutil.h:202
static av_const int av_isdigit(int c)
Locale-independent conversion of ASCII isdigit.
Definition avstring.h:202
static av_const int av_isspace(int c)
Locale-independent conversion of ASCII isspace.
Definition avstring.h:218
int av_stristart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str independent of case.
Definition avstring.c:47
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
static void merge(GetBitContext *gb, uint8_t *dst, uint8_t *src, int size)
Merge two consequent lists of equal size depending on bits read.
Definition bink.c:220
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
static av_cold int read_close(AVFormatContext *ctx)
Definition libcdio.c:143
@ AV_CLASS_CATEGORY_DEMUXER
Definition log.h:33
Utility Preprocessor macros.
static const AVClass mcc_class
Definition mccdec.c:408
static attribute_nonstring const char cc_pad[27]
Definition mccdec.c:88
static int mcc_read_seek(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
Definition mccdec.c:386
static int time_tracker_init(TimeTracker *tt, AVStream *st, AVRational rate, void *log_ctx)
Definition mccdec.c:121
static int mcc_read_header(AVFormatContext *s)
Definition mccdec.c:242
static const AVOption mcc_options[]
Definition mccdec.c:402
static int mcc_parse_time_code(char **line_left, MCCTimecode *tc)
Definition mccdec.c:212
static int time_tracker_set_time(TimeTracker *tt, const MCCTimecode *tc, void *log_ctx)
Definition mccdec.c:142
static int convert(uint8_t x)
Definition mccdec.c:68
static const alias aliases[20]
Definition mccdec.c:90
static int mcc_parse_time_code_part(char **line_left, unsigned *value, unsigned max, const char *after_set)
Definition mccdec.c:193
static int mcc_read_close(AVFormatContext *s)
Definition mccdec.c:392
static int mcc_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition mccdec.c:380
#define CCPAD3
Definition mccdec.c:86
static int parse_time_code_rate(AVFormatContext *s, AVStream *st, TimeTracker *tt, const char *time_code_rate)
Definition mccdec.c:172
#define OFFSET(x)
Definition mccdec.c:399
static int mcc_probe(const AVProbeData *p)
Definition mccdec.c:50
static const struct ValidTimeCodeRate valid_time_code_rates[]
Definition mccdec.c:162
AVOptions.
Utilities for rational number calculation.
#define FF_ARRAY_ELEMS(a)
int av_smpte_291m_anc_8bit_decode(AVSmpte291mAnc8bit *out, AVSmpte436mPayloadSampleCoding sample_coding, uint16_t sample_count, const uint8_t *payload, void *log_ctx)
Decode a AVSmpte436mCodedAnc payload into AVSmpte291mAnc8bit.
Definition smpte_436m.c:295
int av_smpte_291m_anc_8bit_extract_cta_708(const AVSmpte291mAnc8bit *anc, uint8_t *cc_data, void *log_ctx)
Try to decode an ANC packet into EIA-608/CTA-708 data (AV_CODEC_ID_EIA_608).
Definition smpte_436m.c:433
int av_smpte_436m_anc_append(AVPacket *pkt, int anc_packet_count, const AVSmpte436mCodedAnc *anc_packets)
Append more ANC packets to a single AV_CODEC_ID_SMPTE_436M_ANC AVPacket's data.
Definition smpte_436m.c:201
@ AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA
used for VBI and ANC
Definition smpte_436m.h:67
@ AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_2
Definition smpte_436m.h:44
@ AV_SMPTE_436M_WRAPPING_TYPE_VANC_FRAME
Definition smpte_436m.h:42
#define AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY
max number of bytes that can be stored in the payload of AVSmpte436mCodedAnc
Definition smpte_436m.h:110
unsigned int pos
Definition spdifenc.c:431
Describe the class of an AVClass context structure.
Definition log.h:76
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
Format I/O context.
Definition avformat.h:1333
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition packet.h:621
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition packet.h:596
int64_t pos
byte position in stream, -1 if unknown
Definition packet.h:623
This structure contains the data a format has to probe a file.
Definition avformat.h:471
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
An ANC packet with an 8-bit payload.
Definition smpte_436m.h:98
An encoded ANC packet within a single AV_CODEC_ID_SMPTE_436M_ANC AVPacket's data.
Definition smpte_436m.h:117
AVSmpte436mWrappingType wrapping_type
Definition smpte_436m.h:119
uint32_t payload_array_length
Definition smpte_436m.h:122
AVSmpte436mPayloadSampleCoding payload_sample_coding
Definition smpte_436m.h:120
uint16_t payload_sample_count
Definition smpte_436m.h:121
uint8_t payload[AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY]
the payload, has size payload_array_length.
Definition smpte_436m.h:126
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
AVDictionary * metadata
Definition avformat.h:846
uint32_t flags
flags such as drop frame, +24 hours support, ...
Definition timecode.h:43
AVRational rate
frame rate in rational form
Definition timecode.h:44
int start
timecode frame start (first base frame number)
Definition timecode.h:42
FFDemuxSubtitlesQueue q
Definition mccdec.c:47
int eia608_extract
Definition mccdec.c:46
unsigned line_number
Definition mccdec.c:139
unsigned ss
Definition mccdec.c:139
unsigned mm
Definition mccdec.c:139
unsigned field
Definition mccdec.c:139
unsigned hh
Definition mccdec.c:139
unsigned ff
Definition mccdec.c:139
AVTimecode timecode
Definition mccdec.c:118
int64_t last_ts
Definition mccdec.c:116
int64_t twenty_four_hr
Definition mccdec.c:117
AVRational rate
Definition mccdec.c:158
Definition mccdec.c:79
uint8_t key
Definition mccdec.c:80
const char * value
Definition mccdec.c:82
int len
Definition mccdec.c:81
ptrdiff_t ff_subtitles_read_line(FFTextReader *tr, char *buf, size_t size)
Read a line of text.
Definition subtitles.c:454
int64_t ff_text_pos(FFTextReader *r)
Return the byte position of the next byte returned by ff_text_r8().
Definition subtitles.c:60
int ff_subtitles_queue_seek(FFDemuxSubtitlesQueue *q, AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
Update current_sub_idx to emulate a seek.
Definition subtitles.c:269
AVPacket * ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q, const uint8_t *event, size_t len, int merge)
Insert a new subtitle event.
Definition subtitles.c:111
void ff_text_read(FFTextReader *r, char *buf, size_t size)
Read the given number of bytes (in UTF-8).
Definition subtitles.c:86
int ff_text_eof(FFTextReader *r)
Return non-zero if EOF was reached.
Definition subtitles.c:92
void ff_text_init_buf(FFTextReader *r, const void *buf, size_t size)
Similar to ff_text_init_avio(), but sets it up to read from a bounded buffer.
Definition subtitles.c:54
void ff_text_init_avio(void *s, FFTextReader *r, AVIOContext *pb)
Initialize the FFTextReader from the given AVIOContext.
Definition subtitles.c:28
int ff_text_r8(FFTextReader *r)
Return the next byte.
Definition subtitles.c:65
int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt)
Generic read_packet() callback for subtitles demuxers using this queue system.
Definition subtitles.c:230
int ff_text_peek_r8(FFTextReader *r)
Like ff_text_r8(), but don't remove the byte from the buffer.
Definition subtitles.c:97
void ff_subtitles_queue_finalize(void *log_ctx, FFDemuxSubtitlesQueue *q)
Set missing durations, sort subtitles by PTS (and then byte position), and drop duplicated events.
Definition subtitles.c:212
void ff_subtitles_queue_clean(FFDemuxSubtitlesQueue *q)
Remove and destroy all the subtitles packets.
Definition subtitles.c:321
#define av_log(a,...)
int av_timecode_init_from_components(AVTimecode *tc, AVRational rate, int flags, int hh, int mm, int ss, int ff, void *log_ctx)
Init a timecode struct from the passed timecode components.
Definition timecode.c:211
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition timecode.c:201
Timecode helpers header.
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition timecode.h:36
int len