2 * DSD Stream File (DSF) demuxer
3 * Copyright (c) 2014 Peter Ross
5 * This file is part of FFmpeg.
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.
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.
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
22 #include "libavutil/intreadwrite.h"
31 static int dsf_probe(AVProbeData
*p
)
33 if (p
->buf_size
< 12 || memcmp(p
->buf
, "DSD ", 4) || AV_RL64(p
->buf
+ 4) != 28)
35 return AVPROBE_SCORE_MAX
;
38 static const uint64_t dsf_channel_layout
[] = {
42 AV_CH_LAYOUT_SURROUND
,
45 AV_CH_LAYOUT_5POINT0_BACK
,
46 AV_CH_LAYOUT_5POINT1_BACK
,
49 static void read_id3(AVFormatContext
*s
, uint64_t id3pos
)
51 ID3v2ExtraMeta
*id3v2_extra_meta
= NULL
;
52 if (avio_seek(s
->pb
, id3pos
, SEEK_SET
) < 0)
55 ff_id3v2_read(s
, ID3v2_DEFAULT_MAGIC
, &id3v2_extra_meta
, 0);
57 ff_id3v2_parse_apic(s
, &id3v2_extra_meta
);
58 ff_id3v2_free_extra_meta(&id3v2_extra_meta
);
61 static int dsf_read_header(AVFormatContext
*s
)
63 DSFContext
*dsf
= s
->priv_data
;
64 AVIOContext
*pb
= s
->pb
;
67 unsigned int channel_type
;
70 if (avio_rl64(pb
) != 28)
71 return AVERROR_INVALIDDATA
;
73 /* create primary stream before any id3 coverart streams */
74 st
= avformat_new_stream(s
, NULL
);
76 return AVERROR(ENOMEM
);
79 id3pos
= avio_rl64(pb
);
82 avio_seek(pb
, 28, SEEK_SET
);
87 if (avio_rl32(pb
) != MKTAG('f', 'm', 't', ' ') || avio_rl64(pb
) != 52)
88 return AVERROR_INVALIDDATA
;
90 if (avio_rl32(pb
) != 1) {
91 avpriv_request_sample(s
, "unknown format version");
92 return AVERROR_INVALIDDATA
;
96 avpriv_request_sample(s
, "unknown format id");
97 return AVERROR_INVALIDDATA
;
100 channel_type
= avio_rl32(pb
);
101 if (channel_type
< FF_ARRAY_ELEMS(dsf_channel_layout
))
102 st
->codec
->channel_layout
= dsf_channel_layout
[channel_type
];
103 if (!st
->codec
->channel_layout
)
104 avpriv_request_sample(s
, "channel type %i", channel_type
);
106 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
107 st
->codec
->channels
= avio_rl32(pb
);
108 st
->codec
->sample_rate
= avio_rl32(pb
) / 8;
110 switch(avio_rl32(pb
)) {
111 case 1: st
->codec
->codec_id
= AV_CODEC_ID_DSD_LSBF_PLANAR
; break;
112 case 8: st
->codec
->codec_id
= AV_CODEC_ID_DSD_MSBF_PLANAR
; break;
114 avpriv_request_sample(s
, "unknown most significant bit");
115 return AVERROR_INVALIDDATA
;
119 st
->codec
->block_align
= avio_rl32(pb
);
120 if (st
->codec
->block_align
> INT_MAX
/ st
->codec
->channels
) {
121 avpriv_request_sample(s
, "block_align overflow");
122 return AVERROR_INVALIDDATA
;
124 st
->codec
->block_align
*= st
->codec
->channels
;
129 dsf
->data_end
= avio_tell(pb
);
130 if (avio_rl32(pb
) != MKTAG('d', 'a', 't', 'a'))
131 return AVERROR_INVALIDDATA
;
132 dsf
->data_end
+= avio_rl64(pb
);
137 static int dsf_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
139 DSFContext
*dsf
= s
->priv_data
;
140 AVIOContext
*pb
= s
->pb
;
141 AVStream
*st
= s
->streams
[0];
142 int64_t pos
= avio_tell(pb
);
144 if (pos
>= dsf
->data_end
)
147 pkt
->stream_index
= 0;
148 return av_get_packet(pb
, pkt
, FFMIN(dsf
->data_end
- pos
, st
->codec
->block_align
));
151 AVInputFormat ff_dsf_demuxer
= {
153 .long_name
= NULL_IF_CONFIG_SMALL("DSD Stream File (DSF)"),
154 .priv_data_size
= sizeof(DSFContext
),
155 .read_probe
= dsf_probe
,
156 .read_header
= dsf_read_header
,
157 .read_packet
= dsf_read_packet
,
158 .flags
= AVFMT_GENERIC_INDEX
| AVFMT_NO_BYTE_SEEK
,