]> git.sesse.net Git - ffmpeg/blob - libavcodec/libspeexdec.c
b02582b3800dca82e9c0b1972b22c979e5635333
[ffmpeg] / libavcodec / libspeexdec.c
1 /*
2  * Copyright (C) 2008 David Conrad
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 <speex/speex.h>
22 #include <speex/speex_header.h>
23 #include <speex/speex_stereo.h>
24 #include <speex/speex_callbacks.h>
25
26 #include "libavutil/channel_layout.h"
27 #include "libavutil/common.h"
28 #include "avcodec.h"
29 #include "internal.h"
30
31 typedef struct LibSpeexContext {
32     SpeexBits bits;
33     SpeexStereoState stereo;
34     void *dec_state;
35     int frame_size;
36     int pktsize;
37 } LibSpeexContext;
38
39
40 static av_cold int libspeex_decode_init(AVCodecContext *avctx)
41 {
42     LibSpeexContext *s = avctx->priv_data;
43     const SpeexMode *mode;
44     SpeexHeader *header = NULL;
45     int spx_mode;
46
47     if (avctx->extradata && avctx->extradata_size >= 80) {
48         header = speex_packet_to_header(avctx->extradata,
49                                         avctx->extradata_size);
50         if (!header)
51             av_log(avctx, AV_LOG_WARNING, "Invalid Speex header\n");
52     }
53     if (avctx->codec_tag == MKTAG('S', 'P', 'X', 'N')) {
54         int quality;
55         if (!avctx->extradata || avctx->extradata && avctx->extradata_size < 47) {
56             av_log(avctx, AV_LOG_ERROR, "Missing or invalid extradata.\n");
57             return AVERROR_INVALIDDATA;
58         }
59
60         quality = avctx->extradata[37];
61         if (quality > 10) {
62             av_log(avctx, AV_LOG_ERROR, "Unsupported quality mode %d.\n", quality);
63             return AVERROR_PATCHWELCOME;
64         }
65
66         s->pktsize = ((const int[]){5,10,15,20,20,28,28,38,38,46,62})[quality];
67
68         spx_mode           = 0;
69     } else if (header) {
70         avctx->sample_rate = header->rate;
71         avctx->channels    = header->nb_channels;
72         spx_mode           = header->mode;
73         speex_header_free(header);
74     } else {
75         switch (avctx->sample_rate) {
76         case 8000:  spx_mode = 0; break;
77         case 16000: spx_mode = 1; break;
78         case 32000: spx_mode = 2; break;
79         default:
80             /* libspeex can handle any mode if initialized as ultra-wideband */
81             av_log(avctx, AV_LOG_WARNING, "Invalid sample rate: %d\n"
82                                           "Decoding as 32kHz ultra-wideband\n",
83                                           avctx->sample_rate);
84             spx_mode = 2;
85         }
86     }
87
88     mode = speex_lib_get_mode(spx_mode);
89     if (!mode) {
90         av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", spx_mode);
91         return AVERROR_INVALIDDATA;
92     }
93     s->frame_size      =  160 << spx_mode;
94     if (!avctx->sample_rate)
95         avctx->sample_rate = 8000 << spx_mode;
96
97     if (avctx->channels < 1 || avctx->channels > 2) {
98         /* libspeex can handle mono or stereo if initialized as stereo */
99         av_log(avctx, AV_LOG_ERROR, "Invalid channel count: %d.\n"
100                                     "Decoding as stereo.\n", avctx->channels);
101         avctx->channels = 2;
102     }
103     avctx->channel_layout = avctx->channels == 2 ? AV_CH_LAYOUT_STEREO :
104                                                    AV_CH_LAYOUT_MONO;
105
106     speex_bits_init(&s->bits);
107     s->dec_state = speex_decoder_init(mode);
108     if (!s->dec_state) {
109         av_log(avctx, AV_LOG_ERROR, "Error initializing libspeex decoder.\n");
110         return -1;
111     }
112
113     if (avctx->channels == 2) {
114         SpeexCallback callback;
115         callback.callback_id = SPEEX_INBAND_STEREO;
116         callback.func = speex_std_stereo_request_handler;
117         callback.data = &s->stereo;
118         s->stereo = (SpeexStereoState)SPEEX_STEREO_STATE_INIT;
119         speex_decoder_ctl(s->dec_state, SPEEX_SET_HANDLER, &callback);
120     }
121
122     return 0;
123 }
124
125 static int libspeex_decode_frame(AVCodecContext *avctx, void *data,
126                                  int *got_frame_ptr, AVPacket *avpkt)
127 {
128     uint8_t *buf = avpkt->data;
129     int buf_size = avpkt->size;
130     LibSpeexContext *s = avctx->priv_data;
131     AVFrame *frame     = data;
132     int16_t *output;
133     int ret, consumed = 0;
134     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
135
136     /* get output buffer */
137     frame->nb_samples = s->frame_size;
138     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
139         return ret;
140     output = (int16_t *)frame->data[0];
141
142     /* if there is not enough data left for the smallest possible frame or the
143        next 5 bits are a terminator code, reset the libspeex buffer using the
144        current packet, otherwise ignore the current packet and keep decoding
145        frames from the libspeex buffer. */
146     if (speex_bits_remaining(&s->bits) < 5 ||
147         speex_bits_peek_unsigned(&s->bits, 5) == 0xF) {
148         /* check for flush packet */
149         if (!buf || !buf_size) {
150             *got_frame_ptr = 0;
151             return buf_size;
152         }
153         if (s->pktsize && buf_size == 62)
154             buf_size = s->pktsize;
155         /* set new buffer */
156         speex_bits_read_from(&s->bits, buf, buf_size);
157         consumed = avpkt->size;
158     }
159
160     /* decode a single frame */
161     ret = speex_decode_int(s->dec_state, &s->bits, output);
162     if (ret <= -2) {
163         av_log(avctx, AV_LOG_ERROR, "Error decoding Speex frame.\n");
164         return AVERROR_INVALIDDATA;
165     }
166     if (avctx->channels == 2)
167         speex_decode_stereo_int(output, s->frame_size, &s->stereo);
168
169     *got_frame_ptr = 1;
170
171     if (!avctx->bit_rate)
172         speex_decoder_ctl(s->dec_state, SPEEX_GET_BITRATE, &avctx->bit_rate);
173     return consumed;
174 }
175
176 static av_cold int libspeex_decode_close(AVCodecContext *avctx)
177 {
178     LibSpeexContext *s = avctx->priv_data;
179
180     speex_bits_destroy(&s->bits);
181     speex_decoder_destroy(s->dec_state);
182
183     return 0;
184 }
185
186 static av_cold void libspeex_decode_flush(AVCodecContext *avctx)
187 {
188     LibSpeexContext *s = avctx->priv_data;
189     speex_bits_reset(&s->bits);
190 }
191
192 AVCodec ff_libspeex_decoder = {
193     .name           = "libspeex",
194     .long_name      = NULL_IF_CONFIG_SMALL("libspeex Speex"),
195     .type           = AVMEDIA_TYPE_AUDIO,
196     .id             = AV_CODEC_ID_SPEEX,
197     .priv_data_size = sizeof(LibSpeexContext),
198     .init           = libspeex_decode_init,
199     .close          = libspeex_decode_close,
200     .decode         = libspeex_decode_frame,
201     .flush          = libspeex_decode_flush,
202     .capabilities   = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
203     .wrapper_name   = "libspeex",
204 };