/src/ffmpeg/libavformat/mlpdec.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * MLP and TrueHD demuxer |
3 | | * Copyright (c) 2001 Fabrice Bellard |
4 | | * Copyright (c) 2005 Alex Beregszaszi |
5 | | * Copyright (c) 2015 Carl Eugen Hoyos |
6 | | * |
7 | | * This file is part of FFmpeg. |
8 | | * |
9 | | * FFmpeg is free software; you can redistribute it and/or |
10 | | * modify it under the terms of the GNU Lesser General Public |
11 | | * License as published by the Free Software Foundation; either |
12 | | * version 2.1 of the License, or (at your option) any later version. |
13 | | * |
14 | | * FFmpeg is distributed in the hope that it will be useful, |
15 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | | * Lesser General Public License for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU Lesser General Public |
20 | | * License along with FFmpeg; if not, write to the Free Software |
21 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 | | */ |
23 | | |
24 | | #include "config_components.h" |
25 | | |
26 | | #include "avformat.h" |
27 | | #include "avio_internal.h" |
28 | | #include "demux.h" |
29 | | #include "internal.h" |
30 | | #include "rawdec.h" |
31 | | #include "libavutil/intreadwrite.h" |
32 | | #include "libavcodec/mlp.h" |
33 | | #include "libavcodec/mlp_parse.h" |
34 | | |
35 | | static int av_always_inline mlp_thd_probe(const AVProbeData *p, uint32_t sync) |
36 | 1.84M | { |
37 | 1.84M | const uint8_t *buf, *last_buf = p->buf, *end = p->buf + p->buf_size; |
38 | 1.84M | int valid = 0, size = 0; |
39 | 1.84M | int nsubframes = 0; |
40 | | |
41 | 6.94G | for (buf = p->buf; buf + 8 <= end; buf++) { |
42 | 6.94G | if (AV_RB32(buf + 4) == sync) { |
43 | 1.37M | if (last_buf + size == buf) { |
44 | 284k | valid += 1 + nsubframes / 8; |
45 | 284k | } |
46 | 1.37M | nsubframes = 0; |
47 | 1.37M | last_buf = buf; |
48 | 1.37M | size = (AV_RB16(buf) & 0xfff) * 2; |
49 | 6.94G | } else if (buf - last_buf == size) { |
50 | 3.93M | nsubframes++; |
51 | 3.93M | size += (AV_RB16(buf) & 0xfff) * 2; |
52 | 3.93M | } |
53 | 6.94G | } |
54 | 1.84M | if (valid >= 100) |
55 | 985 | return AVPROBE_SCORE_MAX; |
56 | 1.84M | return 0; |
57 | 1.84M | } |
58 | | |
59 | | static int mlp_read_header(AVFormatContext *s) |
60 | 13.8k | { |
61 | 13.8k | int ret = ff_raw_audio_read_header(s); |
62 | | |
63 | 13.8k | if (ret < 0) |
64 | 0 | return ret; |
65 | | |
66 | 13.8k | ret = ffio_ensure_seekback(s->pb, 10); |
67 | 13.8k | if (ret == 0) { |
68 | 13.8k | uint8_t buffer[10]; |
69 | 13.8k | int read, sample_rate = 0; |
70 | | |
71 | 13.8k | read = avio_read(s->pb, buffer, 10); |
72 | 13.8k | if (read == 10) { |
73 | 3.82k | switch (buffer[7]) { |
74 | 685 | case SYNC_TRUEHD: |
75 | 685 | sample_rate = mlp_samplerate(buffer[8] >> 4); |
76 | 685 | break; |
77 | 1.44k | case SYNC_MLP: |
78 | 1.44k | sample_rate = mlp_samplerate(buffer[9] >> 4); |
79 | 1.44k | break; |
80 | 3.82k | } |
81 | | |
82 | 3.82k | if (sample_rate) |
83 | 1.93k | avpriv_set_pts_info(s->streams[0], 64, 1, sample_rate); |
84 | 3.82k | } |
85 | | |
86 | 13.8k | if (read > 0) |
87 | 4.43k | avio_seek(s->pb, -read, SEEK_CUR); |
88 | 13.8k | } |
89 | | |
90 | 13.8k | return 0; |
91 | 13.8k | } |
92 | | |
93 | | #if CONFIG_MLP_DEMUXER |
94 | | static int mlp_probe(const AVProbeData *p) |
95 | 924k | { |
96 | 924k | return mlp_thd_probe(p, 0xf8726fbb); |
97 | 924k | } |
98 | | |
99 | | const FFInputFormat ff_mlp_demuxer = { |
100 | | .p.name = "mlp", |
101 | | .p.long_name = NULL_IF_CONFIG_SMALL("raw MLP"), |
102 | | .p.flags = AVFMT_GENERIC_INDEX | AVFMT_NOTIMESTAMPS, |
103 | | .p.extensions = "mlp", |
104 | | .p.priv_class = &ff_raw_demuxer_class, |
105 | | .read_probe = mlp_probe, |
106 | | .read_header = mlp_read_header, |
107 | | .read_packet = ff_raw_read_partial_packet, |
108 | | .raw_codec_id = AV_CODEC_ID_MLP, |
109 | | .priv_data_size = sizeof(FFRawDemuxerContext), |
110 | | }; |
111 | | #endif |
112 | | |
113 | | #if CONFIG_TRUEHD_DEMUXER |
114 | | static int thd_probe(const AVProbeData *p) |
115 | 924k | { |
116 | 924k | return mlp_thd_probe(p, 0xf8726fba); |
117 | 924k | } |
118 | | |
119 | | const FFInputFormat ff_truehd_demuxer = { |
120 | | .p.name = "truehd", |
121 | | .p.long_name = NULL_IF_CONFIG_SMALL("raw TrueHD"), |
122 | | .p.flags = AVFMT_GENERIC_INDEX | AVFMT_NOTIMESTAMPS, |
123 | | .p.extensions = "thd", |
124 | | .p.priv_class = &ff_raw_demuxer_class, |
125 | | .read_probe = thd_probe, |
126 | | .read_header = mlp_read_header, |
127 | | .read_packet = ff_raw_read_partial_packet, |
128 | | .raw_codec_id = AV_CODEC_ID_TRUEHD, |
129 | | .priv_data_size = sizeof(FFRawDemuxerContext), |
130 | | }; |
131 | | #endif |