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
;
40 static av_cold
int libspeex_decode_init(AVCodecContext
*avctx
)
42 LibSpeexContext
*s
= avctx
->priv_data
;
43 const SpeexMode
*mode
;
44 SpeexHeader
*header
= NULL
;
47 if (avctx
->extradata
&& avctx
->extradata_size
>= 80) {
48 header
= speex_packet_to_header(avctx
->extradata
,
49 avctx
->extradata_size
);
51 av_log(avctx
, AV_LOG_WARNING
, "Invalid Speex header\n");
53 if (avctx
->codec_tag
== MKTAG('S', 'P', 'X', 'N')) {
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
;
60 quality
= avctx
->extradata
[37];
62 av_log(avctx
, AV_LOG_ERROR
, "Unsupported quality mode %d.\n", quality
);
63 return AVERROR_PATCHWELCOME
;
66 s
->pktsize
= ((const int[]){5,10,15,20,20,28,28,38,38,46,62})[quality
];
70 avctx
->sample_rate
= header
->rate
;
71 avctx
->channels
= header
->nb_channels
;
72 spx_mode
= header
->mode
;
73 speex_header_free(header
);
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;
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",
88 mode
= speex_lib_get_mode(spx_mode
);
90 av_log(avctx
, AV_LOG_ERROR
, "Unknown Speex mode %d", spx_mode
);
91 return AVERROR_INVALIDDATA
;
93 s
->frame_size
= 160 << spx_mode
;
94 if (!avctx
->sample_rate
)
95 avctx
->sample_rate
= 8000 << spx_mode
;
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
);
103 avctx
->channel_layout
= avctx
->channels
== 2 ? AV_CH_LAYOUT_STEREO
:
106 speex_bits_init(&s
->bits
);
107 s
->dec_state
= speex_decoder_init(mode
);
109 av_log(avctx
, AV_LOG_ERROR
, "Error initializing libspeex decoder.\n");
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
);
125 static int libspeex_decode_frame(AVCodecContext
*avctx
, void *data
,
126 int *got_frame_ptr
, AVPacket
*avpkt
)
128 uint8_t *buf
= avpkt
->data
;
129 int buf_size
= avpkt
->size
;
130 LibSpeexContext
*s
= avctx
->priv_data
;
131 AVFrame
*frame
= data
;
133 int ret
, consumed
= 0;
134 avctx
->sample_fmt
= AV_SAMPLE_FMT_S16
;
136 /* get output buffer */
137 frame
->nb_samples
= s
->frame_size
;
138 if ((ret
= ff_get_buffer(avctx
, frame
, 0)) < 0)
140 output
= (int16_t *)frame
->data
[0];
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
) {
153 if (s
->pktsize
&& buf_size
== 62)
154 buf_size
= s
->pktsize
;
156 speex_bits_read_from(&s
->bits
, buf
, buf_size
);
157 consumed
= avpkt
->size
;
160 /* decode a single frame */
161 ret
= speex_decode_int(s
->dec_state
, &s
->bits
, output
);
163 av_log(avctx
, AV_LOG_ERROR
, "Error decoding Speex frame.\n");
164 return AVERROR_INVALIDDATA
;
166 if (avctx
->channels
== 2)
167 speex_decode_stereo_int(output
, s
->frame_size
, &s
->stereo
);
171 if (!avctx
->bit_rate
)
172 speex_decoder_ctl(s
->dec_state
, SPEEX_GET_BITRATE
, &avctx
->bit_rate
);
176 static av_cold
int libspeex_decode_close(AVCodecContext
*avctx
)
178 LibSpeexContext
*s
= avctx
->priv_data
;
180 speex_bits_destroy(&s
->bits
);
181 speex_decoder_destroy(s
->dec_state
);
186 static av_cold
void libspeex_decode_flush(AVCodecContext
*avctx
)
188 LibSpeexContext
*s
= avctx
->priv_data
;
189 speex_bits_reset(&s
->bits
);
192 AVCodec ff_libspeex_decoder
= {
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
= CODEC_CAP_SUBFRAMES
| CODEC_CAP_DELAY
| CODEC_CAP_DR1
,