FFmpeg
Loading...
Searching...
No Matches
oggparseflac.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 "libavcodec/avcodec.h"
24#include "libavcodec/flac.h"
25#include "avformat.h"
26#include "internal.h"
27#include "oggdec.h"
28
29#define OGG_FLAC_METADATA_TYPE_STREAMINFO 0x7F
30#define OGG_FLAC_MAGIC "\177FLAC"
31#define OGG_FLAC_MAGIC_SIZE sizeof(OGG_FLAC_MAGIC)-1
32
33static int
35{
36 struct ogg *ogg = s->priv_data;
37 struct ogg_stream *os = ogg->streams + idx;
38 AVStream *st = s->streams[idx];
40 int mdt, ret;
41
42 if (os->buf[os->pstart] == 0xff)
43 return 0;
44
45 bytestream2_init(&gb, os->buf + os->pstart, os->psize);
46 mdt = bytestream2_get_byte(&gb) & 0x7F;
47
49 uint32_t samplerate;
50
51 if (bytestream2_get_bytes_left(&gb) < 4 + 4 + 4 + 4 + FLAC_STREAMINFO_SIZE)
53 bytestream2_skipu(&gb, 4); /* "FLAC" */
54 if (bytestream2_get_byteu(&gb) != 1) /* unsupported major version */
55 return -1;
56 bytestream2_skipu(&gb, 1 + 2); /* minor version + header count */
57 bytestream2_skipu(&gb, 4); /* "fLaC" */
58
59 /* METADATA_BLOCK_HEADER */
60 if (bytestream2_get_be32u(&gb) != FLAC_STREAMINFO_SIZE)
61 return -1;
62
66
68 return ret;
70
71 samplerate = AV_RB24(st->codecpar->extradata + 10) >> 4;
72 if (!samplerate)
74
75 avpriv_set_pts_info(st, 64, 1, samplerate);
76 } else if (mdt == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
77 ff_vorbis_stream_comment(s, st, os->buf + os->pstart + 4, os->psize - 4);
78 }
79
80 return 1;
81}
82
83static int
85{
86 struct ogg *ogg = s->priv_data;
87 struct ogg_stream *os = ogg->streams + idx;
88 AVStream *st = s->streams[idx];
89 int ret;
90
91 if (os->psize > OGG_FLAC_MAGIC_SIZE &&
92 !memcmp(
93 os->buf + os->pstart,
96 return 1;
97
98 if (os->psize > 0 &&
99 ((os->buf[os->pstart] & 0x7F) == FLAC_METADATA_TYPE_VORBIS_COMMENT)) {
100 ret = ff_vorbis_update_metadata(s, st, os->buf + os->pstart + 4,
101 os->psize - 4);
102 if (ret < 0)
103 return ret;
104
105 return 1;
106 }
107
108 return 0;
109}
110
111static int
113{
114 struct ogg *ogg = s->priv_data;
115 AVStream *st = s->streams[idx];
116 struct ogg_stream *os = ogg->streams + idx;
118 AVCodecContext *avctx;
119 int size, ret;
120 uint8_t *data;
121
122 if (!parser)
123 return -1;
124
127
129 if (!avctx) {
130 ret = AVERROR(ENOMEM);
131 goto fail;
132 }
133
134 ret = avcodec_parameters_to_context(avctx, st->codecpar);
135 if (ret < 0)
136 goto fail;
137
139 av_parser_parse2(parser, avctx,
140 &data, &size, os->buf + os->pstart, os->psize,
142
143 av_parser_close(parser);
144
145 if (avctx->sample_rate) {
146 avpriv_set_pts_info(st, 64, 1, avctx->sample_rate);
147 avcodec_free_context(&avctx);
148 return 0;
149 }
150
151 avcodec_free_context(&avctx);
152 return 1;
153fail:
154 av_parser_close(parser);
155 avcodec_free_context(&avctx);
156 return ret;
157}
158
159const struct ogg_codec ff_flac_codec = {
160 .magic = OGG_FLAC_MAGIC,
161 .magicsize = OGG_FLAC_MAGIC_SIZE,
162 .header = flac_header,
163 .nb_header = 2,
164 .packet = flac_packet,
165};
166
168 .magic = "fLaC",
169 .magicsize = 4,
170 .header = old_flac_header,
171 .nb_header = 0,
172};
Libavcodec external API header.
#define PARSER_FLAG_COMPLETE_FRAMES
Definition avcodec.h:2651
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:834
Main libavformat public API header.
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition avformat.h:612
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
#define NULL
Definition coverity.c:32
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:164
@ AV_CODEC_ID_FLAC
Definition codec_id.h:465
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
@ 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:365
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
const char data[16]
Definition mxf.c:149
int ff_vorbis_update_metadata(AVFormatContext *s, AVStream *st, const uint8_t *buf, int size)
Parse Vorbis comments, add metadata to an AVStream.
const struct ogg_codec ff_flac_codec
int ff_vorbis_stream_comment(AVFormatContext *as, AVStream *st, const uint8_t *buf, int size)
Parse Vorbis comments and add metadata to an AVStream.
const struct ogg_codec ff_old_flac_codec
#define OGG_FLAC_MAGIC_SIZE
static int old_flac_header(AVFormatContext *s, int idx)
#define OGG_FLAC_MAGIC
static int flac_header(AVFormatContext *s, int idx)
#define OGG_FLAC_METADATA_TYPE_STREAMINFO
static int flac_packet(AVFormatContext *s, int idx)
main external API structure.
Definition avcodec.h:443
int sample_rate
samples per second
Definition avcodec.h:1040
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:1333
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
enum AVStreamParseType need_parsing
Definition internal.h:321
Copyright (C) 2005 Michael Ahlberg, Måns Rullgård.
Definition oggdec.h:30
unsigned int pstart
Definition oggdec.h:71
unsigned int psize
Definition oggdec.h:72
uint8_t * buf
Definition oggdec.h:68
Definition oggdec.h:112
struct ogg_stream * streams
Definition oggdec.h:113
int size