3 * Copyright (c) 2001 Fabrice Bellard
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 "libavcodec/flac.h"
24 #include "flac_picture.h"
28 #include "vorbiscomment.h"
29 #include "replaygain.h"
31 static int flac_read_header(AVFormatContext
*s
)
33 int ret
, metadata_last
=0, metadata_type
, metadata_size
, found_streaminfo
=0;
36 AVStream
*st
= avformat_new_stream(s
, NULL
);
38 return AVERROR(ENOMEM
);
39 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
40 st
->codec
->codec_id
= AV_CODEC_ID_FLAC
;
41 st
->need_parsing
= AVSTREAM_PARSE_FULL_RAW
;
42 /* the parameters will be extracted from the compressed bitstream */
44 /* if fLaC marker is not found, assume there is no header */
45 if (avio_rl32(s
->pb
) != MKTAG('f','L','a','C')) {
46 avio_seek(s
->pb
, -4, SEEK_CUR
);
50 /* process metadata blocks */
51 while (!avio_feof(s
->pb
) && !metadata_last
) {
52 avio_read(s
->pb
, header
, 4);
53 flac_parse_block_header(header
, &metadata_last
, &metadata_type
,
55 switch (metadata_type
) {
56 /* allocate and read metadata block for supported types */
57 case FLAC_METADATA_TYPE_STREAMINFO
:
58 case FLAC_METADATA_TYPE_CUESHEET
:
59 case FLAC_METADATA_TYPE_PICTURE
:
60 case FLAC_METADATA_TYPE_VORBIS_COMMENT
:
61 buffer
= av_mallocz(metadata_size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
63 return AVERROR(ENOMEM
);
65 if (avio_read(s
->pb
, buffer
, metadata_size
) != metadata_size
) {
66 RETURN_ERROR(AVERROR(EIO
));
69 /* skip metadata block for unsupported types */
71 ret
= avio_skip(s
->pb
, metadata_size
);
76 if (metadata_type
== FLAC_METADATA_TYPE_STREAMINFO
) {
80 /* STREAMINFO can only occur once */
81 if (found_streaminfo
) {
82 RETURN_ERROR(AVERROR_INVALIDDATA
);
84 if (metadata_size
!= FLAC_STREAMINFO_SIZE
) {
85 RETURN_ERROR(AVERROR_INVALIDDATA
);
88 st
->codec
->extradata
= buffer
;
89 st
->codec
->extradata_size
= metadata_size
;
92 /* get sample rate and sample count from STREAMINFO header;
93 * other parameters will be extracted by the parser */
94 samplerate
= AV_RB24(st
->codec
->extradata
+ 10) >> 4;
95 samples
= (AV_RB64(st
->codec
->extradata
+ 13) >> 24) & ((1ULL << 36) - 1);
97 /* set time base and duration */
99 avpriv_set_pts_info(st
, 64, 1, samplerate
);
101 st
->duration
= samples
;
103 } else if (metadata_type
== FLAC_METADATA_TYPE_CUESHEET
) {
106 const uint8_t *offset
;
107 int i
, chapters
, track
, ti
;
108 if (metadata_size
< 431)
109 RETURN_ERROR(AVERROR_INVALIDDATA
);
110 offset
= buffer
+ 395;
111 chapters
= bytestream_get_byte(&offset
) - 1;
113 RETURN_ERROR(AVERROR_INVALIDDATA
);
114 for (i
= 0; i
< chapters
; i
++) {
115 if (offset
+ 36 - buffer
> metadata_size
)
116 RETURN_ERROR(AVERROR_INVALIDDATA
);
117 start
= bytestream_get_be64(&offset
);
118 track
= bytestream_get_byte(&offset
);
119 bytestream_get_buffer(&offset
, isrc
, 12);
122 ti
= bytestream_get_byte(&offset
);
123 if (ti
<= 0) RETURN_ERROR(AVERROR_INVALIDDATA
);
125 avpriv_new_chapter(s
, track
, st
->time_base
, start
, AV_NOPTS_VALUE
, isrc
);
128 } else if (metadata_type
== FLAC_METADATA_TYPE_PICTURE
) {
129 ret
= ff_flac_parse_picture(s
, buffer
, metadata_size
);
132 av_log(s
, AV_LOG_ERROR
, "Error parsing attached picture.\n");
136 /* STREAMINFO must be the first block */
137 if (!found_streaminfo
) {
138 RETURN_ERROR(AVERROR_INVALIDDATA
);
140 /* process supported blocks other than STREAMINFO */
141 if (metadata_type
== FLAC_METADATA_TYPE_VORBIS_COMMENT
) {
142 AVDictionaryEntry
*chmask
;
144 ret
= ff_vorbis_comment(s
, &s
->metadata
, buffer
, metadata_size
, 1);
146 av_log(s
, AV_LOG_WARNING
, "error parsing VorbisComment metadata\n");
147 } else if (ret
> 0) {
148 s
->event_flags
|= AVFMT_EVENT_FLAG_METADATA_UPDATED
;
151 /* parse the channels mask if present */
152 chmask
= av_dict_get(s
->metadata
, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", NULL
, 0);
154 uint64_t mask
= strtol(chmask
->value
, NULL
, 0);
155 if (!mask
|| mask
& ~0x3ffffULL
) {
156 av_log(s
, AV_LOG_WARNING
,
157 "Invalid value of WAVEFORMATEXTENSIBLE_CHANNEL_MASK\n");
159 st
->codec
->channel_layout
= mask
;
160 av_dict_set(&s
->metadata
, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", NULL
, 0);
168 ret
= ff_replaygain_export(st
, s
->metadata
);
179 static int flac_probe(AVProbeData
*p
)
181 if (p
->buf_size
< 4 || memcmp(p
->buf
, "fLaC", 4))
183 return AVPROBE_SCORE_EXTENSION
;
186 static av_unused
int64_t flac_read_timestamp(AVFormatContext
*s
, int stream_index
,
187 int64_t *ppos
, int64_t pos_limit
)
189 AVPacket pkt
, out_pkt
;
190 AVStream
*st
= s
->streams
[stream_index
];
191 AVCodecParserContext
*parser
;
193 int64_t pts
= AV_NOPTS_VALUE
;
195 if (avio_seek(s
->pb
, *ppos
, SEEK_SET
) < 0)
196 return AV_NOPTS_VALUE
;
198 av_init_packet(&pkt
);
199 parser
= av_parser_init(st
->codec
->codec_id
);
201 return AV_NOPTS_VALUE
;
203 parser
->flags
|= PARSER_FLAG_USE_CODEC_TS
;
206 ret
= ff_raw_read_partial_packet(s
, &pkt
);
208 if (ret
== AVERROR(EAGAIN
))
213 av_init_packet(&out_pkt
);
214 ret
= av_parser_parse2(parser
, st
->codec
,
215 &out_pkt
.data
, &out_pkt
.size
, pkt
.data
, pkt
.size
,
216 pkt
.pts
, pkt
.dts
, *ppos
);
218 av_free_packet(&pkt
);
220 int size
= out_pkt
.size
;
221 if (parser
->pts
!= AV_NOPTS_VALUE
){
222 // seeking may not have started from beginning of a frame
223 // calculate frame start position from next frame backwards
224 *ppos
= parser
->next_frame_offset
- size
;
230 av_parser_close(parser
);
234 AVInputFormat ff_flac_demuxer
= {
236 .long_name
= NULL_IF_CONFIG_SMALL("raw FLAC"),
237 .read_probe
= flac_probe
,
238 .read_header
= flac_read_header
,
239 .read_packet
= ff_raw_read_partial_packet
,
240 .read_timestamp
= flac_read_timestamp
,
241 .flags
= AVFMT_GENERIC_INDEX
,
242 .extensions
= "flac",
243 .raw_codec_id
= AV_CODEC_ID_FLAC
,