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_init(AVCodecContext *avccontext) {
36  OggVorbisDecContext *context = avccontext->priv_data ;
37  uint8_t *p= avccontext->extradata;
38  int i, hsizes[3];
39  unsigned char *headers[3], *extradata = avccontext->extradata;
40 
41  vorbis_info_init(&context->vi) ;
42  vorbis_comment_init(&context->vc) ;
43 
44  if(! avccontext->extradata_size || ! p) {
45  av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n");
46  return -1;
47  }
48 
49  if(p[0] == 0 && p[1] == 30) {
50  for(i = 0; i < 3; i++){
51  hsizes[i] = bytestream_get_be16((const uint8_t **)&p);
52  headers[i] = p;
53  p += hsizes[i];
54  }
55  } else if(*p == 2) {
56  unsigned int offset = 1;
57  p++;
58  for(i=0; i<2; i++) {
59  hsizes[i] = 0;
60  while((*p == 0xFF) && (offset < avccontext->extradata_size)) {
61  hsizes[i] += 0xFF;
62  offset++;
63  p++;
64  }
65  if(offset >= avccontext->extradata_size - 1) {
66  av_log(avccontext, AV_LOG_ERROR,
67  "vorbis header sizes damaged\n");
68  return -1;
69  }
70  hsizes[i] += *p;
71  offset++;
72  p++;
73  }
74  hsizes[2] = avccontext->extradata_size - hsizes[0]-hsizes[1]-offset;
75 #if 0
76  av_log(avccontext, AV_LOG_DEBUG,
77  "vorbis header sizes: %d, %d, %d, / extradata_len is %d \n",
78  hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size);
79 #endif
80  headers[0] = extradata + offset;
81  headers[1] = extradata + offset + hsizes[0];
82  headers[2] = extradata + offset + hsizes[0] + hsizes[1];
83  } else {
84  av_log(avccontext, AV_LOG_ERROR,
85  "vorbis initial header len is wrong: %d\n", *p);
86  return -1;
87  }
88 
89  for(i=0; i<3; i++){
90  context->op.b_o_s= i==0;
91  context->op.bytes = hsizes[i];
92  context->op.packet = headers[i];
93  if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){
94  av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1);
95  return -1;
96  }
97  }
98 
99  avccontext->channels = context->vi.channels;
100  avccontext->sample_rate = context->vi.rate;
101  avccontext->sample_fmt = AV_SAMPLE_FMT_S16;
102  avccontext->time_base= (AVRational){1, avccontext->sample_rate};
103 
104  vorbis_synthesis_init(&context->vd, &context->vi);
105  vorbis_block_init(&context->vd, &context->vb);
106 
107  return 0 ;
108 }
109 
110 
111 static inline int conv(int samples, float **pcm, char *buf, int channels) {
112  int i, j;
113  ogg_int16_t *ptr, *data = (ogg_int16_t*)buf ;
114  float *mono ;
115 
116  for(i = 0 ; i < channels ; i++){
117  ptr = &data[i];
118  mono = pcm[i] ;
119 
120  for(j = 0 ; j < samples ; j++) {
121  *ptr = av_clip_int16(mono[j] * 32767.f);
122  ptr += channels;
123  }
124  }
125 
126  return 0 ;
127 }
128 
129 static int oggvorbis_decode_frame(AVCodecContext *avccontext, void *data,
130  int *got_frame_ptr, AVPacket *avpkt)
131 {
132  OggVorbisDecContext *context = avccontext->priv_data ;
133  AVFrame *frame = data;
134  float **pcm ;
135  ogg_packet *op= &context->op;
136  int samples, total_samples, total_bytes;
137  int ret;
138  int16_t *output;
139 
140  if(!avpkt->size){
141  //FIXME flush
142  return 0;
143  }
144 
145  frame->nb_samples = 8192*4;
146  if ((ret = ff_get_buffer(avccontext, frame, 0)) < 0)
147  return ret;
148  output = (int16_t *)frame->data[0];
149 
150 
151  op->packet = avpkt->data;
152  op->bytes = avpkt->size;
153 
154 // 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);
155 
156 /* for(i=0; i<op->bytes; i++)
157  av_log(avccontext, AV_LOG_DEBUG, "%02X ", op->packet[i]);
158  av_log(avccontext, AV_LOG_DEBUG, "\n");*/
159 
160  if(vorbis_synthesis(&context->vb, op) == 0)
161  vorbis_synthesis_blockin(&context->vd, &context->vb) ;
162 
163  total_samples = 0 ;
164  total_bytes = 0 ;
165 
166  while((samples = vorbis_synthesis_pcmout(&context->vd, &pcm)) > 0) {
167  conv(samples, pcm, (char*)output + total_bytes, context->vi.channels) ;
168  total_bytes += samples * 2 * context->vi.channels ;
169  total_samples += samples ;
170  vorbis_synthesis_read(&context->vd, samples) ;
171  }
172 
173  frame->nb_samples = total_samples;
174  *got_frame_ptr = 1;
175  return avpkt->size;
176 }
177 
178 
179 static int oggvorbis_decode_close(AVCodecContext *avccontext) {
180  OggVorbisDecContext *context = avccontext->priv_data ;
181 
182  vorbis_info_clear(&context->vi) ;
183  vorbis_comment_clear(&context->vc) ;
184 
185  return 0 ;
186 }
187 
188 
190  .name = "libvorbis",
191  .type = AVMEDIA_TYPE_AUDIO,
192  .id = AV_CODEC_ID_VORBIS,
193  .priv_data_size = sizeof(OggVorbisDecContext),
197  .capabilities = CODEC_CAP_DELAY,
198  .long_name = NULL_IF_CONFIG_SMALL("libvorbis"),
199 };
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
ogg_packet op
ogg packet
Definition: libvorbisdec.c:32
static int conv(int samples, float **pcm, char *buf, int channels)
Definition: libvorbisdec.c:111
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
vorbis_dsp_state vd
DSP state used for analysis.
Definition: libvorbisdec.c:29
Sinusoidal phase f
signed 16 bits
Definition: samplefmt.h:52
FFmpeg currently uses a custom build this text attempts to document some of its obscure features and options Makefile the full command issued by make and its output will be shown on the screen DESTDIR Destination directory for the install useful to prepare packages or install FFmpeg in cross environments Makefile builds all the libraries and the executables fate Run the fate test note you must have installed it fate list Will list all fate regression test targets install Install headers
Definition: build_system.txt:1
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
vorbis_block vb
vorbis_block used for analysis
Definition: libvorbisdec.c:30
struct OggVorbisDecContext OggVorbisDecContext
enum AVSampleFormat sample_fmt
audio sample format
uint8_t
static int oggvorbis_decode_init(AVCodecContext *avccontext)
Definition: libvorbisdec.c:35
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
uint8_t * data
frame
Definition: stft.m:14
#define CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
vorbis_comment vc
VorbisComment info.
Definition: libvorbisdec.c:31
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Spectrum Plot time data
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
static const uint8_t offset[127][2]
Definition: vf_spp.c:70
external API header
vorbis_info vi
vorbis_info used during init
Definition: libvorbisdec.c:28
struct AVRational AVRational
rational number numerator/denominator
ret
Definition: avfilter.c:821
static int oggvorbis_decode_frame(AVCodecContext *avccontext, void *data, int *got_frame_ptr, AVPacket *avpkt)
Definition: libvorbisdec.c:129
int sample_rate
samples per second
static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize, int64_t *fpos)
find the next Ogg packet
Definition: oggdec.c:436
main external API structure.
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
static int oggvorbis_decode_close(AVCodecContext *avccontext)
Definition: libvorbisdec.c:179
void * buf
Definition: avisynth_c.h:594
synthesis window for stochastic i
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
common internal api header.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
these buffered frames must be flushed immediately if a new input produces new output(Example:frame rate-doubling filter:filter_frame must(1) flush the second copy of the previous frame, if it is still there,(2) push the first copy of the incoming frame,(3) keep the second copy for later.) If the input frame is not enough to produce output
AVCodec ff_libvorbis_decoder
Definition: libvorbisdec.c:189
int channels
number of audio channels
Filter the word “frame” indicates either a video frame or a group of audio samples
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: crystalhd.c:868
This structure stores compressed data.
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:127