FFmpeg
Loading...
Searching...
No Matches
flac.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2005 Matthieu CASTET
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <stdlib.h>
22#include "libavutil/mem.h"
23#include "libavcodec/avcodec.h"
25#include "libavcodec/flac.h"
30
31#define OGG_FLAC_METADATA_TYPE_STREAMINFO 0x7F
32#define OGG_FLAC_MAGIC "\177FLAC"
33#define OGG_FLAC_MAGIC_SIZE sizeof(OGG_FLAC_MAGIC)-1
34#define OGG_FLAC_STREAMINFO_OFFSET (OGG_FLAC_MAGIC_SIZE + 1 + 1 + 2 + 4 + 4)
35
36static int
38{
39 struct ogg *ogg = s->priv_data;
40 struct ogg_stream *os = ogg->streams + idx;
41 AVStream *st = s->streams[idx];
43 int mdt, ret;
44
45 if (os->buf[os->pstart] == 0xff)
46 return 0;
47
48 bytestream2_init(&gb, os->buf + os->pstart, os->psize);
49 mdt = bytestream2_get_byte(&gb) & 0x7F;
50
52 uint32_t samplerate;
53
54 if (bytestream2_get_bytes_left(&gb) < 4 + 4 + 4 + 4 + FLAC_STREAMINFO_SIZE)
56 bytestream2_skipu(&gb, 4); /* "FLAC" */
57 if (bytestream2_get_byteu(&gb) != 1) /* unsupported major version */
58 return -1;
59 bytestream2_skipu(&gb, 1 + 2); /* minor version + header count */
60 bytestream2_skipu(&gb, 4); /* "fLaC" */
61
62 /* METADATA_BLOCK_HEADER */
63 if (bytestream2_get_be32u(&gb) != FLAC_STREAMINFO_SIZE)
64 return -1;
65
69
71 return ret;
73
74 samplerate = AV_RB24(st->codecpar->extradata + 10) >> 4;
75 if (!samplerate)
77
78 avpriv_set_pts_info(st, 64, 1, samplerate);
79 } else if (mdt == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
80 ff_vorbis_comment_read_stream(s, st, os->buf + os->pstart + 4, os->psize - 4);
81 }
82
83 return 1;
84}
85
86static int
88{
89 struct ogg *ogg = s->priv_data;
90 struct ogg_stream *os = ogg->streams + idx;
91 AVStream *st = s->streams[idx];
92 int ret;
93
94 if (os->psize > OGG_FLAC_MAGIC_SIZE &&
95 !memcmp(
96 os->buf + os->pstart,
99 /* A later link's STREAMINFO: the decoder is still set up for the previous one. */
104 if (!os->new_extradata)
105 return AVERROR(ENOMEM);
107 }
108 return 1;
109 }
110
111 if (os->psize > 0 &&
112 ((os->buf[os->pstart] & 0x7F) == FLAC_METADATA_TYPE_VORBIS_COMMENT)) {
113 ret = ff_vorbis_update_metadata(s, st, os->buf + os->pstart + 4,
114 os->psize - 4);
115 if (ret < 0)
116 return ret;
117
118 return 1;
119 }
120
121 return 0;
122}
123
124static int
126{
127 struct ogg *ogg = s->priv_data;
128 AVStream *st = s->streams[idx];
129 struct ogg_stream *os = ogg->streams + idx;
131 AVCodecContext *avctx;
132 int size, ret;
133 uint8_t *data;
134
135 if (!parser)
136 return -1;
137
140
142 if (!avctx) {
143 ret = AVERROR(ENOMEM);
144 goto fail;
145 }
146
148 if (ret < 0)
149 goto fail;
150
152 av_parser_parse2(parser, avctx,
153 &data, &size, os->buf + os->pstart, os->psize,
155
156 av_parser_close(parser);
157
158 if (avctx->sample_rate) {
159 avpriv_set_pts_info(st, 64, 1, avctx->sample_rate);
160 avcodec_free_context(&avctx);
161 return 0;
162 }
163
164 avcodec_free_context(&avctx);
165 return 1;
166fail:
167 av_parser_close(parser);
168 avcodec_free_context(&avctx);
169 return ret;
170}
171
172const struct ogg_codec ff_flac_codec = {
173 .magic = OGG_FLAC_MAGIC,
174 .magicsize = OGG_FLAC_MAGIC_SIZE,
175 .header = flac_header,
176 .nb_header = 2,
177 .packet = flac_packet,
178};
179
181 .magic = "fLaC",
182 .magicsize = 4,
183 .header = old_flac_header,
184 .nb_header = 0,
185};
Libavcodec external API header.
#define PARSER_FLAG_COMPLETE_FRAMES
Definition avcodec.h:2672
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:865
Main libavformat public API header.
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition avformat.h:614
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
Definition bytestream.h:174
static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition bytestream.h:277
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition bytestream.h:158
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition bytestream.h:137
#define s(width, name)
Definition cbs_vp9.c:198
int avcodec_parameters_to_context(AVCodecContext *codec, const AVCodecParameters *par)
Definition codec_par.c:206
int ff_vorbis_comment_read_stream(AVFormatContext *as, AVStream *st, const uint8_t *buf, int size)
Parse Vorbis comments and add metadata to an AVStream.
Definition reader.c:73
#define NULL
Definition coverity.c:32
int ret
Definition ffplay.c:391
FLAC (Free Lossless Audio Codec) common stuff.
@ FLAC_METADATA_TYPE_VORBIS_COMMENT
Definition flac.h:50
#define FLAC_STREAMINFO_SIZE
Definition flac.h:32
#define fail
Definition test.h:479
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition options.c:149
void avcodec_free_context(AVCodecContext **avctx)
Free the codec context and everything associated with it and write NULL to the provided pointer.
Definition options.c:168
@ AV_CODEC_ID_FLAC
Definition codec_id.h:471
AVCodecParserContext * av_parser_init(enum AVCodecID codec_id)
Definition parser.c:35
void av_parser_close(AVCodecParserContext *s)
Definition parser.c:203
int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int64_t pts, int64_t dts, int64_t pos)
Parse a packet.
Definition parser.c:120
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition mem.c:408
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_RB24(x)
static av_always_inline FFStream * ffstream(AVStream *st)
Definition internal.h:390
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition utils.c:237
#define OGG_FLAC_STREAMINFO_OFFSET
Definition flac.c:34
#define OGG_FLAC_MAGIC_SIZE
Definition flac.c:33
static int old_flac_header(AVFormatContext *s, int idx)
Definition flac.c:125
#define OGG_FLAC_MAGIC
Definition flac.c:32
static int flac_header(AVFormatContext *s, int idx)
Definition flac.c:37
#define OGG_FLAC_METADATA_TYPE_STREAMINFO
Definition flac.c:31
static int flac_packet(AVFormatContext *s, int idx)
Definition flac.c:87
int ff_vorbis_update_metadata(AVFormatContext *s, AVStream *st, const uint8_t *buf, int size)
Parse Vorbis comments, add metadata to an AVStream.
Definition vorbis.c:125
const struct ogg_codec ff_flac_codec
Definition flac.c:172
const struct ogg_codec ff_old_flac_codec
Definition flac.c:180
Memory handling functions.
const char data[16]
Definition mxf.c:149
main external API structure.
Definition avcodec.h:443
int sample_rate
samples per second
Definition avcodec.h:1044
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
Format I/O context.
Definition avformat.h:1401
Stream structure.
Definition avformat.h:768
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:791
enum AVStreamParseType need_parsing
Definition internal.h:346
Copyright (C) 2005 Michael Ahlberg, Måns Rullgård.
Definition mapping.h:30
uint8_t * new_extradata
Definition mapping.h:99
size_t new_extradata_size
Definition mapping.h:100
unsigned int pstart
Definition mapping.h:71
unsigned int psize
Definition mapping.h:72
uint8_t * buf
Definition mapping.h:68
Definition mapping.h:112
struct ogg_stream * streams
Definition mapping.h:113
#define av_freep(p)
int size