libspeexdec.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008 David Conrad
3  *
4  * This file is part of Libav.
5  *
6  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <speex/speex.h>
22 #include <speex/speex_header.h>
23 #include <speex/speex_stereo.h>
24 #include <speex/speex_callbacks.h>
25 #include "avcodec.h"
26 #include "internal.h"
27 
28 typedef struct {
30  SpeexBits bits;
31  SpeexStereoState stereo;
32  void *dec_state;
33  SpeexHeader *header;
36 
37 
39 {
40  LibSpeexContext *s = avctx->priv_data;
41  const SpeexMode *mode;
42 
43  // defaults in the case of a missing header
44  if (avctx->sample_rate <= 8000)
45  mode = &speex_nb_mode;
46  else if (avctx->sample_rate <= 16000)
47  mode = &speex_wb_mode;
48  else
49  mode = &speex_uwb_mode;
50 
51  if (avctx->extradata_size >= 80)
52  s->header = speex_packet_to_header(avctx->extradata, avctx->extradata_size);
53 
55  if (s->header) {
56  avctx->sample_rate = s->header->rate;
57  avctx->channels = s->header->nb_channels;
58  avctx->frame_size = s->frame_size = s->header->frame_size;
59  if (s->header->frames_per_packet)
60  avctx->frame_size *= s->header->frames_per_packet;
61 
62  mode = speex_lib_get_mode(s->header->mode);
63  if (!mode) {
64  av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", s->header->mode);
65  return AVERROR_INVALIDDATA;
66  }
67  } else
68  av_log(avctx, AV_LOG_INFO, "Missing Speex header, assuming defaults.\n");
69 
70  if (avctx->channels > 2) {
71  av_log(avctx, AV_LOG_ERROR, "Only stereo and mono are supported.\n");
72  return AVERROR(EINVAL);
73  }
74 
75  speex_bits_init(&s->bits);
76  s->dec_state = speex_decoder_init(mode);
77  if (!s->dec_state) {
78  av_log(avctx, AV_LOG_ERROR, "Error initializing libspeex decoder.\n");
79  return -1;
80  }
81 
82  if (!s->header) {
83  speex_decoder_ctl(s->dec_state, SPEEX_GET_FRAME_SIZE, &s->frame_size);
84  }
85 
86  if (avctx->channels == 2) {
87  SpeexCallback callback;
88  callback.callback_id = SPEEX_INBAND_STEREO;
89  callback.func = speex_std_stereo_request_handler;
90  callback.data = &s->stereo;
91  s->stereo = (SpeexStereoState)SPEEX_STEREO_STATE_INIT;
92  speex_decoder_ctl(s->dec_state, SPEEX_SET_HANDLER, &callback);
93  }
94 
96  avctx->coded_frame = &s->frame;
97 
98  return 0;
99 }
100 
101 static int libspeex_decode_frame(AVCodecContext *avctx, void *data,
102  int *got_frame_ptr, AVPacket *avpkt)
103 {
104  uint8_t *buf = avpkt->data;
105  int buf_size = avpkt->size;
106  LibSpeexContext *s = avctx->priv_data;
107  int16_t *output;
108  int ret, consumed = 0;
109 
110  /* get output buffer */
111  s->frame.nb_samples = s->frame_size;
112  if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
113  av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
114  return ret;
115  }
116  output = (int16_t *)s->frame.data[0];
117 
118  /* if there is not enough data left for the smallest possible frame,
119  reset the libspeex buffer using the current packet, otherwise ignore
120  the current packet and keep decoding frames from the libspeex buffer. */
121  if (speex_bits_remaining(&s->bits) < 43) {
122  /* check for flush packet */
123  if (!buf || !buf_size) {
124  *got_frame_ptr = 0;
125  return buf_size;
126  }
127  /* set new buffer */
128  speex_bits_read_from(&s->bits, buf, buf_size);
129  consumed = buf_size;
130  }
131 
132  /* decode a single frame */
133  ret = speex_decode_int(s->dec_state, &s->bits, output);
134  if (ret <= -2) {
135  av_log(avctx, AV_LOG_ERROR, "Error decoding Speex frame.\n");
136  return AVERROR_INVALIDDATA;
137  }
138  if (avctx->channels == 2)
139  speex_decode_stereo_int(output, s->frame_size, &s->stereo);
140 
141  *got_frame_ptr = 1;
142  *(AVFrame *)data = s->frame;
143 
144  return consumed;
145 }
146 
148 {
149  LibSpeexContext *s = avctx->priv_data;
150 
151  speex_header_free(s->header);
152  speex_bits_destroy(&s->bits);
153  speex_decoder_destroy(s->dec_state);
154 
155  return 0;
156 }
157 
159 {
160  LibSpeexContext *s = avctx->priv_data;
161  speex_bits_reset(&s->bits);
162 }
163 
165  .name = "libspeex",
166  .type = AVMEDIA_TYPE_AUDIO,
167  .id = CODEC_ID_SPEEX,
168  .priv_data_size = sizeof(LibSpeexContext),
174  .long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"),
175 };
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:54
Audio Video Frame.
Definition: avcodec.h:985
AVCodec ff_libspeex_decoder
Definition: libspeexdec.c:164
AVFrame * coded_frame
the picture in the bitstream
Definition: avcodec.h:2000
SpeexHeader * header
Definition: libspeexdec.c:33
int size
Definition: avcodec.h:909
SpeexStereoState stereo
Definition: libspeexdec.c:31
SpeexBits bits
Definition: libspeexdec.c:30
signed 16 bits
Definition: samplefmt.h:30
AVCodec.
Definition: avcodec.h:3189
static int decode(MimicContext *ctx, int quality, int num_coeffs, int is_iframe)
Definition: mimic.c:228
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1464
#define av_cold
Definition: attributes.h:71
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1387
const char data[16]
Definition: mxf.c:60
uint8_t * data
Definition: avcodec.h:908
static int init(AVCodecParserContext *s)
Definition: h264_parser.c:336
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:719
static av_cold void libspeex_decode_flush(AVCodecContext *avctx)
Definition: libspeexdec.c:158
void * dec_state
Definition: libspeexdec.c:32
#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:191
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:140
const char * name
Name of the codec implementation.
Definition: avcodec.h:3196
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame)
Definition: utils.c:1867
static av_cold int libspeex_decode_init(AVCodecContext *avctx)
Definition: libspeexdec.c:38
int frame_size
Samples per packet, initialized when calling 'init'.
Definition: avcodec.h:1470
external API header
int sample_rate
samples per second
Definition: avcodec.h:1456
main external API structure.
Definition: avcodec.h:1329
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:327
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:111
static av_cold int libspeex_decode_close(AVCodecContext *avctx)
Definition: libspeexdec.c:147
int extradata_size
Definition: avcodec.h:1388
static int libspeex_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt)
Definition: libspeexdec.c:101
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: avcodec.h:997
common internal api header.
static av_cold void flush(AVCodecContext *avctx)
Flush (reset) the frame ID after seeking.
Definition: alsdec.c:1779
void * priv_data
Definition: avcodec.h:1531
int channels
number of audio channels
Definition: avcodec.h:1457
#define CODEC_CAP_SUBFRAMES
Codec can output multiple frames per AVPacket Normally demuxers return one frame at a time...
Definition: avcodec.h:771
#define AV_LOG_INFO
Definition: log.h:119
void avcodec_get_frame_defaults(AVFrame *pic)
Set the fields of the given AVFrame to default values.
Definition: utils.c:609
#define 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:750
int nb_samples
number of audio samples (per channel) described by this frame
Definition: avcodec.h:1265