00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "avcodec.h"
00022 #include <speex/speex.h>
00023 #include <speex/speex_header.h>
00024 #include <speex/speex_stereo.h>
00025 #include <speex/speex_callbacks.h>
00026
00027 typedef struct {
00028 SpeexBits bits;
00029 SpeexStereoState stereo;
00030 void *dec_state;
00031 SpeexHeader *header;
00032 } LibSpeexContext;
00033
00034
00035 static av_cold int libspeex_decode_init(AVCodecContext *avctx)
00036 {
00037 LibSpeexContext *s = avctx->priv_data;
00038 const SpeexMode *mode;
00039
00040
00041 if (avctx->sample_rate <= 8000)
00042 mode = &speex_nb_mode;
00043 else if (avctx->sample_rate <= 16000)
00044 mode = &speex_wb_mode;
00045 else
00046 mode = &speex_uwb_mode;
00047
00048 if (avctx->extradata_size >= 80)
00049 s->header = speex_packet_to_header(avctx->extradata, avctx->extradata_size);
00050
00051 avctx->sample_fmt = SAMPLE_FMT_S16;
00052 if (s->header) {
00053 avctx->sample_rate = s->header->rate;
00054 avctx->channels = s->header->nb_channels;
00055 avctx->frame_size = s->header->frame_size;
00056
00057 mode = speex_lib_get_mode(s->header->mode);
00058 if (!mode) {
00059 av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", s->header->mode);
00060 return -1;
00061 }
00062 } else
00063 av_log(avctx, AV_LOG_INFO, "Missing Speex header, assuming defaults.\n");
00064
00065 if (avctx->channels > 2) {
00066 av_log(avctx, AV_LOG_ERROR, "Only stereo and mono are supported.\n");
00067 return -1;
00068 }
00069
00070 speex_bits_init(&s->bits);
00071 s->dec_state = speex_decoder_init(mode);
00072 if (!s->dec_state) {
00073 av_log(avctx, AV_LOG_ERROR, "Error initializing libspeex decoder.\n");
00074 return -1;
00075 }
00076
00077 if (!s->header)
00078 speex_decoder_ctl(s->dec_state, SPEEX_GET_FRAME_SIZE, &avctx->frame_size);
00079
00080 if (avctx->channels == 2) {
00081 SpeexCallback callback;
00082 callback.callback_id = SPEEX_INBAND_STEREO;
00083 callback.func = speex_std_stereo_request_handler;
00084 callback.data = &s->stereo;
00085 s->stereo = (SpeexStereoState)SPEEX_STEREO_STATE_INIT;
00086 speex_decoder_ctl(s->dec_state, SPEEX_SET_HANDLER, &callback);
00087 }
00088 return 0;
00089 }
00090
00091 static int libspeex_decode_frame(AVCodecContext *avctx,
00092 void *data, int *data_size,
00093 const uint8_t *buf, int buf_size)
00094 {
00095 LibSpeexContext *s = avctx->priv_data;
00096 int16_t *output = data, *end;
00097 int i, num_samples;
00098
00099 num_samples = avctx->frame_size * avctx->channels;
00100 end = output + *data_size/2;
00101
00102 speex_bits_read_from(&s->bits, buf, buf_size);
00103
00104 for (i = 0; speex_bits_remaining(&s->bits) && output + num_samples < end; i++) {
00105 int ret = speex_decode_int(s->dec_state, &s->bits, output);
00106 if (ret <= -2) {
00107 av_log(avctx, AV_LOG_ERROR, "Error decoding Speex frame.\n");
00108 return -1;
00109 } else if (ret == -1)
00110
00111 break;
00112
00113 if (avctx->channels == 2)
00114 speex_decode_stereo_int(output, avctx->frame_size, &s->stereo);
00115
00116 output += num_samples;
00117 }
00118
00119 *data_size = i * avctx->channels * avctx->frame_size * 2;
00120 return buf_size;
00121 }
00122
00123 static av_cold int libspeex_decode_close(AVCodecContext *avctx)
00124 {
00125 LibSpeexContext *s = avctx->priv_data;
00126
00127 speex_header_free(s->header);
00128 speex_bits_destroy(&s->bits);
00129 speex_decoder_destroy(s->dec_state);
00130
00131 return 0;
00132 }
00133
00134 AVCodec libspeex_decoder = {
00135 "libspeex",
00136 CODEC_TYPE_AUDIO,
00137 CODEC_ID_SPEEX,
00138 sizeof(LibSpeexContext),
00139 libspeex_decode_init,
00140 NULL,
00141 libspeex_decode_close,
00142 libspeex_decode_frame,
00143 .long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"),
00144 };