FFmpeg
Loading...
Searching...
No Matches
libvorbisdec.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2002 Mark Hills <mark@pogo.org.uk>
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 <string.h>
22#include <vorbis/vorbisenc.h>
23
24#include "avcodec.h"
25#include "bytestream.h"
26#include "codec_internal.h"
27#include "decode.h"
28
29typedef struct OggVorbisDecContext {
30 vorbis_info vi; /**< vorbis_info used during init */
31 vorbis_dsp_state vd; /**< DSP state used for analysis */
32 vorbis_block vb; /**< vorbis_block used for analysis */
33 vorbis_comment vc; /**< VorbisComment info */
34 ogg_packet op; /**< ogg packet */
36
37static int oggvorbis_decode_close(AVCodecContext *avccontext);
38
40{
41 OggVorbisDecContext *context = avccontext->priv_data ;
42 uint8_t *p= avccontext->extradata;
43 int i, hsizes[3], ret;
44 unsigned char *headers[3], *extradata = avccontext->extradata;
45
46 if(! avccontext->extradata_size || ! p) {
47 av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n");
48 return AVERROR(EINVAL);
49 }
50
51 vorbis_info_init(&context->vi) ;
52 vorbis_comment_init(&context->vc) ;
53
54 if(p[0] == 0 && p[1] == 30) {
55 int sizesum = 0;
56 for(i = 0; i < 3; i++){
57 hsizes[i] = bytestream_get_be16((const uint8_t **)&p);
58 sizesum += 2 + hsizes[i];
59 if (sizesum > avccontext->extradata_size) {
60 av_log(avccontext, AV_LOG_ERROR, "vorbis extradata too small\n");
62 goto error;
63 }
64
65 headers[i] = p;
66 p += hsizes[i];
67 }
68 } else if(*p == 2) {
69 unsigned int offset = 1;
70 unsigned int sizesum = 1;
71 p++;
72 for(i=0; i<2; i++) {
73 hsizes[i] = 0;
74 while((*p == 0xFF) && (sizesum < avccontext->extradata_size)) {
75 hsizes[i] += 0xFF;
76 offset++;
77 sizesum += 1 + 0xFF;
78 p++;
79 }
80 hsizes[i] += *p;
81 offset++;
82 sizesum += 1 + *p;
83 if(sizesum > avccontext->extradata_size) {
84 av_log(avccontext, AV_LOG_ERROR,
85 "vorbis header sizes damaged\n");
87 goto error;
88 }
89 p++;
90 }
91 hsizes[2] = avccontext->extradata_size - hsizes[0]-hsizes[1]-offset;
92#if 0
93 av_log(avccontext, AV_LOG_DEBUG,
94 "vorbis header sizes: %d, %d, %d, / extradata_len is %d \n",
95 hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size);
96#endif
97 headers[0] = extradata + offset;
98 headers[1] = extradata + offset + hsizes[0];
99 headers[2] = extradata + offset + hsizes[0] + hsizes[1];
100 } else {
101 av_log(avccontext, AV_LOG_ERROR,
102 "vorbis initial header len is wrong: %d\n", *p);
104 goto error;
105 }
106
107 for(i=0; i<3; i++){
108 context->op.b_o_s= i==0;
109 context->op.bytes = hsizes[i];
110 context->op.packet = headers[i];
111 if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){
112 av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1);
114 goto error;
115 }
116 }
117
118 if (context->vi.rate <= 0 || context->vi.rate > INT_MAX) {
119 av_log(avccontext, AV_LOG_ERROR, "vorbis rate is invalid\n");
121 goto error;
122 }
123
126 avccontext->ch_layout.nb_channels = context->vi.channels;
127 avccontext->sample_rate = context->vi.rate;
128 avccontext->sample_fmt = AV_SAMPLE_FMT_FLTP;
129 avccontext->time_base= (AVRational){1, avccontext->sample_rate};
130
131 vorbis_synthesis_init(&context->vd, &context->vi);
132 vorbis_block_init(&context->vd, &context->vb);
133
134 return 0 ;
135
136 error:
137 oggvorbis_decode_close(avccontext);
138 return ret;
139}
140
141
143 int *got_frame_ptr, AVPacket *avpkt)
144{
145 OggVorbisDecContext *context = avccontext->priv_data ;
146 float **pcm ;
147 ogg_packet *op= &context->op;
148 int samples, total_samples;
149 int ret;
150
151 if(!avpkt->size){
152 //FIXME flush
153 return 0;
154 }
155
156 frame->nb_samples = 8192*4;
157 if ((ret = ff_get_buffer(avccontext, frame, 0)) < 0)
158 return ret;
159
160 op->packet = avpkt->data;
161 op->bytes = avpkt->size;
162
163// av_log(avccontext, AV_LOG_DEBUG, "%d %d %d %"PRId64" %"PRId64" %d %d\n", op->bytes, op->b_o_s, op->e_o_s, op->granulepos, op->packetno, buf_size, context->vi.rate);
164
165/* for(i=0; i<op->bytes; i++)
166 av_log(avccontext, AV_LOG_DEBUG, "%02X ", op->packet[i]);
167 av_log(avccontext, AV_LOG_DEBUG, "\n");*/
168
169 if(vorbis_synthesis(&context->vb, op) == 0)
170 vorbis_synthesis_blockin(&context->vd, &context->vb) ;
171
172 total_samples = 0 ;
173
174 while((samples = vorbis_synthesis_pcmout(&context->vd, &pcm)) > 0) {
175 for (int ch = 0; ch < context->vi.channels; ch++)
176 memcpy((float *)frame->extended_data[ch] + total_samples, pcm[ch], samples * sizeof(float));
177 total_samples += samples ;
178 vorbis_synthesis_read(&context->vd, samples) ;
179 }
180
181 frame->nb_samples = total_samples;
182 *got_frame_ptr = total_samples > 0;
183 return avpkt->size;
184}
185
186
188{
189 OggVorbisDecContext *context = avccontext->priv_data ;
190
191 vorbis_block_clear(&context->vb);
192 vorbis_dsp_clear(&context->vd);
193 vorbis_info_clear(&context->vi) ;
194 vorbis_comment_clear(&context->vc) ;
195
196 return 0 ;
197}
198
199
201 .p.name = "libvorbis",
202 CODEC_LONG_NAME("libvorbis"),
203 .p.type = AVMEDIA_TYPE_AUDIO,
204 .p.id = AV_CODEC_ID_VORBIS,
206 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
207 .priv_data_size = sizeof(OggVorbisDecContext),
210 .close = oggvorbis_decode_close,
211};
const FFCodec ff_libvorbis_decoder
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1777
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition codec.h:79
#define AV_CODEC_CAP_CHANNEL_CONF
Codec should fill in channel configuration and samplerate instead of container.
Definition codec.h:94
@ AV_CODEC_ID_VORBIS
Definition codec_id.h:458
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition samplefmt.h:66
unsigned offset
Definition libaomenc.c:763
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition anm.c:76
#define av_cold
Definition attributes.h:117
static int oggvorbis_decode_frame(AVCodecContext *avccontext, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt)
static int oggvorbis_decode_close(AVCodecContext *avccontext)
static av_cold int oggvorbis_decode_init(AVCodecContext *avccontext)
static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize, int64_t *fpos)
find the next Ogg packet
Definition oggdec.c:503
enum AVChannelOrder order
Channel order used in this layout.
int nb_channels
Number of channels in this layout.
main external API structure.
Definition avcodec.h:443
AVChannelLayout ch_layout
Audio channel layout.
Definition avcodec.h:1055
enum AVSampleFormat sample_fmt
audio sample format
Definition avcodec.h:1047
int sample_rate
samples per second
Definition avcodec.h:1040
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avcodec.h:547
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition avcodec.h:526
int extradata_size
Definition avcodec.h:527
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
Rational number (pair of numerator and denominator).
Definition rational.h:58
vorbis_block vb
vorbis_block used for analysis
vorbis_comment vc
VorbisComment info.
vorbis_info vi
vorbis_info used during init
vorbis_dsp_state vd
DSP state used for analysis.
ogg_packet op
ogg packet
#define av_log(a,...)
static void error(const char *err)