• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavcodec/libspeexdec.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008 David Conrad
00003  *
00004  * This file is part of Libav.
00005  *
00006  * Libav is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * Libav is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with Libav; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 
00021 #include <speex/speex.h>
00022 #include <speex/speex_header.h>
00023 #include <speex/speex_stereo.h>
00024 #include <speex/speex_callbacks.h>
00025 #include "avcodec.h"
00026 
00027 typedef struct {
00028     AVFrame frame;
00029     SpeexBits bits;
00030     SpeexStereoState stereo;
00031     void *dec_state;
00032     SpeexHeader *header;
00033     int frame_size;
00034 } LibSpeexContext;
00035 
00036 
00037 static av_cold int libspeex_decode_init(AVCodecContext *avctx)
00038 {
00039     LibSpeexContext *s = avctx->priv_data;
00040     const SpeexMode *mode;
00041 
00042     // defaults in the case of a missing header
00043     if (avctx->sample_rate <= 8000)
00044         mode = &speex_nb_mode;
00045     else if (avctx->sample_rate <= 16000)
00046         mode = &speex_wb_mode;
00047     else
00048         mode = &speex_uwb_mode;
00049 
00050     if (avctx->extradata_size >= 80)
00051         s->header = speex_packet_to_header(avctx->extradata, avctx->extradata_size);
00052 
00053     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00054     if (s->header) {
00055         avctx->sample_rate = s->header->rate;
00056         avctx->channels    = s->header->nb_channels;
00057         avctx->frame_size  = s->frame_size = s->header->frame_size;
00058         if (s->header->frames_per_packet)
00059             avctx->frame_size *= s->header->frames_per_packet;
00060 
00061         mode = speex_lib_get_mode(s->header->mode);
00062         if (!mode) {
00063             av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", s->header->mode);
00064             return AVERROR_INVALIDDATA;
00065         }
00066     } else
00067         av_log(avctx, AV_LOG_INFO, "Missing Speex header, assuming defaults.\n");
00068 
00069     if (avctx->channels > 2) {
00070         av_log(avctx, AV_LOG_ERROR, "Only stereo and mono are supported.\n");
00071         return AVERROR(EINVAL);
00072     }
00073 
00074     speex_bits_init(&s->bits);
00075     s->dec_state = speex_decoder_init(mode);
00076     if (!s->dec_state) {
00077         av_log(avctx, AV_LOG_ERROR, "Error initializing libspeex decoder.\n");
00078         return -1;
00079     }
00080 
00081     if (!s->header) {
00082         speex_decoder_ctl(s->dec_state, SPEEX_GET_FRAME_SIZE, &s->frame_size);
00083     }
00084 
00085     if (avctx->channels == 2) {
00086         SpeexCallback callback;
00087         callback.callback_id = SPEEX_INBAND_STEREO;
00088         callback.func = speex_std_stereo_request_handler;
00089         callback.data = &s->stereo;
00090         s->stereo = (SpeexStereoState)SPEEX_STEREO_STATE_INIT;
00091         speex_decoder_ctl(s->dec_state, SPEEX_SET_HANDLER, &callback);
00092     }
00093 
00094     avcodec_get_frame_defaults(&s->frame);
00095     avctx->coded_frame = &s->frame;
00096 
00097     return 0;
00098 }
00099 
00100 static int libspeex_decode_frame(AVCodecContext *avctx, void *data,
00101                                  int *got_frame_ptr, AVPacket *avpkt)
00102 {
00103     uint8_t *buf = avpkt->data;
00104     int buf_size = avpkt->size;
00105     LibSpeexContext *s = avctx->priv_data;
00106     int16_t *output;
00107     int ret, consumed = 0;
00108 
00109     /* get output buffer */
00110     s->frame.nb_samples = s->frame_size;
00111     if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
00112         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00113         return ret;
00114     }
00115     output = (int16_t *)s->frame.data[0];
00116 
00117     /* if there is not enough data left for the smallest possible frame,
00118        reset the libspeex buffer using the current packet, otherwise ignore
00119        the current packet and keep decoding frames from the libspeex buffer. */
00120     if (speex_bits_remaining(&s->bits) < 43) {
00121         /* check for flush packet */
00122         if (!buf || !buf_size) {
00123             *got_frame_ptr = 0;
00124             return buf_size;
00125         }
00126         /* set new buffer */
00127         speex_bits_read_from(&s->bits, buf, buf_size);
00128         consumed = buf_size;
00129     }
00130 
00131     /* decode a single frame */
00132     ret = speex_decode_int(s->dec_state, &s->bits, output);
00133     if (ret <= -2) {
00134         av_log(avctx, AV_LOG_ERROR, "Error decoding Speex frame.\n");
00135         return AVERROR_INVALIDDATA;
00136     }
00137     if (avctx->channels == 2)
00138         speex_decode_stereo_int(output, s->frame_size, &s->stereo);
00139 
00140     *got_frame_ptr   = 1;
00141     *(AVFrame *)data = s->frame;
00142 
00143     return consumed;
00144 }
00145 
00146 static av_cold int libspeex_decode_close(AVCodecContext *avctx)
00147 {
00148     LibSpeexContext *s = avctx->priv_data;
00149 
00150     speex_header_free(s->header);
00151     speex_bits_destroy(&s->bits);
00152     speex_decoder_destroy(s->dec_state);
00153 
00154     return 0;
00155 }
00156 
00157 static av_cold void libspeex_decode_flush(AVCodecContext *avctx)
00158 {
00159     LibSpeexContext *s = avctx->priv_data;
00160     speex_bits_reset(&s->bits);
00161 }
00162 
00163 AVCodec ff_libspeex_decoder = {
00164     .name           = "libspeex",
00165     .type           = AVMEDIA_TYPE_AUDIO,
00166     .id             = CODEC_ID_SPEEX,
00167     .priv_data_size = sizeof(LibSpeexContext),
00168     .init           = libspeex_decode_init,
00169     .close          = libspeex_decode_close,
00170     .decode         = libspeex_decode_frame,
00171     .flush          = libspeex_decode_flush,
00172     .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DELAY | CODEC_CAP_DR1,
00173     .long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"),
00174 };
Generated on Sat Mar 17 2012 12:57:46 for Libav by doxygen 1.7.1