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
22 #include <speex/speex.h>
23 #include <speex/speex_header.h>
24 #include <speex/speex_stereo.h>
25 #include <speex/speex_callbacks.h>
29 SpeexStereoState stereo
;
35 static av_cold
int libspeex_decode_init(AVCodecContext
*avctx
)
37 LibSpeexContext
*s
= avctx
->priv_data
;
38 const SpeexMode
*mode
;
40 // defaults in the case of a missing header
41 if (avctx
->sample_rate
<= 8000)
42 mode
= &speex_nb_mode
;
43 else if (avctx
->sample_rate
<= 16000)
44 mode
= &speex_wb_mode
;
46 mode
= &speex_uwb_mode
;
48 if (avctx
->extradata_size
>= 80)
49 s
->header
= speex_packet_to_header(avctx
->extradata
, avctx
->extradata_size
);
51 avctx
->sample_fmt
= SAMPLE_FMT_S16
;
53 avctx
->sample_rate
= s
->header
->rate
;
54 avctx
->channels
= s
->header
->nb_channels
;
55 avctx
->frame_size
= s
->header
->frame_size
;
57 mode
= speex_lib_get_mode(s
->header
->mode
);
59 av_log(avctx
, AV_LOG_ERROR
, "Unknown Speex mode %d", s
->header
->mode
);
63 av_log(avctx
, AV_LOG_INFO
, "Missing Speex header, assuming defaults.\n");
65 if (avctx
->channels
> 2) {
66 av_log(avctx
, AV_LOG_ERROR
, "Only stereo and mono are supported.\n");
70 speex_bits_init(&s
->bits
);
71 s
->dec_state
= speex_decoder_init(mode
);
73 av_log(avctx
, AV_LOG_ERROR
, "Error initializing libspeex decoder.\n");
78 speex_decoder_ctl(s
->dec_state
, SPEEX_GET_FRAME_SIZE
, &avctx
->frame_size
);
80 if (avctx
->channels
== 2) {
81 SpeexCallback callback
;
82 callback
.callback_id
= SPEEX_INBAND_STEREO
;
83 callback
.func
= speex_std_stereo_request_handler
;
84 callback
.data
= &s
->stereo
;
85 s
->stereo
= (SpeexStereoState
)SPEEX_STEREO_STATE_INIT
;
86 speex_decoder_ctl(s
->dec_state
, SPEEX_SET_HANDLER
, &callback
);
91 static int libspeex_decode_frame(AVCodecContext
*avctx
,
92 void *data
, int *data_size
,
93 const uint8_t *buf
, int buf_size
)
95 LibSpeexContext
*s
= avctx
->priv_data
;
96 int16_t *output
= data
, *end
;
99 num_samples
= avctx
->frame_size
* avctx
->channels
;
100 end
= output
+ *data_size
/2;
102 speex_bits_read_from(&s
->bits
, buf
, buf_size
);
104 for (i
= 0; speex_bits_remaining(&s
->bits
) && output
+ num_samples
< end
; i
++) {
105 int ret
= speex_decode_int(s
->dec_state
, &s
->bits
, output
);
107 av_log(avctx
, AV_LOG_ERROR
, "Error decoding Speex frame.\n");
109 } else if (ret
== -1)
113 if (avctx
->channels
== 2)
114 speex_decode_stereo_int(output
, avctx
->frame_size
, &s
->stereo
);
116 output
+= num_samples
;
119 *data_size
= i
* avctx
->channels
* avctx
->frame_size
* 2;
123 static av_cold
int libspeex_decode_close(AVCodecContext
*avctx
)
125 LibSpeexContext
*s
= avctx
->priv_data
;
127 speex_header_free(s
->header
);
128 speex_bits_destroy(&s
->bits
);
129 speex_decoder_destroy(s
->dec_state
);
134 AVCodec libspeex_decoder
= {
138 sizeof(LibSpeexContext
),
139 libspeex_decode_init
,
141 libspeex_decode_close
,
142 libspeex_decode_frame
,
143 .long_name
= NULL_IF_CONFIG_SMALL("libspeex Speex"),