Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * IEC 61937 demuxer | ||
3 | * Copyright (c) 2010 Anssi Hannula <anssi.hannula at iki.fi> | ||
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 | /** | ||
23 | * @file | ||
24 | * IEC 61937 demuxer, used for compressed data in S/PDIF | ||
25 | * @author Anssi Hannula | ||
26 | */ | ||
27 | |||
28 | #include "libavutil/bswap.h" | ||
29 | |||
30 | #include "libavcodec/ac3defs.h" | ||
31 | #include "libavcodec/adts_parser.h" | ||
32 | |||
33 | #include "avformat.h" | ||
34 | #include "demux.h" | ||
35 | #include "internal.h" | ||
36 | #include "spdif.h" | ||
37 | |||
38 | 2194 | static int spdif_get_offset_and_codec(AVFormatContext *s, | |
39 | enum IEC61937DataType data_type, | ||
40 | const char *buf, int *offset, | ||
41 | enum AVCodecID *codec) | ||
42 | { | ||
43 | uint32_t samples; | ||
44 | uint8_t frames; | ||
45 | int ret; | ||
46 | |||
47 |
6/13✓ Branch 0 taken 107 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1189 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 662 times.
✓ Branch 12 taken 20 times.
|
2194 | switch (data_type & 0xff) { |
48 | 107 | case IEC61937_AC3: | |
49 | 107 | *offset = AC3_FRAME_SIZE << 2; | |
50 | 107 | *codec = AV_CODEC_ID_AC3; | |
51 | 107 | break; | |
52 | ✗ | case IEC61937_MPEG1_LAYER1: | |
53 | ✗ | *offset = spdif_mpeg_pkt_offset[1][0]; | |
54 | ✗ | *codec = AV_CODEC_ID_MP1; | |
55 | ✗ | break; | |
56 | 114 | case IEC61937_MPEG1_LAYER23: | |
57 | 114 | *offset = spdif_mpeg_pkt_offset[1][0]; | |
58 | 114 | *codec = AV_CODEC_ID_MP3; | |
59 | 114 | break; | |
60 | ✗ | case IEC61937_MPEG2_EXT: | |
61 | ✗ | *offset = 4608; | |
62 | ✗ | *codec = AV_CODEC_ID_MP3; | |
63 | ✗ | break; | |
64 | 102 | case IEC61937_MPEG2_AAC: | |
65 | 102 | ret = av_adts_header_parse(buf, &samples, &frames); | |
66 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 86 times.
|
102 | if (ret < 0) { |
67 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | if (s) /* be silent during a probe */ |
68 | ✗ | av_log(s, AV_LOG_ERROR, "Invalid AAC packet in IEC 61937\n"); | |
69 | 16 | return ret; | |
70 | } | ||
71 | 86 | *offset = samples << 2; | |
72 | 86 | *codec = AV_CODEC_ID_AAC; | |
73 | 86 | break; | |
74 | ✗ | case IEC61937_MPEG2_LAYER1_LSF: | |
75 | ✗ | *offset = spdif_mpeg_pkt_offset[0][0]; | |
76 | ✗ | *codec = AV_CODEC_ID_MP1; | |
77 | ✗ | break; | |
78 | ✗ | case IEC61937_MPEG2_LAYER2_LSF: | |
79 | ✗ | *offset = spdif_mpeg_pkt_offset[0][1]; | |
80 | ✗ | *codec = AV_CODEC_ID_MP2; | |
81 | ✗ | break; | |
82 | ✗ | case IEC61937_MPEG2_LAYER3_LSF: | |
83 | ✗ | *offset = spdif_mpeg_pkt_offset[0][2]; | |
84 | ✗ | *codec = AV_CODEC_ID_MP3; | |
85 | ✗ | break; | |
86 | 1189 | case IEC61937_DTS1: | |
87 | 1189 | *offset = 2048; | |
88 | 1189 | *codec = AV_CODEC_ID_DTS; | |
89 | 1189 | break; | |
90 | ✗ | case IEC61937_DTS2: | |
91 | ✗ | *offset = 4096; | |
92 | ✗ | *codec = AV_CODEC_ID_DTS; | |
93 | ✗ | break; | |
94 | ✗ | case IEC61937_DTS3: | |
95 | ✗ | *offset = 8192; | |
96 | ✗ | *codec = AV_CODEC_ID_DTS; | |
97 | ✗ | break; | |
98 | 662 | case IEC61937_EAC3: | |
99 | 662 | *offset = 24576; | |
100 | 662 | *codec = AV_CODEC_ID_EAC3; | |
101 | 662 | break; | |
102 | 20 | default: | |
103 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | if (s) { /* be silent during a probe */ |
104 | ✗ | avpriv_request_sample(s, "Data type 0x%04x in IEC 61937", | |
105 | data_type); | ||
106 | } | ||
107 | 20 | return AVERROR_PATCHWELCOME; | |
108 | } | ||
109 | 2158 | return 0; | |
110 | } | ||
111 | |||
112 | /* Largest offset between bursts we currently handle, i.e. AAC with | ||
113 | samples = 4096 */ | ||
114 | #define SPDIF_MAX_OFFSET 16384 | ||
115 | |||
116 | 7186 | static int spdif_probe(const AVProbeData *p) | |
117 | { | ||
118 | enum AVCodecID codec; | ||
119 | 7186 | return ff_spdif_probe (p->buf, p->buf_size, &codec); | |
120 | } | ||
121 | |||
122 | 7698 | int ff_spdif_probe(const uint8_t *p_buf, int buf_size, enum AVCodecID *codec) | |
123 | { | ||
124 | 7698 | const uint8_t *buf = p_buf; | |
125 |
2/2✓ Branch 0 taken 5848 times.
✓ Branch 1 taken 1850 times.
|
7698 | const uint8_t *probe_end = p_buf + FFMIN(2 * SPDIF_MAX_OFFSET, buf_size - 1); |
126 | 7698 | const uint8_t *expected_code = buf + 7; | |
127 | 7698 | uint32_t state = 0; | |
128 | 7698 | int sync_codes = 0; | |
129 | 7698 | int consecutive_codes = 0; | |
130 | int offset; | ||
131 | |||
132 |
2/2✓ Branch 0 taken 100012728 times.
✓ Branch 1 taken 7680 times.
|
100020408 | for (; buf < probe_end; buf++) { |
133 | 100012728 | state = (state << 8) | *buf; | |
134 | |||
135 |
2/2✓ Branch 0 taken 101 times.
✓ Branch 1 taken 100012627 times.
|
100012728 | if (state == (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2)) |
136 |
1/2✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
|
101 | && buf[1] < 0x37) { |
137 | 101 | sync_codes++; | |
138 | |||
139 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 90 times.
|
101 | if (buf == expected_code) { |
140 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7 times.
|
11 | if (++consecutive_codes >= 2) |
141 | 4 | return AVPROBE_SCORE_MAX; | |
142 | } else | ||
143 | 90 | consecutive_codes = 0; | |
144 | |||
145 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
|
97 | if (buf + 4 + AV_AAC_ADTS_HEADER_SIZE > p_buf + buf_size) |
146 | ✗ | break; | |
147 | |||
148 | /* continue probing to find more sync codes */ | ||
149 | 97 | probe_end = FFMIN(buf + SPDIF_MAX_OFFSET, p_buf + buf_size - 1); | |
150 | |||
151 | /* skip directly to the next sync code */ | ||
152 |
2/2✓ Branch 0 taken 61 times.
✓ Branch 1 taken 36 times.
|
97 | if (!spdif_get_offset_and_codec(NULL, (buf[2] << 8) | buf[1], |
153 | 97 | &buf[5], &offset, codec)) { | |
154 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 47 times.
|
61 | if (buf + offset >= p_buf + buf_size) |
155 | 14 | break; | |
156 | 47 | expected_code = buf + offset; | |
157 | 47 | buf = expected_code - 7; | |
158 | } | ||
159 | } | ||
160 | } | ||
161 | |||
162 |
2/2✓ Branch 0 taken 7651 times.
✓ Branch 1 taken 43 times.
|
7694 | if (!sync_codes) |
163 | 7651 | return 0; | |
164 | |||
165 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 40 times.
|
43 | if (sync_codes >= 6) |
166 | /* good amount of sync codes but with unexpected offsets */ | ||
167 | 3 | return AVPROBE_SCORE_EXTENSION; | |
168 | |||
169 | /* some sync codes were found */ | ||
170 | 40 | return AVPROBE_SCORE_EXTENSION / 4; | |
171 | } | ||
172 | |||
173 | 7 | static int spdif_read_header(AVFormatContext *s) | |
174 | { | ||
175 | 7 | s->ctx_flags |= AVFMTCTX_NOHEADER; | |
176 | 7 | return 0; | |
177 | } | ||
178 | |||
179 | 2097 | static int spdif_get_pkt_size_bits(int type, int code) | |
180 | { | ||
181 |
2/2✓ Branch 0 taken 652 times.
✓ Branch 1 taken 1445 times.
|
2097 | switch (type & 0xff) { |
182 | 652 | case IEC61937_EAC3: | |
183 | 652 | return code << 3; | |
184 | 1445 | default: | |
185 | 1445 | return code; | |
186 | } | ||
187 | } | ||
188 | |||
189 | 2114 | int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt) | |
190 | { | ||
191 | 2114 | AVIOContext *pb = s->pb; | |
192 | enum IEC61937DataType data_type; | ||
193 | enum AVCodecID codec_id; | ||
194 | 2114 | uint32_t state = 0; | |
195 | int pkt_size_bits, offset, ret; | ||
196 | |||
197 |
2/2✓ Branch 0 taken 260309 times.
✓ Branch 1 taken 2097 times.
|
262406 | while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) { |
198 | 260309 | state = (state << 8) | avio_r8(pb); | |
199 |
2/2✓ Branch 1 taken 17 times.
✓ Branch 2 taken 260292 times.
|
260309 | if (avio_feof(pb)) |
200 | 17 | return AVERROR_EOF; | |
201 | } | ||
202 | |||
203 | 2097 | data_type = avio_rl16(pb); | |
204 | 2097 | pkt_size_bits = spdif_get_pkt_size_bits(data_type, avio_rl16(pb)); | |
205 | |||
206 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2097 times.
|
2097 | if (pkt_size_bits % 16) |
207 | ✗ | avpriv_request_sample(s, "Packet not ending at a 16-bit boundary"); | |
208 | |||
209 | 2097 | ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3); | |
210 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2097 times.
|
2097 | if (ret) |
211 | ✗ | return ret; | |
212 | |||
213 | 2097 | pkt->pos = avio_tell(pb) - BURST_HEADER_SIZE; | |
214 | |||
215 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2097 times.
|
2097 | if (avio_read(pb, pkt->data, pkt->size) < pkt->size) { |
216 | ✗ | return AVERROR_EOF; | |
217 | } | ||
218 | 2097 | ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1); | |
219 | |||
220 | 2097 | ret = spdif_get_offset_and_codec(s, data_type, pkt->data, | |
221 | &offset, &codec_id); | ||
222 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2097 times.
|
2097 | if (ret < 0) { |
223 | ✗ | return ret; | |
224 | } | ||
225 | |||
226 | /* skip over the padding to the beginning of the next frame */ | ||
227 | 2097 | avio_skip(pb, offset - pkt->size - BURST_HEADER_SIZE); | |
228 | |||
229 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2090 times.
|
2097 | if (!s->nb_streams) { |
230 | /* first packet, create a stream */ | ||
231 | 7 | AVStream *st = avformat_new_stream(s, NULL); | |
232 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (!st) { |
233 | ✗ | return AVERROR(ENOMEM); | |
234 | } | ||
235 | 7 | st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; | |
236 | 7 | st->codecpar->codec_id = codec_id; | |
237 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
|
7 | if (codec_id == AV_CODEC_ID_EAC3) |
238 | 1 | ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL; | |
239 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2090 times.
|
2090 | } else if (codec_id != s->streams[0]->codecpar->codec_id) { |
240 | ✗ | avpriv_report_missing_feature(s, "Codec change in IEC 61937"); | |
241 | ✗ | return AVERROR_PATCHWELCOME; | |
242 | } | ||
243 | |||
244 |
4/4✓ Branch 0 taken 1408 times.
✓ Branch 1 taken 689 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1406 times.
|
2097 | if (!s->bit_rate && s->streams[0]->codecpar->sample_rate) |
245 | /* stream bitrate matches 16-bit stereo PCM bitrate for currently | ||
246 | supported codecs */ | ||
247 | 2 | s->bit_rate = 2 * 16LL * s->streams[0]->codecpar->sample_rate; | |
248 | |||
249 | 2097 | return 0; | |
250 | } | ||
251 | |||
252 | const FFInputFormat ff_spdif_demuxer = { | ||
253 | .p.name = "spdif", | ||
254 | .p.long_name = NULL_IF_CONFIG_SMALL("IEC 61937 (compressed data in S/PDIF)"), | ||
255 | .p.flags = AVFMT_GENERIC_INDEX, | ||
256 | .read_probe = spdif_probe, | ||
257 | .read_header = spdif_read_header, | ||
258 | .read_packet = ff_spdif_read_packet, | ||
259 | }; | ||
260 |