Coverage Report

Created: 2024-09-06 07:53

/src/ffmpeg/libavformat/lxfdec.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * LXF demuxer
3
 * Copyright (c) 2010 Tomas Härdin
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#include <inttypes.h>
23
24
#include "libavutil/intreadwrite.h"
25
#include "libavcodec/bytestream.h"
26
#include "avformat.h"
27
#include "demux.h"
28
#include "internal.h"
29
30
435k
#define LXF_MAX_PACKET_HEADER_SIZE 256
31
3.73k
#define LXF_HEADER_DATA_SIZE    120
32
8.41M
#define LXF_IDENT               "LEITCH\0"
33
24.5M
#define LXF_IDENT_LENGTH        8
34
12.9k
#define LXF_SAMPLERATE          48000
35
36
static const AVCodecTag lxf_tags[] = {
37
    { AV_CODEC_ID_MJPEG,       0 },
38
    { AV_CODEC_ID_MPEG1VIDEO,  1 },
39
    { AV_CODEC_ID_MPEG2VIDEO,  2 },    //MpMl, 4:2:0
40
    { AV_CODEC_ID_MPEG2VIDEO,  3 },    //MpPl, 4:2:2
41
    { AV_CODEC_ID_DVVIDEO,     4 },    //DV25
42
    { AV_CODEC_ID_DVVIDEO,     5 },    //DVCPRO
43
    { AV_CODEC_ID_DVVIDEO,     6 },    //DVCPRO50
44
    { AV_CODEC_ID_RAWVIDEO,    7 },    //AV_PIX_FMT_ARGB, where alpha is used for chroma keying
45
    { AV_CODEC_ID_RAWVIDEO,    8 },    //16-bit chroma key
46
    { AV_CODEC_ID_MPEG2VIDEO,  9 },    //4:2:2 CBP ("Constrained Bytes per Gop")
47
    { AV_CODEC_ID_NONE,        0 },
48
};
49
50
typedef struct LXFDemuxContext {
51
    int channels;                       ///< number of audio channels. zero means no audio
52
    int frame_number;                   ///< current video frame
53
    uint32_t video_format, packet_type, extended_size;
54
} LXFDemuxContext;
55
56
static int lxf_probe(const AVProbeData *p)
57
358k
{
58
358k
    if (!memcmp(p->buf, LXF_IDENT, LXF_IDENT_LENGTH))
59
80
        return AVPROBE_SCORE_MAX;
60
61
358k
    return 0;
62
358k
}
63
64
/**
65
 * Verify the checksum of an LXF packet header
66
 *
67
 * @param[in] header the packet header to check
68
 * @return zero if the checksum is OK, non-zero otherwise
69
 */
70
static int check_checksum(const uint8_t *header, int size)
71
217k
{
72
217k
    int x;
73
217k
    uint32_t sum = 0;
74
75
3.48M
    for (x = 0; x < size; x += 4)
76
3.27M
        sum += AV_RL32(&header[x]);
77
78
217k
    return sum;
79
217k
}
80
81
/**
82
 * Read input until we find the next ident. If found, copy it to the header buffer
83
 *
84
 * @param[out] header where to copy the ident to
85
 * @return 0 if an ident was found, < 0 on I/O error
86
 */
87
static int lxf_sync(AVFormatContext *s, uint8_t *header)
88
223k
{
89
223k
    uint8_t buf[LXF_IDENT_LENGTH];
90
223k
    int ret;
91
92
223k
    if ((ret = avio_read(s->pb, buf, LXF_IDENT_LENGTH)) != LXF_IDENT_LENGTH)
93
5.79k
        return ret < 0 ? ret : AVERROR_EOF;
94
95
7.83M
    while (memcmp(buf, LXF_IDENT, LXF_IDENT_LENGTH)) {
96
7.61M
        if (avio_feof(s->pb))
97
348
            return AVERROR_EOF;
98
99
7.61M
        memmove(buf, &buf[1], LXF_IDENT_LENGTH-1);
100
7.61M
        buf[LXF_IDENT_LENGTH-1] = avio_r8(s->pb);
101
7.61M
    }
102
103
217k
    memcpy(header, LXF_IDENT, LXF_IDENT_LENGTH);
104
105
217k
    return 0;
106
218k
}
107
108
/**
109
 * Read and checksum the next packet header
110
 *
111
 * @return the size of the payload following the header or < 0 on failure
112
 */
113
static int get_packet_header(AVFormatContext *s)
114
223k
{
115
223k
    LXFDemuxContext *lxf = s->priv_data;
116
223k
    AVIOContext   *pb  = s->pb;
117
223k
    int track_size, samples, ret;
118
223k
    uint32_t version, audio_format, header_size, channels, tmp;
119
223k
    AVStream *st;
120
223k
    uint8_t header[LXF_MAX_PACKET_HEADER_SIZE];
121
223k
    const uint8_t *p = header + LXF_IDENT_LENGTH;
122
123
    //find and read the ident
124
223k
    if ((ret = lxf_sync(s, header)) < 0)
125
6.14k
        return ret;
126
127
217k
    ret = avio_read(pb, header + LXF_IDENT_LENGTH, 8);
128
217k
    if (ret != 8)
129
41
        return ret < 0 ? ret : AVERROR_EOF;
130
131
217k
    version     = bytestream_get_le32(&p);
132
217k
    header_size = bytestream_get_le32(&p);
133
217k
    if (version > 1)
134
1.28k
        avpriv_request_sample(s, "Format version %"PRIu32, version);
135
136
217k
    if (header_size < (version ? 72 : 60) ||
137
217k
        header_size > LXF_MAX_PACKET_HEADER_SIZE ||
138
217k
        (header_size & 3)) {
139
286
        av_log(s, AV_LOG_ERROR, "Invalid header size 0x%"PRIx32"\n", header_size);
140
286
        return AVERROR_INVALIDDATA;
141
286
    }
142
143
    //read the rest of the packet header
144
217k
    if ((ret = avio_read(pb, header + (p - header),
145
217k
                          header_size - (p - header))) !=
146
217k
                          header_size - (p - header))
147
61
        return ret < 0 ? ret : AVERROR_EOF;
148
149
217k
    if (check_checksum(header, header_size))
150
217k
        av_log(s, AV_LOG_ERROR, "checksum error\n");
151
152
217k
    lxf->packet_type = bytestream_get_le32(&p);
153
217k
    p += version ? 20 : 12;
154
155
217k
    lxf->extended_size = 0;
156
217k
    switch (lxf->packet_type) {
157
208k
    case 0:
158
        //video
159
208k
        lxf->video_format = bytestream_get_le32(&p);
160
208k
        ret               = bytestream_get_le32(&p);
161
        //skip VBI data and metadata
162
208k
        avio_skip(pb, (int64_t)(uint32_t)AV_RL32(p + 4) +
163
208k
                      (int64_t)(uint32_t)AV_RL32(p + 12));
164
208k
        break;
165
6.31k
    case 1:
166
        //audio
167
6.31k
        if (s->nb_streams < 2) {
168
8
            av_log(s, AV_LOG_INFO, "got audio packet, but no audio stream present\n");
169
8
            break;
170
8
        }
171
172
6.30k
        if (version == 0)
173
5.42k
            p += 8;
174
6.30k
        audio_format = bytestream_get_le32(&p);
175
6.30k
        channels     = bytestream_get_le32(&p);
176
6.30k
        track_size   = bytestream_get_le32(&p);
177
178
6.30k
        st = s->streams[1];
179
180
        //set codec based on specified audio bitdepth
181
        //we only support tightly packed 16-, 20-, 24- and 32-bit PCM at the moment
182
6.30k
        st->codecpar->bits_per_coded_sample = (audio_format >> 6) & 0x3F;
183
184
6.30k
        if (st->codecpar->bits_per_coded_sample != (audio_format & 0x3F)) {
185
26
            avpriv_report_missing_feature(s, "Not tightly packed PCM");
186
26
            return AVERROR_PATCHWELCOME;
187
26
        }
188
189
6.27k
        switch (st->codecpar->bits_per_coded_sample) {
190
4.42k
        case 16: st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE_PLANAR; break;
191
200
        case 20: st->codecpar->codec_id = AV_CODEC_ID_PCM_LXF;   break;
192
197
        case 24: st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE_PLANAR; break;
193
1.42k
        case 32: st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE_PLANAR; break;
194
24
        default:
195
24
            avpriv_report_missing_feature(s, "PCM not 16-, 20-, 24- or 32-bits");
196
24
            return AVERROR_PATCHWELCOME;
197
6.27k
        }
198
199
6.25k
        samples = track_size * 8LL / st->codecpar->bits_per_coded_sample;
200
201
        //use audio packet size to determine video standard
202
        //for NTSC we have one 8008-sample audio frame per five video frames
203
6.25k
        if (samples == LXF_SAMPLERATE * 5005 / 30000) {
204
703
            avpriv_set_pts_info(s->streams[0], 64, 1001, 30000);
205
5.54k
        } else {
206
            //assume PAL, but warn if we don't have 1920 samples
207
5.54k
            if (samples != LXF_SAMPLERATE / 25)
208
5.34k
                av_log(s, AV_LOG_WARNING,
209
5.34k
                       "video doesn't seem to be PAL or NTSC. guessing PAL\n");
210
211
5.54k
            avpriv_set_pts_info(s->streams[0], 64, 1, 25);
212
5.54k
        }
213
214
6.25k
        if (av_popcount(channels) * (uint64_t)track_size > INT_MAX)
215
63
            return AVERROR_INVALIDDATA;
216
        //TODO: warning if track mask != (1 << channels) - 1?
217
6.18k
        ret = av_popcount(channels) * track_size;
218
219
6.18k
        break;
220
2.37k
    default:
221
2.37k
        tmp = bytestream_get_le32(&p);
222
2.37k
        ret = bytestream_get_le32(&p);
223
2.37k
        if (tmp == 1)
224
218
            lxf->extended_size = bytestream_get_le32(&p);
225
2.37k
        break;
226
217k
    }
227
228
217k
    return ret;
229
217k
}
230
231
static int lxf_read_header(AVFormatContext *s)
232
5.92k
{
233
5.92k
    LXFDemuxContext *lxf = s->priv_data;
234
5.92k
    AVIOContext   *pb  = s->pb;
235
5.92k
    uint8_t header_data[LXF_HEADER_DATA_SIZE];
236
5.92k
    int ret;
237
5.92k
    AVStream *st;
238
5.92k
    uint32_t video_params, disk_params;
239
5.92k
    uint16_t record_date, expiration_date;
240
241
5.92k
    if ((ret = get_packet_header(s)) < 0)
242
4.66k
        return ret;
243
244
1.26k
    if (ret != LXF_HEADER_DATA_SIZE) {
245
59
        av_log(s, AV_LOG_ERROR, "expected %d B size header, got %d\n",
246
59
               LXF_HEADER_DATA_SIZE, ret);
247
59
        return AVERROR_INVALIDDATA;
248
59
    }
249
250
1.20k
    if ((ret = avio_read(pb, header_data, LXF_HEADER_DATA_SIZE)) != LXF_HEADER_DATA_SIZE)
251
10
        return ret < 0 ? ret : AVERROR_EOF;
252
253
1.19k
    if (!(st = avformat_new_stream(s, NULL)))
254
0
        return AVERROR(ENOMEM);
255
256
1.19k
    st->duration          = AV_RL32(&header_data[32]);
257
1.19k
    video_params          = AV_RL32(&header_data[40]);
258
1.19k
    record_date           = AV_RL16(&header_data[56]);
259
1.19k
    expiration_date       = AV_RL16(&header_data[58]);
260
1.19k
    disk_params           = AV_RL32(&header_data[116]);
261
262
1.19k
    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
263
1.19k
    st->codecpar->bit_rate   = 1000000 * ((video_params >> 14) & 0xFF);
264
1.19k
    st->codecpar->codec_tag  = video_params & 0xF;
265
1.19k
    st->codecpar->codec_id   = ff_codec_get_id(lxf_tags, st->codecpar->codec_tag);
266
1.19k
    ffstream(st)->need_parsing = AVSTREAM_PARSE_HEADERS;
267
268
1.19k
    av_log(s, AV_LOG_DEBUG, "record: %x = %i-%02i-%02i\n",
269
1.19k
           record_date, 1900 + (record_date & 0x7F), (record_date >> 7) & 0xF,
270
1.19k
           (record_date >> 11) & 0x1F);
271
272
1.19k
    av_log(s, AV_LOG_DEBUG, "expire: %x = %i-%02i-%02i\n",
273
1.19k
           expiration_date, 1900 + (expiration_date & 0x7F), (expiration_date >> 7) & 0xF,
274
1.19k
           (expiration_date >> 11) & 0x1F);
275
276
1.19k
    if ((video_params >> 22) & 1)
277
412
        av_log(s, AV_LOG_WARNING, "VBI data not yet supported\n");
278
279
1.19k
    if ((lxf->channels = 1 << (disk_params >> 4 & 3) + 1)) {
280
1.19k
        if (!(st = avformat_new_stream(s, NULL)))
281
0
            return AVERROR(ENOMEM);
282
283
1.19k
        st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
284
1.19k
        st->codecpar->sample_rate = LXF_SAMPLERATE;
285
1.19k
        st->codecpar->ch_layout.nb_channels = lxf->channels;
286
287
1.19k
        avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
288
1.19k
    }
289
290
1.19k
    avio_skip(s->pb, lxf->extended_size);
291
292
1.19k
    return 0;
293
1.19k
}
294
295
static int lxf_read_packet(AVFormatContext *s, AVPacket *pkt)
296
217k
{
297
217k
    LXFDemuxContext *lxf = s->priv_data;
298
217k
    AVIOContext   *pb  = s->pb;
299
217k
    uint32_t stream;
300
217k
    int ret, ret2;
301
302
217k
    if ((ret = get_packet_header(s)) < 0)
303
2.53k
        return ret;
304
305
215k
    stream = lxf->packet_type;
306
307
215k
    if (stream > 1) {
308
1.16k
        av_log(s, AV_LOG_WARNING,
309
1.16k
               "got packet with illegal stream index %"PRIu32"\n", stream);
310
1.16k
        return FFERROR_REDO;
311
1.16k
    }
312
313
214k
    if (stream == 1 && s->nb_streams < 2) {
314
0
        av_log(s, AV_LOG_ERROR, "got audio packet without having an audio stream\n");
315
0
        return AVERROR_INVALIDDATA;
316
0
    }
317
318
214k
    if ((ret2 = av_new_packet(pkt, ret)) < 0)
319
4
        return ret2;
320
321
214k
    if ((ret2 = avio_read(pb, pkt->data, ret)) != ret) {
322
91
        return ret2 < 0 ? ret2 : AVERROR_EOF;
323
91
    }
324
325
214k
    pkt->stream_index = stream;
326
327
214k
    if (!stream) {
328
        //picture type (0 = closed I, 1 = open I, 2 = P, 3 = B)
329
208k
        if (((lxf->video_format >> 22) & 0x3) < 2)
330
207k
            pkt->flags |= AV_PKT_FLAG_KEY;
331
332
208k
        pkt->dts = lxf->frame_number++;
333
208k
    }
334
335
214k
    return ret;
336
214k
}
337
338
const FFInputFormat ff_lxf_demuxer = {
339
    .p.name         = "lxf",
340
    .p.long_name    = NULL_IF_CONFIG_SMALL("VR native stream (LXF)"),
341
    .p.codec_tag    = (const AVCodecTag* const []){lxf_tags, 0},
342
    .priv_data_size = sizeof(LXFDemuxContext),
343
    .read_probe     = lxf_probe,
344
    .read_header    = lxf_read_header,
345
    .read_packet    = lxf_read_packet,
346
};