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"
33 static int dsf_probe(const AVProbeData
*p
)
35 if (p
->buf_size
< 12 || memcmp(p
->buf
, "DSD ", 4) || AV_RL64(p
->buf
+ 4) != 28)
37 return AVPROBE_SCORE_MAX
;
40 static const uint64_t dsf_channel_layout
[] = {
44 AV_CH_LAYOUT_SURROUND
,
47 AV_CH_LAYOUT_5POINT0_BACK
,
48 AV_CH_LAYOUT_5POINT1_BACK
,
51 static void read_id3(AVFormatContext
*s
, uint64_t id3pos
)
53 ID3v2ExtraMeta
*id3v2_extra_meta
= NULL
;
54 if (avio_seek(s
->pb
, id3pos
, SEEK_SET
) < 0)
57 ff_id3v2_read(s
, ID3v2_DEFAULT_MAGIC
, &id3v2_extra_meta
, 0);
58 if (id3v2_extra_meta
) {
59 ff_id3v2_parse_apic(s
, id3v2_extra_meta
);
60 ff_id3v2_parse_chapters(s
, id3v2_extra_meta
);
62 ff_id3v2_free_extra_meta(&id3v2_extra_meta
);
65 static int dsf_read_header(AVFormatContext
*s
)
67 DSFContext
*dsf
= s
->priv_data
;
68 AVIOContext
*pb
= s
->pb
;
71 unsigned int channel_type
;
74 if (avio_rl64(pb
) != 28)
75 return AVERROR_INVALIDDATA
;
77 /* create primary stream before any id3 coverart streams */
78 st
= avformat_new_stream(s
, NULL
);
80 return AVERROR(ENOMEM
);
83 id3pos
= avio_rl64(pb
);
84 if (pb
->seekable
& AVIO_SEEKABLE_NORMAL
) {
86 avio_seek(pb
, 28, SEEK_SET
);
91 if (avio_rl32(pb
) != MKTAG('f', 'm', 't', ' ') || avio_rl64(pb
) != 52)
92 return AVERROR_INVALIDDATA
;
94 if (avio_rl32(pb
) != 1) {
95 avpriv_request_sample(s
, "unknown format version");
96 return AVERROR_INVALIDDATA
;
100 avpriv_request_sample(s
, "unknown format id");
101 return AVERROR_INVALIDDATA
;
104 channel_type
= avio_rl32(pb
);
105 if (channel_type
< FF_ARRAY_ELEMS(dsf_channel_layout
))
106 st
->codecpar
->channel_layout
= dsf_channel_layout
[channel_type
];
107 if (!st
->codecpar
->channel_layout
)
108 avpriv_request_sample(s
, "channel type %i", channel_type
);
110 st
->codecpar
->codec_type
= AVMEDIA_TYPE_AUDIO
;
111 st
->codecpar
->channels
= avio_rl32(pb
);
112 st
->codecpar
->sample_rate
= avio_rl32(pb
) / 8;
114 if (st
->codecpar
->channels
<= 0)
115 return AVERROR_INVALIDDATA
;
117 switch(avio_rl32(pb
)) {
118 case 1: st
->codecpar
->codec_id
= AV_CODEC_ID_DSD_LSBF_PLANAR
; break;
119 case 8: st
->codecpar
->codec_id
= AV_CODEC_ID_DSD_MSBF_PLANAR
; break;
121 avpriv_request_sample(s
, "unknown most significant bit");
122 return AVERROR_INVALIDDATA
;
125 dsf
->audio_size
= avio_rl64(pb
) / 8 * st
->codecpar
->channels
;
126 st
->codecpar
->block_align
= avio_rl32(pb
);
127 if (st
->codecpar
->block_align
> INT_MAX
/ st
->codecpar
->channels
|| st
->codecpar
->block_align
<= 0) {
128 avpriv_request_sample(s
, "block_align invalid");
129 return AVERROR_INVALIDDATA
;
131 st
->codecpar
->block_align
*= st
->codecpar
->channels
;
132 st
->codecpar
->bit_rate
= st
->codecpar
->channels
* 8LL * st
->codecpar
->sample_rate
;
133 avpriv_set_pts_info(st
, 64, 1, st
->codecpar
->sample_rate
);
138 dsf
->data_end
= avio_tell(pb
);
139 if (avio_rl32(pb
) != MKTAG('d', 'a', 't', 'a'))
140 return AVERROR_INVALIDDATA
;
141 dsf
->data_size
= avio_rl64(pb
) - 12;
142 dsf
->data_end
+= dsf
->data_size
+ 12;
143 s
->internal
->data_offset
= avio_tell(pb
);
148 static int dsf_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
150 DSFContext
*dsf
= s
->priv_data
;
151 AVIOContext
*pb
= s
->pb
;
152 AVStream
*st
= s
->streams
[0];
153 int64_t pos
= avio_tell(pb
);
156 if (pos
>= dsf
->data_end
)
159 if (dsf
->data_size
> dsf
->audio_size
) {
160 int last_packet
= pos
== (dsf
->data_end
- st
->codecpar
->block_align
);
163 int64_t data_pos
= pos
- s
->internal
->data_offset
;
164 int64_t packet_size
= dsf
->audio_size
- data_pos
;
165 int64_t skip_size
= dsf
->data_size
- data_pos
- packet_size
;
169 if (packet_size
<= 0 || skip_size
<= 0)
170 return AVERROR_INVALIDDATA
;
172 if ((ret
= av_new_packet(pkt
, packet_size
)) < 0)
175 for (ch
= 0; ch
< st
->codecpar
->channels
; ch
++) {
176 ret
= avio_read(pb
, dst
, packet_size
/ st
->codecpar
->channels
);
177 if (ret
< packet_size
/ st
->codecpar
->channels
)
181 avio_skip(pb
, skip_size
/ st
->codecpar
->channels
);
185 pkt
->stream_index
= 0;
186 pkt
->pts
= (pos
- s
->internal
->data_offset
) / st
->codecpar
->channels
;
187 pkt
->duration
= packet_size
/ st
->codecpar
->channels
;
191 ret
= av_get_packet(pb
, pkt
, FFMIN(dsf
->data_end
- pos
, st
->codecpar
->block_align
));
195 pkt
->stream_index
= 0;
196 pkt
->pts
= (pos
- s
->internal
->data_offset
) / st
->codecpar
->channels
;
197 pkt
->duration
= st
->codecpar
->block_align
/ st
->codecpar
->channels
;
202 AVInputFormat ff_dsf_demuxer
= {
204 .long_name
= NULL_IF_CONFIG_SMALL("DSD Stream File (DSF)"),
205 .priv_data_size
= sizeof(DSFContext
),
206 .read_probe
= dsf_probe
,
207 .read_header
= dsf_read_header
,
208 .read_packet
= dsf_read_packet
,
209 .flags
= AVFMT_GENERIC_INDEX
| AVFMT_NO_BYTE_SEEK
,