FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
dsfdec.c
Go to the documentation of this file.
1
/*
2
* DSD Stream File (DSF) demuxer
3
* Copyright (c) 2014 Peter Ross
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
#include "
libavutil/intreadwrite.h
"
23
#include "
avformat.h
"
24
#include "
internal.h
"
25
#include "
id3v2.h
"
26
27
typedef
struct
{
28
uint64_t
data_end
;
29
}
DSFContext
;
30
31
static
int
dsf_probe
(
AVProbeData
*p)
32
{
33
if
(p->
buf_size
< 12 || memcmp(p->
buf
,
"DSD "
, 4) ||
AV_RL64
(p->
buf
+ 4) != 28)
34
return
0;
35
return
AVPROBE_SCORE_MAX
;
36
}
37
38
static
const
uint64_t
dsf_channel_layout
[] = {
39
0,
40
AV_CH_LAYOUT_MONO
,
41
AV_CH_LAYOUT_STEREO
,
42
AV_CH_LAYOUT_SURROUND
,
43
AV_CH_LAYOUT_QUAD
,
44
AV_CH_LAYOUT_4POINT0
,
45
AV_CH_LAYOUT_5POINT0_BACK
,
46
AV_CH_LAYOUT_5POINT1_BACK
,
47
};
48
49
static
void
read_id3
(
AVFormatContext
*
s
, uint64_t id3pos)
50
{
51
ID3v2ExtraMeta
*id3v2_extra_meta = NULL;
52
if
(
avio_seek
(s->
pb
, id3pos, SEEK_SET) < 0)
53
return
;
54
55
ff_id3v2_read
(s,
ID3v2_DEFAULT_MAGIC
, &id3v2_extra_meta, 0);
56
if
(id3v2_extra_meta)
57
ff_id3v2_parse_apic
(s, &id3v2_extra_meta);
58
ff_id3v2_free_extra_meta
(&id3v2_extra_meta);
59
}
60
61
static
int
dsf_read_header
(
AVFormatContext
*
s
)
62
{
63
DSFContext
*dsf = s->
priv_data
;
64
AVIOContext
*pb = s->
pb
;
65
AVStream
*st;
66
uint64_t id3pos;
67
unsigned
int
channel_type;
68
69
avio_skip
(pb, 4);
70
if
(
avio_rl64
(pb) != 28)
71
return
AVERROR_INVALIDDATA
;
72
73
/* create primary stream before any id3 coverart streams */
74
st =
avformat_new_stream
(s, NULL);
75
if
(!st)
76
return
AVERROR
(ENOMEM);
77
78
avio_skip
(pb, 8);
79
id3pos =
avio_rl64
(pb);
80
if
(pb->
seekable
) {
81
read_id3
(s, id3pos);
82
avio_seek
(pb, 28, SEEK_SET);
83
}
84
85
/* fmt chunk */
86
87
if
(
avio_rl32
(pb) !=
MKTAG
(
'f'
,
'm'
,
't'
,
' '
) ||
avio_rl64
(pb) != 52)
88
return
AVERROR_INVALIDDATA
;
89
90
if
(
avio_rl32
(pb) != 1) {
91
avpriv_request_sample
(s,
"unknown format version"
);
92
return
AVERROR_INVALIDDATA
;
93
}
94
95
if
(
avio_rl32
(pb)) {
96
avpriv_request_sample
(s,
"unknown format id"
);
97
return
AVERROR_INVALIDDATA
;
98
}
99
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);
105
106
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
107
st->
codec
->
channels
=
avio_rl32
(pb);
108
st->
codec
->
sample_rate
=
avio_rl32
(pb) / 8;
109
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
;
113
default
:
114
avpriv_request_sample
(s,
"unknown most significant bit"
);
115
return
AVERROR_INVALIDDATA
;
116
}
117
118
avio_skip
(pb, 8);
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
;
123
}
124
st->
codec
->
block_align
*= st->
codec
->
channels
;
125
avio_skip
(pb, 4);
126
127
/* data chunk */
128
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);
133
134
return
0;
135
}
136
137
static
int
dsf_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
138
{
139
DSFContext
*dsf = s->
priv_data
;
140
AVIOContext
*pb = s->
pb
;
141
AVStream
*st = s->
streams
[0];
142
int64_t pos =
avio_tell
(pb);
143
144
if
(pos >= dsf->
data_end
)
145
return
AVERROR_EOF
;
146
147
pkt->
stream_index
= 0;
148
return
av_get_packet
(pb, pkt,
FFMIN
(dsf->
data_end
- pos, st->
codec
->
block_align
));
149
}
150
151
AVInputFormat
ff_dsf_demuxer
= {
152
.
name
=
"dsf"
,
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
,
159
};
Generated on Fri Dec 5 2014 04:42:11 for FFmpeg by
1.8.2