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