FFmpeg  4.4.6
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 <vorbis/vorbisenc.h>
22 
23 #include "avcodec.h"
24 #include "bytestream.h"
25 #include "internal.h"
26 
27 typedef struct OggVorbisDecContext {
28  vorbis_info vi; /**< vorbis_info used during init */
29  vorbis_dsp_state vd; /**< DSP state used for analysis */
30  vorbis_block vb; /**< vorbis_block used for analysis */
31  vorbis_comment vc; /**< VorbisComment info */
32  ogg_packet op; /**< ogg packet */
34 
35 static int oggvorbis_decode_close(AVCodecContext *avccontext);
36 
37 static int oggvorbis_decode_init(AVCodecContext *avccontext) {
38  OggVorbisDecContext *context = avccontext->priv_data ;
39  uint8_t *p= avccontext->extradata;
40  int i, hsizes[3], ret;
41  unsigned char *headers[3], *extradata = avccontext->extradata;
42 
43  if(! avccontext->extradata_size || ! p) {
44  av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n");
45  return AVERROR(EINVAL);
46  }
47 
48  vorbis_info_init(&context->vi) ;
49  vorbis_comment_init(&context->vc) ;
50 
51  if(p[0] == 0 && p[1] == 30) {
52  int sizesum = 0;
53  for(i = 0; i < 3; i++){
54  hsizes[i] = bytestream_get_be16((const uint8_t **)&p);
55  sizesum += 2 + hsizes[i];
56  if (sizesum > avccontext->extradata_size) {
57  av_log(avccontext, AV_LOG_ERROR, "vorbis extradata too small\n");
58  ret = AVERROR_INVALIDDATA;
59  goto error;
60  }
61 
62  headers[i] = p;
63  p += hsizes[i];
64  }
65  } else if(*p == 2) {
66  unsigned int offset = 1;
67  unsigned int sizesum = 1;
68  p++;
69  for(i=0; i<2; i++) {
70  hsizes[i] = 0;
71  while((*p == 0xFF) && (sizesum < avccontext->extradata_size)) {
72  hsizes[i] += 0xFF;
73  offset++;
74  sizesum += 1 + 0xFF;
75  p++;
76  }
77  hsizes[i] += *p;
78  offset++;
79  sizesum += 1 + *p;
80  if(sizesum > avccontext->extradata_size) {
81  av_log(avccontext, AV_LOG_ERROR,
82  "vorbis header sizes damaged\n");
83  ret = AVERROR_INVALIDDATA;
84  goto error;
85  }
86  p++;
87  }
88  hsizes[2] = avccontext->extradata_size - hsizes[0]-hsizes[1]-offset;
89 #if 0
90  av_log(avccontext, AV_LOG_DEBUG,
91  "vorbis header sizes: %d, %d, %d, / extradata_len is %d \n",
92  hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size);
93 #endif
94  headers[0] = extradata + offset;
95  headers[1] = extradata + offset + hsizes[0];
96  headers[2] = extradata + offset + hsizes[0] + hsizes[1];
97  } else {
98  av_log(avccontext, AV_LOG_ERROR,
99  "vorbis initial header len is wrong: %d\n", *p);
100  ret = AVERROR_INVALIDDATA;
101  goto error;
102  }
103 
104  for(i=0; i<3; i++){
105  context->op.b_o_s= i==0;
106  context->op.bytes = hsizes[i];
107  context->op.packet = headers[i];
108  if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){
109  av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1);
110  ret = AVERROR_INVALIDDATA;
111  goto error;
112  }
113  }
114 
115  avccontext->channels = context->vi.channels;
116  avccontext->sample_rate = context->vi.rate;
117  avccontext->sample_fmt = AV_SAMPLE_FMT_S16;
118  avccontext->time_base= (AVRational){1, avccontext->sample_rate};
119 
120  vorbis_synthesis_init(&context->vd, &context->vi);
121  vorbis_block_init(&context->vd, &context->vb);
122 
123  return 0 ;
124 
125  error:
126  oggvorbis_decode_close(avccontext);
127  return ret;
128 }
129 
130 
131 static inline int conv(int samples, float **pcm, char *buf, int channels) {
132  int i, j;
133  ogg_int16_t *ptr, *data = (ogg_int16_t*)buf ;
134  float *mono ;
135 
136  for(i = 0 ; i < channels ; i++){
137  ptr = &data[i];
138  mono = pcm[i] ;
139 
140  for(j = 0 ; j < samples ; j++) {
141  *ptr = av_clip_int16(mono[j] * 32767.f);
142  ptr += channels;
143  }
144  }
145 
146  return 0 ;
147 }
148 
149 static int oggvorbis_decode_frame(AVCodecContext *avccontext, void *data,
150  int *got_frame_ptr, AVPacket *avpkt)
151 {
152  OggVorbisDecContext *context = avccontext->priv_data ;
153  AVFrame *frame = data;
154  float **pcm ;
155  ogg_packet *op= &context->op;
156  int samples, total_samples, total_bytes;
157  int ret;
158  int16_t *output;
159 
160  if(!avpkt->size){
161  //FIXME flush
162  return 0;
163  }
164 
165  frame->nb_samples = 8192*4;
166  if ((ret = ff_get_buffer(avccontext, frame, 0)) < 0)
167  return ret;
168  output = (int16_t *)frame->data[0];
169 
170 
171  op->packet = avpkt->data;
172  op->bytes = avpkt->size;
173 
174 // 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);
175 
176 /* for(i=0; i<op->bytes; i++)
177  av_log(avccontext, AV_LOG_DEBUG, "%02X ", op->packet[i]);
178  av_log(avccontext, AV_LOG_DEBUG, "\n");*/
179 
180  if(vorbis_synthesis(&context->vb, op) == 0)
181  vorbis_synthesis_blockin(&context->vd, &context->vb) ;
182 
183  total_samples = 0 ;
184  total_bytes = 0 ;
185 
186  while((samples = vorbis_synthesis_pcmout(&context->vd, &pcm)) > 0) {
187  conv(samples, pcm, (char*)output + total_bytes, context->vi.channels) ;
188  total_bytes += samples * 2 * context->vi.channels ;
189  total_samples += samples ;
190  vorbis_synthesis_read(&context->vd, samples) ;
191  }
192 
193  frame->nb_samples = total_samples;
194  *got_frame_ptr = total_samples > 0;
195  return avpkt->size;
196 }
197 
198 
199 static int oggvorbis_decode_close(AVCodecContext *avccontext) {
200  OggVorbisDecContext *context = avccontext->priv_data ;
201 
202  vorbis_block_clear(&context->vb);
203  vorbis_dsp_clear(&context->vd);
204  vorbis_info_clear(&context->vi) ;
205  vorbis_comment_clear(&context->vc) ;
206 
207  return 0 ;
208 }
209 
210 
212  .name = "libvorbis",
213  .long_name = NULL_IF_CONFIG_SMALL("libvorbis"),
214  .type = AVMEDIA_TYPE_AUDIO,
215  .id = AV_CODEC_ID_VORBIS,
216  .priv_data_size = sizeof(OggVorbisDecContext),
219  .close = oggvorbis_decode_close,
221 };
channels
Definition: aptx.h:33
uint8_t
Libavcodec external API header.
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
#define av_clip_int16
Definition: common.h:137
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1900
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
static AVFrame * frame
#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:77
#define AV_CODEC_CAP_CHANNEL_CONF
Codec should fill in channel configuration and samplerate instead of container.
Definition: codec.h:104
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:429
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:61
int i
Definition: input.c:407
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:75
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
AVCodec ff_libvorbis_decoder
Definition: libvorbisdec.c:211
static int oggvorbis_decode_close(AVCodecContext *avccontext)
Definition: libvorbisdec.c:199
static int oggvorbis_decode_frame(AVCodecContext *avccontext, void *data, int *got_frame_ptr, AVPacket *avpkt)
Definition: libvorbisdec.c:149
static int conv(int samples, float **pcm, char *buf, int channels)
Definition: libvorbisdec.c:131
static int oggvorbis_decode_init(AVCodecContext *avccontext)
Definition: libvorbisdec.c:37
const char data[16]
Definition: mxf.c:142
static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize, int64_t *fpos)
find the next Ogg packet
Definition: oggdec.c:498
main external API structure.
Definition: avcodec.h:536
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1204
int sample_rate
samples per second
Definition: avcodec.h:1196
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avcodec.h:659
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:637
int channels
number of audio channels
Definition: avcodec.h:1197
int extradata_size
Definition: avcodec.h:638
void * priv_data
Definition: avcodec.h:563
AVCodec.
Definition: codec.h:197
const char * name
Name of the codec implementation.
Definition: codec.h:204
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:384
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
This structure stores compressed data.
Definition: packet.h:346
int size
Definition: packet.h:370
uint8_t * data
Definition: packet.h:369
Rational number (pair of numerator and denominator).
Definition: rational.h:58
vorbis_block vb
vorbis_block used for analysis
Definition: libvorbisdec.c:30
vorbis_comment vc
VorbisComment info
Definition: libvorbisdec.c:31
vorbis_info vi
vorbis_info used during init
Definition: libvorbisdec.c:28
vorbis_dsp_state vd
DSP state used for analysis
Definition: libvorbisdec.c:29
ogg_packet op
ogg packet
Definition: libvorbisdec.c:32
#define av_log(a,...)
static void error(const char *err)
static const uint8_t offset[127][2]
Definition: vf_spp.c:107