FFmpeg
Loading...
Searching...
No Matches
rcwtdec.c
Go to the documentation of this file.
1/*
2 * RCWT (Raw Captions With Time) demuxer
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 * RCWT (Raw Captions With Time) is a format native to ccextractor, a commonly
23 * used open source tool for processing 608/708 Closed Captions (CC) sources.
24 *
25 * This demuxer implements the specification as of March 2024, which has
26 * been stable and unchanged since April 2014.
27 *
28 * A free specification of RCWT can be found here:
29 * @url{https://github.com/CCExtractor/ccextractor/blob/master/docs/BINARY_FILE_FORMAT.TXT}
30 */
31
32#include "avformat.h"
33#include "demux.h"
34#include "internal.h"
35#include "subtitles.h"
37
38#define RCWT_HEADER_SIZE 11
39
43
45{
46 RCWTContext *rcwt = avf->priv_data;
47
48 AVStream *st;
49 uint8_t header[RCWT_HEADER_SIZE];
50 int ret;
51
52 /* read header */
54 if (ret < 0)
55 return ret;
56
57 if (AV_RB16(header + 6) != 0x0001) {
58 av_log(avf, AV_LOG_ERROR, "RCWT format version is not compatible "
59 "(only version 0.001 is known)\n");
61 }
62
63 av_log(avf, AV_LOG_DEBUG, "RCWT writer application: %02X version: %02x\n",
64 header[3], header[5]);
65
66 /* setup stream */
67 st = avformat_new_stream(avf, NULL);
68 if (!st)
69 return AVERROR(ENOMEM);
70
73
74 avpriv_set_pts_info(st, 64, 1, 1000);
75
76 /* demux */
77 while (!avio_feof(avf->pb)) {
78 AVPacket *sub;
79 int64_t cluster_pos = avio_tell(avf->pb);
80 int64_t cluster_pts = avio_rl64(avf->pb);
81 int cluster_nb_blocks = avio_rl16(avf->pb);
82
83 if (cluster_nb_blocks == 0)
84 continue;
85
86 sub = ff_subtitles_queue_insert(&rcwt->q, NULL, 0, 0);
87 if (!sub)
88 return AVERROR(ENOMEM);
89
90 ret = av_get_packet(avf->pb, sub, cluster_nb_blocks * 3);
91 if (ret < 0)
92 return ret;
93
94 sub->pos = cluster_pos;
95 sub->pts = cluster_pts;
96 }
97
98 ff_subtitles_queue_finalize(avf, &rcwt->q);
99
100 return 0;
101}
102
103static int rcwt_probe(const AVProbeData *p)
104{
105 return p->buf_size > RCWT_HEADER_SIZE &&
106 AV_RB16(p->buf) == 0xCCCC &&
107 AV_RB8(p->buf + 2) == 0xED &&
108 AV_RB16(p->buf + 6) == 0x0001 ? 50 : 0;
109}
110
112 .p.name = "rcwt",
113 .p.long_name = NULL_IF_CONFIG_SMALL("RCWT (Raw Captions With Time)"),
114 .p.flags = AVFMT_TS_DISCONT,
115 .priv_data_size = sizeof(RCWTContext),
116 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
120 .read_seek2 = ff_subtitles_read_seek,
122};
const FFInputFormat ff_rcwt_demuxer
Definition rcwtdec.c:111
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 AVFMT_TS_DISCONT
Format allows timestamp discontinuities.
Definition avformat.h:500
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition utils.c:98
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition aviobuf.c:349
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition avio.h:494
unsigned int avio_rl16(AVIOContext *s)
Definition aviobuf.c:717
uint64_t avio_rl64(AVIOContext *s)
Definition aviobuf.c:741
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:665
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
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 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 int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
@ AV_CODEC_ID_EIA_608
Definition codec_id.h:576
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_SUBTITLE
Definition avutil.h:203
#define AV_RB8(x)
#define AV_RB16(p)
#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
#define RCWT_HEADER_SIZE
Definition rcwtdec.c:38
static int rcwt_probe(const AVProbeData *p)
Definition rcwtdec.c:103
static int rcwt_read_header(AVFormatContext *avf)
Definition rcwtdec.c:44
static const uint8_t header[24]
Definition sdr2.c:68
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
AVIOContext * pb
I/O context.
Definition avformat.h:1375
void * priv_data
Format private data.
Definition avformat.h:1361
This structure stores compressed data.
Definition packet.h:580
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
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
FFDemuxSubtitlesQueue q
Definition rcwtdec.c:41
int ff_subtitles_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition subtitles.c:331
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
int ff_subtitles_read_seek(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
Definition subtitles.c:337
int ff_subtitles_read_close(AVFormatContext *s)
Definition subtitles.c:345
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
#define av_log(a,...)