2 * Copyright (C) 2008 David Conrad
4 * This file is part of FFmpeg.
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.
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.
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
21 #include <speex/speex.h>
22 #include <speex/speex_header.h>
23 #include <speex/speex_stereo.h>
24 #include <speex/speex_callbacks.h>
26 #include "libavutil/channel_layout.h"
27 #include "libavutil/common.h"
33 SpeexStereoState stereo
;
39 static av_cold
int libspeex_decode_init(AVCodecContext
*avctx
)
41 LibSpeexContext
*s
= avctx
->priv_data
;
42 const SpeexMode
*mode
;
43 SpeexHeader
*header
= NULL
;
46 if (avctx
->extradata
&& avctx
->extradata_size
>= 80) {
47 header
= speex_packet_to_header(avctx
->extradata
,
48 avctx
->extradata_size
);
50 av_log(avctx
, AV_LOG_WARNING
, "Invalid Speex header\n");
52 if (avctx
->codec_tag
== MKTAG('S', 'P', 'X', 'N')) {
53 if (!avctx
->extradata
|| avctx
->extradata
&& avctx
->extradata_size
< 47) {
54 av_log(avctx
, AV_LOG_ERROR
, "Missing or invalid extradata.\n");
55 return AVERROR_INVALIDDATA
;
57 if (avctx
->extradata
[37] != 10) {
58 av_log(avctx
, AV_LOG_ERROR
, "Unsupported quality mode.\n");
59 return AVERROR_PATCHWELCOME
;
63 avctx
->sample_rate
= header
->rate
;
64 avctx
->channels
= header
->nb_channels
;
65 spx_mode
= header
->mode
;
66 speex_header_free(header
);
68 switch (avctx
->sample_rate
) {
69 case 8000: spx_mode
= 0; break;
70 case 16000: spx_mode
= 1; break;
71 case 32000: spx_mode
= 2; break;
73 /* libspeex can handle any mode if initialized as ultra-wideband */
74 av_log(avctx
, AV_LOG_WARNING
, "Invalid sample rate: %d\n"
75 "Decoding as 32kHz ultra-wideband\n",
81 mode
= speex_lib_get_mode(spx_mode
);
83 av_log(avctx
, AV_LOG_ERROR
, "Unknown Speex mode %d", spx_mode
);
84 return AVERROR_INVALIDDATA
;
86 s
->frame_size
= 160 << spx_mode
;
87 if (!avctx
->sample_rate
)
88 avctx
->sample_rate
= 8000 << spx_mode
;
90 if (avctx
->channels
< 1 || avctx
->channels
> 2) {
91 /* libspeex can handle mono or stereo if initialized as stereo */
92 av_log(avctx
, AV_LOG_ERROR
, "Invalid channel count: %d.\n"
93 "Decoding as stereo.\n", avctx
->channels
);
96 avctx
->channel_layout
= avctx
->channels
== 2 ? AV_CH_LAYOUT_STEREO
:
99 speex_bits_init(&s
->bits
);
100 s
->dec_state
= speex_decoder_init(mode
);
102 av_log(avctx
, AV_LOG_ERROR
, "Error initializing libspeex decoder.\n");
106 if (avctx
->channels
== 2) {
107 SpeexCallback callback
;
108 callback
.callback_id
= SPEEX_INBAND_STEREO
;
109 callback
.func
= speex_std_stereo_request_handler
;
110 callback
.data
= &s
->stereo
;
111 s
->stereo
= (SpeexStereoState
)SPEEX_STEREO_STATE_INIT
;
112 speex_decoder_ctl(s
->dec_state
, SPEEX_SET_HANDLER
, &callback
);
118 static int libspeex_decode_frame(AVCodecContext
*avctx
, void *data
,
119 int *got_frame_ptr
, AVPacket
*avpkt
)
121 uint8_t *buf
= avpkt
->data
;
122 int buf_size
= avpkt
->size
;
123 LibSpeexContext
*s
= avctx
->priv_data
;
124 AVFrame
*frame
= data
;
126 int ret
, consumed
= 0;
127 avctx
->sample_fmt
= AV_SAMPLE_FMT_S16
;
129 /* get output buffer */
130 frame
->nb_samples
= s
->frame_size
;
131 if ((ret
= ff_get_buffer(avctx
, frame
, 0)) < 0)
133 output
= (int16_t *)frame
->data
[0];
135 /* if there is not enough data left for the smallest possible frame or the
136 next 5 bits are a terminator code, reset the libspeex buffer using the
137 current packet, otherwise ignore the current packet and keep decoding
138 frames from the libspeex buffer. */
139 if (speex_bits_remaining(&s
->bits
) < 5 ||
140 speex_bits_peek_unsigned(&s
->bits
, 5) == 0xF) {
141 /* check for flush packet */
142 if (!buf
|| !buf_size
) {
147 speex_bits_read_from(&s
->bits
, buf
, buf_size
);
151 /* decode a single frame */
152 ret
= speex_decode_int(s
->dec_state
, &s
->bits
, output
);
154 av_log(avctx
, AV_LOG_ERROR
, "Error decoding Speex frame.\n");
155 return AVERROR_INVALIDDATA
;
157 if (avctx
->channels
== 2)
158 speex_decode_stereo_int(output
, s
->frame_size
, &s
->stereo
);
162 if (!avctx
->bit_rate
)
163 speex_decoder_ctl(s
->dec_state
, SPEEX_GET_BITRATE
, &avctx
->bit_rate
);
167 static av_cold
int libspeex_decode_close(AVCodecContext
*avctx
)
169 LibSpeexContext
*s
= avctx
->priv_data
;
171 speex_bits_destroy(&s
->bits
);
172 speex_decoder_destroy(s
->dec_state
);
177 static av_cold
void libspeex_decode_flush(AVCodecContext
*avctx
)
179 LibSpeexContext
*s
= avctx
->priv_data
;
180 speex_bits_reset(&s
->bits
);
183 AVCodec ff_libspeex_decoder
= {
185 .long_name
= NULL_IF_CONFIG_SMALL("libspeex Speex"),
186 .type
= AVMEDIA_TYPE_AUDIO
,
187 .id
= AV_CODEC_ID_SPEEX
,
188 .priv_data_size
= sizeof(LibSpeexContext
),
189 .init
= libspeex_decode_init
,
190 .close
= libspeex_decode_close
,
191 .decode
= libspeex_decode_frame
,
192 .flush
= libspeex_decode_flush
,
193 .capabilities
= CODEC_CAP_SUBFRAMES
| CODEC_CAP_DELAY
| CODEC_CAP_DR1
,