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
;
36 static av_cold
int libspeex_decode_init(AVCodecContext
*avctx
)
38 LibSpeexContext
*s
= avctx
->priv_data
;
39 const SpeexMode
*mode
;
41 // defaults in the case of a missing header
42 if (avctx
->sample_rate
<= 8000)
43 mode
= &speex_nb_mode
;
44 else if (avctx
->sample_rate
<= 16000)
45 mode
= &speex_wb_mode
;
47 mode
= &speex_uwb_mode
;
49 if (avctx
->extradata_size
>= 80)
50 s
->header
= speex_packet_to_header(avctx
->extradata
, avctx
->extradata_size
);
52 avctx
->sample_fmt
= SAMPLE_FMT_S16
;
54 avctx
->sample_rate
= s
->header
->rate
;
55 avctx
->channels
= s
->header
->nb_channels
;
56 avctx
->frame_size
= s
->frame_size
= s
->header
->frame_size
;
57 if (s
->header
->frames_per_packet
)
58 avctx
->frame_size
*= s
->header
->frames_per_packet
;
60 mode
= speex_lib_get_mode(s
->header
->mode
);
62 av_log(avctx
, AV_LOG_ERROR
, "Unknown Speex mode %d", s
->header
->mode
);
66 av_log(avctx
, AV_LOG_INFO
, "Missing Speex header, assuming defaults.\n");
68 if (avctx
->channels
> 2) {
69 av_log(avctx
, AV_LOG_ERROR
, "Only stereo and mono are supported.\n");
73 speex_bits_init(&s
->bits
);
74 s
->dec_state
= speex_decoder_init(mode
);
76 av_log(avctx
, AV_LOG_ERROR
, "Error initializing libspeex decoder.\n");
81 speex_decoder_ctl(s
->dec_state
, SPEEX_GET_FRAME_SIZE
, &s
->frame_size
);
84 if (avctx
->channels
== 2) {
85 SpeexCallback callback
;
86 callback
.callback_id
= SPEEX_INBAND_STEREO
;
87 callback
.func
= speex_std_stereo_request_handler
;
88 callback
.data
= &s
->stereo
;
89 s
->stereo
= (SpeexStereoState
)SPEEX_STEREO_STATE_INIT
;
90 speex_decoder_ctl(s
->dec_state
, SPEEX_SET_HANDLER
, &callback
);
95 static int libspeex_decode_frame(AVCodecContext
*avctx
,
96 void *data
, int *data_size
,
99 const uint8_t *buf
= avpkt
->data
;
100 int buf_size
= avpkt
->size
;
101 LibSpeexContext
*s
= avctx
->priv_data
;
102 int16_t *output
= data
, *end
;
105 num_samples
= s
->frame_size
* avctx
->channels
;
106 end
= output
+ *data_size
/ sizeof(*output
);
108 speex_bits_read_from(&s
->bits
, buf
, buf_size
);
110 for (i
= 0; speex_bits_remaining(&s
->bits
) && output
+ num_samples
< end
; i
++) {
111 int ret
= speex_decode_int(s
->dec_state
, &s
->bits
, output
);
113 av_log(avctx
, AV_LOG_ERROR
, "Error decoding Speex frame.\n");
115 } else if (ret
== -1)
119 if (avctx
->channels
== 2)
120 speex_decode_stereo_int(output
, s
->frame_size
, &s
->stereo
);
122 output
+= num_samples
;
125 avctx
->frame_size
= s
->frame_size
* i
;
126 *data_size
= avctx
->channels
* avctx
->frame_size
* sizeof(*output
);
130 static av_cold
int libspeex_decode_close(AVCodecContext
*avctx
)
132 LibSpeexContext
*s
= avctx
->priv_data
;
134 speex_header_free(s
->header
);
135 speex_bits_destroy(&s
->bits
);
136 speex_decoder_destroy(s
->dec_state
);
141 AVCodec libspeex_decoder
= {
145 sizeof(LibSpeexContext
),
146 libspeex_decode_init
,
148 libspeex_decode_close
,
149 libspeex_decode_frame
,
150 .long_name
= NULL_IF_CONFIG_SMALL("libspeex Speex"),