You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	Speex decoding via libspeex
Originally committed as revision 15676 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		
							
								
								
									
										5
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								configure
									
									
									
									
										vendored
									
									
								
							| @@ -102,6 +102,7 @@ show_help(){ | ||||
|   echo "  --enable-libnut          enable NUT (de)muxing via libnut," | ||||
|   echo "                           native demuxer exists [default=no]" | ||||
|   echo "  --enable-libschroedinger enable Dirac support via libschroedinger [default=no]" | ||||
|   echo "  --enable-libspeex        enable Speex decoding via libspeex [default=no]" | ||||
|   echo "  --enable-libtheora       enable Theora encoding via libtheora [default=no]" | ||||
|   echo "  --enable-libvorbis       enable Vorbis encoding via libvorbis," | ||||
|   echo "                           native implementation exists [default=no]" | ||||
| @@ -692,6 +693,7 @@ CONFIG_LIST=" | ||||
|     libmp3lame | ||||
|     libnut | ||||
|     libschroedinger | ||||
|     libspeex | ||||
|     libtheora | ||||
|     libvorbis | ||||
|     libx264 | ||||
| @@ -891,6 +893,7 @@ libgsm_ms_encoder_deps="libgsm" | ||||
| libmp3lame_encoder_deps="libmp3lame" | ||||
| libschroedinger_decoder_deps="libschroedinger" | ||||
| libschroedinger_encoder_deps="libschroedinger" | ||||
| libspeex_decoder_deps="libspeex" | ||||
| libtheora_encoder_deps="libtheora" | ||||
| libvorbis_encoder_deps="libvorbis" | ||||
| libx264_encoder_deps="libx264" | ||||
| @@ -1730,6 +1733,7 @@ enabled libmp3lame && require  LAME lame/lame.h lame_init -lmp3lame -lm | ||||
| enabled libnut     && require  libnut libnut.h nut_demuxer_init -lnut | ||||
| enabled libschroedinger && add_cflags $(pkg-config --cflags schroedinger-1.0) && | ||||
|                            require libschroedinger schroedinger/schro.h schro_init $(pkg-config --libs schroedinger-1.0) | ||||
| enabled libspeex   && require  libspeex speex/speex.h speex_decoder_init -lspeex | ||||
| enabled libtheora  && require  libtheora theora/theora.h theora_info_init -ltheora -logg | ||||
| enabled libvorbis  && require  libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg | ||||
| enabled libx264    && require  x264 x264.h x264_encoder_open -lx264 -lm && | ||||
| @@ -2036,6 +2040,7 @@ echo "libgsm enabled            ${libgsm-no}" | ||||
| echo "libmp3lame enabled        ${libmp3lame-no}" | ||||
| echo "libnut enabled            ${libnut-no}" | ||||
| echo "libschroedinger enabled   ${libschroedinger-no}" | ||||
| echo "libspeex enabled          ${libspeex-no}" | ||||
| echo "libtheora enabled         ${libtheora-no}" | ||||
| echo "libvorbis enabled         ${libvorbis-no}" | ||||
| echo "libx264 enabled           ${libx264-no}" | ||||
|   | ||||
| @@ -334,6 +334,7 @@ OBJS-$(CONFIG_LIBGSM)                  += libgsm.o | ||||
| OBJS-$(CONFIG_LIBMP3LAME)              += libmp3lame.o | ||||
| OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o libschroedinger.o libdirac_libschro.o | ||||
| OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o libschroedinger.o libdirac_libschro.o | ||||
| OBJS-$(CONFIG_LIBSPEEX)                += libspeexdec.o | ||||
| OBJS-$(CONFIG_LIBTHEORA)               += libtheoraenc.o | ||||
| OBJS-$(CONFIG_LIBVORBIS)               += libvorbis.o | ||||
| OBJS-$(CONFIG_LIBX264)                 += libx264.o | ||||
|   | ||||
| @@ -293,6 +293,7 @@ void avcodec_register_all(void) | ||||
|     REGISTER_ENCDEC  (LIBGSM_MS, libgsm_ms); | ||||
|     REGISTER_ENCODER (LIBMP3LAME, libmp3lame); | ||||
|     REGISTER_ENCDEC  (LIBSCHROEDINGER, libschroedinger); | ||||
|     REGISTER_DECODER (LIBSPEEX, libspeex); | ||||
|     REGISTER_ENCODER (LIBTHEORA, libtheora); | ||||
|     REGISTER_ENCODER (LIBVORBIS, libvorbis); | ||||
|     REGISTER_ENCODER (LIBX264, libx264); | ||||
|   | ||||
							
								
								
									
										144
									
								
								libavcodec/libspeexdec.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								libavcodec/libspeexdec.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | ||||
| /* | ||||
|  * Copyright (C) 2008 David Conrad | ||||
|  * | ||||
|  * This file is part of FFmpeg. | ||||
|  * | ||||
|  * FFmpeg is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2.1 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * FFmpeg is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with FFmpeg; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||
|  */ | ||||
|  | ||||
| #include "avcodec.h" | ||||
| #include <speex/speex.h> | ||||
| #include <speex/speex_header.h> | ||||
| #include <speex/speex_stereo.h> | ||||
| #include <speex/speex_callbacks.h> | ||||
|  | ||||
| typedef struct { | ||||
|     SpeexBits bits; | ||||
|     SpeexStereoState stereo; | ||||
|     void *dec_state; | ||||
|     SpeexHeader *header; | ||||
| } LibSpeexContext; | ||||
|  | ||||
|  | ||||
| static av_cold int libspeex_decode_init(AVCodecContext *avctx) | ||||
| { | ||||
|     LibSpeexContext *s = avctx->priv_data; | ||||
|     const SpeexMode *mode; | ||||
|  | ||||
|     // defaults in the case of a missing header | ||||
|     if (avctx->sample_rate <= 8000) | ||||
|         mode = &speex_nb_mode; | ||||
|     else if (avctx->sample_rate <= 16000) | ||||
|         mode = &speex_wb_mode; | ||||
|     else | ||||
|         mode = &speex_uwb_mode; | ||||
|  | ||||
|     if (avctx->extradata_size >= 80) | ||||
|         s->header = speex_packet_to_header(avctx->extradata, avctx->extradata_size); | ||||
|  | ||||
|     avctx->sample_fmt = SAMPLE_FMT_S16; | ||||
|     if (s->header) { | ||||
|         avctx->sample_rate = s->header->rate; | ||||
|         avctx->channels    = s->header->nb_channels; | ||||
|         avctx->frame_size  = s->header->frame_size; | ||||
|  | ||||
|         mode = speex_lib_get_mode(s->header->mode); | ||||
|         if (!mode) { | ||||
|             av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", s->header->mode); | ||||
|             return -1; | ||||
|         } | ||||
|     } else | ||||
|         av_log(avctx, AV_LOG_INFO, "Missing speex header, assuming defaults\n"); | ||||
|  | ||||
|     if (avctx->channels > 2) { | ||||
|         av_log(avctx, AV_LOG_ERROR, "Only stereo and mono supported\n"); | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     speex_bits_init(&s->bits); | ||||
|     s->dec_state = speex_decoder_init(mode); | ||||
|     if (!s->dec_state) { | ||||
|         av_log(avctx, AV_LOG_ERROR, "Error initializing libspeex decoder\n"); | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     if (!s->header) | ||||
|         speex_decoder_ctl(s->dec_state, SPEEX_GET_FRAME_SIZE, &avctx->frame_size); | ||||
|  | ||||
|     if (avctx->channels == 2) { | ||||
|         SpeexCallback callback; | ||||
|         callback.callback_id = SPEEX_INBAND_STEREO; | ||||
|         callback.func = speex_std_stereo_request_handler; | ||||
|         callback.data = &s->stereo; | ||||
|         s->stereo = (SpeexStereoState)SPEEX_STEREO_STATE_INIT; | ||||
|         speex_decoder_ctl(s->dec_state, SPEEX_SET_HANDLER, &callback); | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int libspeex_decode_frame(AVCodecContext *avctx, | ||||
|                                  void *data, int *data_size, | ||||
|                                  const uint8_t *buf, int buf_size) | ||||
| { | ||||
|     LibSpeexContext *s = avctx->priv_data; | ||||
|     int16_t *output = data, *end; | ||||
|     int i, num_samples; | ||||
|  | ||||
|     num_samples = avctx->frame_size * avctx->channels; | ||||
|     end = output + *data_size/2; | ||||
|  | ||||
|     speex_bits_read_from(&s->bits, buf, buf_size); | ||||
|  | ||||
|     for (i = 0; speex_bits_remaining(&s->bits) && output + num_samples < end; i++) { | ||||
|         int ret = speex_decode_int(s->dec_state, &s->bits, output); | ||||
|         if (ret <= -2) { | ||||
|             av_log(avctx, AV_LOG_ERROR, "Error decoding speex frame\n"); | ||||
|             return -1; | ||||
|         } else if (ret == -1) | ||||
|             // end of stream | ||||
|             break; | ||||
|  | ||||
|         if (avctx->channels == 2) | ||||
|             speex_decode_stereo_int(output, avctx->frame_size, &s->stereo); | ||||
|  | ||||
|         output += num_samples; | ||||
|     } | ||||
|  | ||||
|     *data_size = i * avctx->channels * avctx->frame_size * 2; | ||||
|     return buf_size; | ||||
| } | ||||
|  | ||||
| static av_cold int libspeex_decode_close(AVCodecContext *avctx) | ||||
| { | ||||
|     LibSpeexContext *s = avctx->priv_data; | ||||
|  | ||||
|     speex_header_free(s->header); | ||||
|     speex_bits_destroy(&s->bits); | ||||
|     speex_decoder_destroy(s->dec_state); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| AVCodec libspeex_decoder = { | ||||
|     "libspeex", | ||||
|     CODEC_TYPE_AUDIO, | ||||
|     CODEC_ID_SPEEX, | ||||
|     sizeof(LibSpeexContext), | ||||
|     libspeex_decode_init, | ||||
|     NULL, | ||||
|     libspeex_decode_close, | ||||
|     libspeex_decode_frame, | ||||
|     .long_name = NULL_IF_CONFIG_SMALL("libspeex"), | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user