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"
30 #include "libavcodec/bytestream.h"
32 static int flac_read_header(AVFormatContext
*s
)
34 int ret
, metadata_last
=0, metadata_type
, metadata_size
, found_streaminfo
=0;
37 AVStream
*st
= avformat_new_stream(s
, NULL
);
39 return AVERROR(ENOMEM
);
40 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
41 st
->codec
->codec_id
= AV_CODEC_ID_FLAC
;
42 st
->need_parsing
= AVSTREAM_PARSE_FULL_RAW
;
43 /* the parameters will be extracted from the compressed bitstream */
45 /* if fLaC marker is not found, assume there is no header */
46 if (avio_rl32(s
->pb
) != MKTAG('f','L','a','C')) {
47 avio_seek(s
->pb
, -4, SEEK_CUR
);
51 /* process metadata blocks */
52 while (!avio_feof(s
->pb
) && !metadata_last
) {
53 avio_read(s
->pb
, header
, 4);
54 flac_parse_block_header(header
, &metadata_last
, &metadata_type
,
56 switch (metadata_type
) {
57 /* allocate and read metadata block for supported types */
58 case FLAC_METADATA_TYPE_STREAMINFO
:
59 case FLAC_METADATA_TYPE_CUESHEET
:
60 case FLAC_METADATA_TYPE_PICTURE
:
61 case FLAC_METADATA_TYPE_VORBIS_COMMENT
:
62 buffer
= av_mallocz(metadata_size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
64 return AVERROR(ENOMEM
);
66 if (avio_read(s
->pb
, buffer
, metadata_size
) != metadata_size
) {
67 RETURN_ERROR(AVERROR(EIO
));
70 /* skip metadata block for unsupported types */
72 ret
= avio_skip(s
->pb
, metadata_size
);
77 if (metadata_type
== FLAC_METADATA_TYPE_STREAMINFO
) {
79 /* STREAMINFO can only occur once */
80 if (found_streaminfo
) {
81 RETURN_ERROR(AVERROR_INVALIDDATA
);
83 if (metadata_size
!= FLAC_STREAMINFO_SIZE
) {
84 RETURN_ERROR(AVERROR_INVALIDDATA
);
87 st
->codec
->extradata
= buffer
;
88 st
->codec
->extradata_size
= metadata_size
;
91 /* get codec params from STREAMINFO header */
92 avpriv_flac_parse_streaminfo(st
->codec
, &si
, st
->codec
->extradata
);
94 /* set time base and duration */
95 if (si
.samplerate
> 0) {
96 avpriv_set_pts_info(st
, 64, 1, si
.samplerate
);
98 st
->duration
= si
.samples
;
100 } else if (metadata_type
== FLAC_METADATA_TYPE_CUESHEET
) {
103 const uint8_t *offset
;
104 int i
, chapters
, track
, ti
;
105 if (metadata_size
< 431)
106 RETURN_ERROR(AVERROR_INVALIDDATA
);
107 offset
= buffer
+ 395;
108 chapters
= bytestream_get_byte(&offset
) - 1;
110 RETURN_ERROR(AVERROR_INVALIDDATA
);
111 for (i
= 0; i
< chapters
; i
++) {
112 if (offset
+ 36 - buffer
> metadata_size
)
113 RETURN_ERROR(AVERROR_INVALIDDATA
);
114 start
= bytestream_get_be64(&offset
);
115 track
= bytestream_get_byte(&offset
);
116 bytestream_get_buffer(&offset
, isrc
, 12);
119 ti
= bytestream_get_byte(&offset
);
120 if (ti
<= 0) RETURN_ERROR(AVERROR_INVALIDDATA
);
122 avpriv_new_chapter(s
, track
, st
->time_base
, start
, AV_NOPTS_VALUE
, isrc
);
125 } else if (metadata_type
== FLAC_METADATA_TYPE_PICTURE
) {
126 ret
= ff_flac_parse_picture(s
, buffer
, metadata_size
);
129 av_log(s
, AV_LOG_ERROR
, "Error parsing attached picture.\n");
133 /* STREAMINFO must be the first block */
134 if (!found_streaminfo
) {
135 RETURN_ERROR(AVERROR_INVALIDDATA
);
137 /* process supported blocks other than STREAMINFO */
138 if (metadata_type
== FLAC_METADATA_TYPE_VORBIS_COMMENT
) {
139 AVDictionaryEntry
*chmask
;
141 ret
= ff_vorbis_comment(s
, &s
->metadata
, buffer
, metadata_size
, 1);
143 av_log(s
, AV_LOG_WARNING
, "error parsing VorbisComment metadata\n");
144 } else if (ret
> 0) {
145 s
->event_flags
|= AVFMT_EVENT_FLAG_METADATA_UPDATED
;
148 /* parse the channels mask if present */
149 chmask
= av_dict_get(s
->metadata
, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", NULL
, 0);
151 uint64_t mask
= strtol(chmask
->value
, NULL
, 0);
152 if (!mask
|| mask
& ~0x3ffffULL
) {
153 av_log(s
, AV_LOG_WARNING
,
154 "Invalid value of WAVEFORMATEXTENSIBLE_CHANNEL_MASK\n");
156 st
->codec
->channel_layout
= mask
;
157 av_dict_set(&s
->metadata
, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", NULL
, 0);
165 ret
= ff_replaygain_export(st
, s
->metadata
);
176 static int flac_probe(AVProbeData
*p
)
178 if (p
->buf_size
< 4 || memcmp(p
->buf
, "fLaC", 4))
180 return AVPROBE_SCORE_EXTENSION
;
183 static av_unused
int64_t flac_read_timestamp(AVFormatContext
*s
, int stream_index
,
184 int64_t *ppos
, int64_t pos_limit
)
186 AVPacket pkt
, out_pkt
;
187 AVStream
*st
= s
->streams
[stream_index
];
188 AVCodecParserContext
*parser
;
190 int64_t pts
= AV_NOPTS_VALUE
;
192 if (avio_seek(s
->pb
, *ppos
, SEEK_SET
) < 0)
193 return AV_NOPTS_VALUE
;
195 av_init_packet(&pkt
);
196 parser
= av_parser_init(st
->codec
->codec_id
);
198 return AV_NOPTS_VALUE
;
200 parser
->flags
|= PARSER_FLAG_USE_CODEC_TS
;
203 ret
= ff_raw_read_partial_packet(s
, &pkt
);
205 if (ret
== AVERROR(EAGAIN
))
210 av_init_packet(&out_pkt
);
211 ret
= av_parser_parse2(parser
, st
->codec
,
212 &out_pkt
.data
, &out_pkt
.size
, pkt
.data
, pkt
.size
,
213 pkt
.pts
, pkt
.dts
, *ppos
);
215 av_free_packet(&pkt
);
217 int size
= out_pkt
.size
;
218 if (parser
->pts
!= AV_NOPTS_VALUE
){
219 // seeking may not have started from beginning of a frame
220 // calculate frame start position from next frame backwards
221 *ppos
= parser
->next_frame_offset
- size
;
227 av_parser_close(parser
);
231 AVInputFormat ff_flac_demuxer
= {
233 .long_name
= NULL_IF_CONFIG_SMALL("raw FLAC"),
234 .read_probe
= flac_probe
,
235 .read_header
= flac_read_header
,
236 .read_packet
= ff_raw_read_partial_packet
,
237 .read_timestamp
= flac_read_timestamp
,
238 .flags
= AVFMT_GENERIC_INDEX
,
239 .extensions
= "flac",
240 .raw_codec_id
= AV_CODEC_ID_FLAC
,