Coverage Report

Created: 2024-09-06 07:53

/src/ffmpeg/libavformat/dtshddec.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Raw DTS-HD demuxer
3
 * Copyright (c) 2012 Paul B Mahol
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 "libavutil/intreadwrite.h"
23
#include "libavutil/dict.h"
24
#include "libavutil/mem.h"
25
#include "libavcodec/dca.h"
26
#include "avformat.h"
27
#include "demux.h"
28
#include "internal.h"
29
30
937
#define AUPR_HDR 0x415550522D484452
31
#define AUPRINFO 0x41555052494E464F
32
#define BITSHVTB 0x4249545348565442
33
#define BLACKOUT 0x424C41434B4F5554
34
#define BRANCHPT 0x4252414E43485054
35
#define BUILDVER 0x4255494C44564552
36
#define CORESSMD 0x434F524553534D44
37
358k
#define DTSHDHDR 0x4454534844484452
38
#define EXTSS_MD 0x45585453535f4d44
39
115
#define FILEINFO 0x46494C45494E464F
40
#define NAVI_TBL 0x4E4156492D54424C
41
3.95k
#define STRMDATA 0x5354524D44415441
42
#define TIMECODE 0x54494D45434F4445
43
44
typedef struct DTSHDDemuxContext {
45
    uint64_t    data_end;
46
} DTSHDDemuxContext;
47
48
static int dtshd_probe(const AVProbeData *p)
49
358k
{
50
358k
    if (AV_RB64(p->buf) == DTSHDHDR)
51
45
        return AVPROBE_SCORE_MAX;
52
358k
    return 0;
53
358k
}
54
55
static int dtshd_read_header(AVFormatContext *s)
56
8.22k
{
57
8.22k
    DTSHDDemuxContext *dtshd = s->priv_data;
58
8.22k
    AVIOContext *pb = s->pb;
59
8.22k
    uint64_t chunk_type, chunk_size;
60
8.22k
    int64_t duration, orig_nb_samples, data_start;
61
8.22k
    AVStream *st;
62
8.22k
    int ret;
63
8.22k
    char *value;
64
65
8.22k
    st = avformat_new_stream(s, NULL);
66
8.22k
    if (!st)
67
0
        return AVERROR(ENOMEM);
68
8.22k
    st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
69
8.22k
    st->codecpar->codec_id   = AV_CODEC_ID_DTS;
70
8.22k
    ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL_RAW;
71
72
11.4k
    for (;;) {
73
11.4k
        chunk_type = avio_rb64(pb);
74
11.4k
        chunk_size = avio_rb64(pb);
75
76
11.4k
        if (avio_feof(pb))
77
4.01k
            break;
78
79
7.47k
        if (chunk_size < 4) {
80
7
            av_log(s, AV_LOG_ERROR, "chunk size too small\n");
81
7
            return AVERROR_INVALIDDATA;
82
7
        }
83
7.46k
        if (chunk_size > ((uint64_t)1 << 61)) {
84
113
            av_log(s, AV_LOG_ERROR, "chunk size too big\n");
85
113
            return AVERROR_INVALIDDATA;
86
113
        }
87
88
7.35k
        switch (chunk_type) {
89
3.95k
        case STRMDATA:
90
3.95k
            data_start = avio_tell(pb);
91
3.95k
            dtshd->data_end = data_start + chunk_size;
92
3.95k
            if (dtshd->data_end <= chunk_size)
93
0
                return AVERROR_INVALIDDATA;
94
3.95k
            if (!(pb->seekable & AVIO_SEEKABLE_NORMAL))
95
3.47k
                goto break_loop;
96
480
            goto skip;
97
480
            break;
98
937
        case AUPR_HDR:
99
937
            if (chunk_size < 21)
100
5
                return AVERROR_INVALIDDATA;
101
932
            avio_skip(pb, 3);
102
932
            st->codecpar->sample_rate = avio_rb24(pb);
103
932
            if (!st->codecpar->sample_rate)
104
35
                return AVERROR_INVALIDDATA;
105
897
            duration  = avio_rb32(pb); // num_frames
106
897
            duration *= avio_rb16(pb); // samples_per_frames
107
897
            st->duration = duration;
108
897
            orig_nb_samples  = avio_rb32(pb);
109
897
            orig_nb_samples <<= 8;
110
897
            orig_nb_samples |= avio_r8(pb);
111
897
            st->codecpar->ch_layout.nb_channels = ff_dca_count_chs_for_mask(avio_rb16(pb));
112
897
            st->codecpar->initial_padding = avio_rb16(pb);
113
897
            st->codecpar->trailing_padding = FFMAX(st->duration - orig_nb_samples - st->codecpar->initial_padding, 0);
114
897
            avio_skip(pb, chunk_size - 21);
115
897
            break;
116
115
        case FILEINFO:
117
115
            if (chunk_size > INT_MAX)
118
33
                goto skip;
119
82
            value = av_malloc(chunk_size);
120
82
            if (!value)
121
0
                goto skip;
122
82
            avio_read(pb, value, chunk_size);
123
82
            value[chunk_size - 1] = 0;
124
82
            av_dict_set(&s->metadata, "fileinfo", value,
125
82
                        AV_DICT_DONT_STRDUP_VAL);
126
82
            break;
127
2.34k
        default:
128
2.85k
skip:
129
2.85k
            ret = avio_skip(pb, chunk_size);
130
2.85k
            if (ret < 0)
131
583
                return ret;
132
7.35k
        };
133
3.25k
    }
134
135
4.01k
    if (!dtshd->data_end)
136
3.78k
        return AVERROR_EOF;
137
138
231
    avio_seek(pb, data_start, SEEK_SET);
139
140
3.70k
break_loop:
141
3.70k
    if (st->codecpar->sample_rate)
142
543
        avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
143
144
3.70k
    return 0;
145
231
}
146
147
static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
148
74.6k
{
149
74.6k
    DTSHDDemuxContext *dtshd = s->priv_data;
150
74.6k
    int64_t size, left;
151
74.6k
    int ret;
152
153
74.6k
    left = dtshd->data_end - avio_tell(s->pb);
154
74.6k
    size = FFMIN(left, 1024);
155
74.6k
    if (size <= 0)
156
258
        return AVERROR_EOF;
157
158
74.4k
    ret = av_get_packet(s->pb, pkt, size);
159
74.4k
    if (ret < 0)
160
10.2k
        return ret;
161
162
64.2k
    pkt->stream_index = 0;
163
164
64.2k
    return ret;
165
74.4k
}
166
167
const FFInputFormat ff_dtshd_demuxer = {
168
    .p.name         = "dtshd",
169
    .p.long_name    = NULL_IF_CONFIG_SMALL("raw DTS-HD"),
170
    .p.flags        = AVFMT_GENERIC_INDEX,
171
    .p.extensions   = "dtshd",
172
    .priv_data_size = sizeof(DTSHDDemuxContext),
173
    .read_probe     = dtshd_probe,
174
    .read_header    = dtshd_read_header,
175
    .read_packet    = raw_read_packet,
176
    .raw_codec_id   = AV_CODEC_ID_DTS,
177
};