FFmpeg
Loading...
Searching...
No Matches
spdifdec.c
Go to the documentation of this file.
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"
32
33#include "avformat.h"
34#include "demux.h"
35#include "internal.h"
36#include "spdif.h"
37
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 switch (data_type & 0xff) {
48 case IEC61937_AC3:
49 *offset = AC3_FRAME_SIZE << 2;
50 *codec = AV_CODEC_ID_AC3;
51 break;
54 *codec = AV_CODEC_ID_MP1;
55 break;
58 *codec = AV_CODEC_ID_MP3;
59 break;
61 *offset = 4608;
62 *codec = AV_CODEC_ID_MP3;
63 break;
65 ret = av_adts_header_parse(buf, &samples, &frames);
66 if (ret < 0) {
67 if (s) /* be silent during a probe */
68 av_log(s, AV_LOG_ERROR, "Invalid AAC packet in IEC 61937\n");
69 return ret;
70 }
71 *offset = samples << 2;
72 *codec = AV_CODEC_ID_AAC;
73 break;
76 *codec = AV_CODEC_ID_MP1;
77 break;
80 *codec = AV_CODEC_ID_MP2;
81 break;
84 *codec = AV_CODEC_ID_MP3;
85 break;
86 case IEC61937_DTS1:
87 *offset = 2048;
88 *codec = AV_CODEC_ID_DTS;
89 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 case IEC61937_EAC3:
99 *offset = 24576;
100 *codec = AV_CODEC_ID_EAC3;
101 break;
102 default:
103 if (s) { /* be silent during a probe */
104 avpriv_request_sample(s, "Data type 0x%04x in IEC 61937",
105 data_type);
106 }
108 }
109 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
116static int spdif_probe(const AVProbeData *p)
117{
118 enum AVCodecID codec;
119 return ff_spdif_probe (p->buf, p->buf_size, &codec);
120}
121
122int ff_spdif_probe(const uint8_t *p_buf, int buf_size, enum AVCodecID *codec)
123{
124 const uint8_t *buf = p_buf;
125 const uint8_t *probe_end = p_buf + FFMIN(2 * SPDIF_MAX_OFFSET, buf_size - 1);
126 const uint8_t *expected_code = buf + 7;
127 uint32_t state = 0;
128 int sync_codes = 0;
129 int consecutive_codes = 0;
130 int offset;
131
132 for (; buf < probe_end; buf++) {
133 state = (state << 8) | *buf;
134
136 && buf[1] < 0x37) {
137 sync_codes++;
138
139 if (buf == expected_code) {
140 if (++consecutive_codes >= 2)
141 return AVPROBE_SCORE_MAX;
142 } else
143 consecutive_codes = 0;
144
145 /* spdif_get_offset_and_codec() parses AV_AAC_ADTS_HEADER_SIZE
146 * bytes starting at buf[5] (the payload after the 4 byte sync and
147 * the Pc/Pd burst header), so that many bytes must be available. */
148 if (buf + 5 + AV_AAC_ADTS_HEADER_SIZE > p_buf + buf_size)
149 break;
150
151 /* continue probing to find more sync codes */
152 probe_end = FFMIN(buf + SPDIF_MAX_OFFSET, p_buf + buf_size - 1);
153
154 /* skip directly to the next sync code */
155 if (!spdif_get_offset_and_codec(NULL, (buf[2] << 8) | buf[1],
156 &buf[5], &offset, codec)) {
157 if (buf + offset >= p_buf + buf_size)
158 break;
159 expected_code = buf + offset;
160 buf = expected_code - 7;
161 }
162 }
163 }
164
165 if (!sync_codes)
166 return 0;
167
168 if (sync_codes >= 6)
169 /* good amount of sync codes but with unexpected offsets */
171
172 /* some sync codes were found */
173 return AVPROBE_SCORE_EXTENSION / 4;
174}
175
177{
178 s->ctx_flags |= AVFMTCTX_NOHEADER;
179 return 0;
180}
181
183{
184 switch (type & 0xff) {
185 case IEC61937_EAC3:
186 return code << 3;
187 default:
188 return code;
189 }
190}
191
193{
194 AVIOContext *pb = s->pb;
195 enum IEC61937DataType data_type;
196 enum AVCodecID codec_id;
197 uint32_t state = 0;
198 int pkt_size_bits, offset, ret;
199
200 while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) {
201 state = (state << 8) | avio_r8(pb);
202 if (avio_feof(pb))
203 return AVERROR_EOF;
204 }
205
206 data_type = avio_rl16(pb);
207 pkt_size_bits = spdif_get_pkt_size_bits(data_type, avio_rl16(pb));
208
209 if (pkt_size_bits % 16)
210 avpriv_request_sample(s, "Packet not ending at a 16-bit boundary");
211
212 ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3);
213 if (ret)
214 return ret;
215
216 pkt->pos = avio_tell(pb) - BURST_HEADER_SIZE;
217
218 if (avio_read(pb, pkt->data, pkt->size) < pkt->size) {
219 return AVERROR_EOF;
220 }
221 ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1);
222
223 ret = spdif_get_offset_and_codec(s, data_type, pkt->data,
224 &offset, &codec_id);
225 if (ret < 0) {
226 return ret;
227 }
228
229 /* skip over the padding to the beginning of the next frame */
230 avio_skip(pb, offset - pkt->size - BURST_HEADER_SIZE);
231
232 if (!s->nb_streams) {
233 /* first packet, create a stream */
235 if (!st) {
236 return AVERROR(ENOMEM);
237 }
242 else
244 } else if (codec_id != s->streams[0]->codecpar->codec_id) {
245 avpriv_report_missing_feature(s, "Codec change in IEC 61937");
247 }
248
249 if (!s->bit_rate && s->streams[0]->codecpar->sample_rate)
250 /* stream bitrate matches 16-bit stereo PCM bitrate for currently
251 supported codecs */
252 s->bit_rate = 2 * 16LL * s->streams[0]->codecpar->sample_rate;
253
254 return 0;
255}
256
258 .p.name = "spdif",
259 .p.long_name = NULL_IF_CONFIG_SMALL("IEC 61937 (compressed data in S/PDIF)"),
260 .p.flags = AVFMT_GENERIC_INDEX,
261 .read_probe = spdif_probe,
262 .read_header = spdif_read_header,
263 .read_packet = ff_spdif_read_packet,
264};
#define AC3_FRAME_SIZE
Definition ac3defs.h:32
int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames)
Extract the number of samples and frames from AAC data.
Definition adts_parser.c:30
#define AV_AAC_ADTS_HEADER_SIZE
Definition adts_parser.h:25
const FFInputFormat ff_spdif_demuxer
Definition spdifdec.c:257
Main libavformat public API header.
#define AVPROBE_SCORE_MAX
maximum score
Definition avformat.h:483
#define AVFMTCTX_NOHEADER
signal that no header is present (streams are added dynamically)
Definition avformat.h:1284
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition avformat.h:481
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition avformat.h:499
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition avformat.h:612
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition avformat.h:611
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
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition aviobuf.c:321
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:615
int avio_r8(AVIOContext *s)
Definition aviobuf.c:606
byte swapping routines
#define AV_BSWAP16C(x)
Definition bswap.h:47
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
static AVPacket * pkt
static struct @346255127015250356166251341105367306144006377143 state
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
@ AV_CODEC_ID_EAC3
Definition codec_id.h:493
@ AV_CODEC_ID_MP1
Definition codec_id.h:495
@ AV_CODEC_ID_MP2
Definition codec_id.h:453
@ AV_CODEC_ID_DTS
Definition codec_id.h:457
@ AV_CODEC_ID_AAC
Definition codec_id.h:455
@ AV_CODEC_ID_AC3
Definition codec_id.h:456
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition codec_id.h:454
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition packet.c:98
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
cl_device_type type
unsigned offset
Definition libaomenc.c:763
static av_always_inline FFStream * ffstream(AVStream *st)
Definition internal.h:365
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
#define FFMIN(a, b)
Definition macros.h:49
#define FFALIGN(x, a)
Definition macros.h:78
void ff_spdif_bswap_buf16(uint16_t *dst, const uint16_t *src, int w)
Definition spdif.c:26
IEC61937DataType
Definition spdif.h:32
@ IEC61937_MPEG1_LAYER1
MPEG-1 layer 1.
Definition spdif.h:34
@ IEC61937_DTS3
DTS type III (2048 samples)
Definition spdif.h:43
@ IEC61937_MPEG1_LAYER23
MPEG-1 layer 2 or 3 data or MPEG-2 without extension.
Definition spdif.h:35
@ IEC61937_MPEG2_EXT
MPEG-2 data with extension.
Definition spdif.h:36
@ IEC61937_DTS2
DTS type II (1024 samples)
Definition spdif.h:42
@ IEC61937_AC3
AC-3 data.
Definition spdif.h:33
@ IEC61937_MPEG2_AAC
MPEG-2 AAC ADTS.
Definition spdif.h:37
@ IEC61937_MPEG2_LAYER2_LSF
MPEG-2, layer-2 low sampling frequency.
Definition spdif.h:39
@ IEC61937_EAC3
E-AC-3 data.
Definition spdif.h:51
@ IEC61937_MPEG2_LAYER1_LSF
MPEG-2, layer-1 low sampling frequency.
Definition spdif.h:38
@ IEC61937_DTS1
DTS type I (512 samples)
Definition spdif.h:41
@ IEC61937_MPEG2_LAYER3_LSF
MPEG-2, layer-3 low sampling frequency.
Definition spdif.h:40
#define SYNCWORD1
Definition spdif.h:28
int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition spdifdec.c:192
#define SYNCWORD2
Definition spdif.h:29
static const uint16_t spdif_mpeg_pkt_offset[2][3]
Definition spdif.h:56
#define BURST_HEADER_SIZE
Definition spdif.h:30
int ff_spdif_probe(const uint8_t *p_buf, int buf_size, enum AVCodecID *codec)
Definition spdifdec.c:122
static int spdif_get_pkt_size_bits(int type, int code)
Definition spdifdec.c:182
static int spdif_read_header(AVFormatContext *s)
Definition spdifdec.c:176
int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition spdifdec.c:192
static int spdif_probe(const AVProbeData *p)
Definition spdifdec.c:116
static int spdif_get_offset_and_codec(AVFormatContext *s, enum IEC61937DataType data_type, const char *buf, int *offset, enum AVCodecID *codec)
Definition spdifdec.c:38
#define SPDIF_MAX_OFFSET
Definition spdifdec.c:114
const uint8_t * code
Definition spdifenc.c:433
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
Bytestream IO Context.
Definition avio.h:160
This structure stores compressed data.
Definition packet.h:580
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
enum AVStreamParseType need_parsing
Definition internal.h:321
#define avpriv_request_sample(...)
#define av_log(a,...)
static int frames
Definition movenc.c:67
enum AVCodecID codec_id