diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-10-04 13:11:45 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-10-04 13:11:45 +0200 |
commit | 0f1446a4d010a1210c8b13562e83c9b157553764 (patch) | |
tree | d774ba3ebddf721dfac6357d8d958ce757a63fa3 /libavcodec/libspeexdec.c | |
parent | 741f5b021a0494676de0dab543f8a9591ec2e01e (diff) | |
parent | ab35ec29a4071871934856c00da7d6ebcc0c095b (diff) | |
download | ffmpeg-0f1446a4d010a1210c8b13562e83c9b157553764.tar.gz |
Merge commit 'ab35ec29a4071871934856c00da7d6ebcc0c095b'
* commit 'ab35ec29a4071871934856c00da7d6ebcc0c095b':
vf_overlay: get rid of pointless messing with timebase.
samplefmt: make av_samples_alloc() initialize the data to silence.
libspeexdec: handle NULL return value from speex_packet_to_header()
h264probe: Don't error out on bits that no longer are reserved
mpegvideo: set extended_data in ff_update_duplicate_context()
libspeexdec: properly handle DTX for multiple frames-per-packet
libspeexdec: move the SpeexHeader from LibSpeexContext to where it is used
libspeexdec: simplify setting of frame_size
libspeexdec: set channel_layout
Conflicts:
libavfilter/vf_overlay.c
libavformat/h264dec.c
libavutil/version.h
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/libspeexdec.c')
-rw-r--r-- | libavcodec/libspeexdec.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c index 490e6925f5..51ab7ea07c 100644 --- a/libavcodec/libspeexdec.c +++ b/libavcodec/libspeexdec.c @@ -22,15 +22,16 @@ #include <speex/speex_header.h> #include <speex/speex_stereo.h> #include <speex/speex_callbacks.h> -#include "avcodec.h" + +#include "libavutil/audioconvert.h" #include "libavutil/common.h" +#include "avcodec.h" typedef struct { AVFrame frame; SpeexBits bits; SpeexStereoState stereo; void *dec_state; - SpeexHeader *header; int frame_size; } LibSpeexContext; @@ -39,16 +40,20 @@ static av_cold int libspeex_decode_init(AVCodecContext *avctx) { LibSpeexContext *s = avctx->priv_data; const SpeexMode *mode; + SpeexHeader *header = NULL; int spx_mode; - if (avctx->extradata_size >= 80) - s->header = speex_packet_to_header(avctx->extradata, avctx->extradata_size); - avctx->sample_fmt = AV_SAMPLE_FMT_S16; - if (s->header) { - avctx->channels = s->header->nb_channels; - s->frame_size = s->header->frame_size; - spx_mode = s->header->mode; + if (avctx->extradata && avctx->extradata_size >= 80) { + header = speex_packet_to_header(avctx->extradata, + avctx->extradata_size); + if (!header) + av_log(avctx, AV_LOG_WARNING, "Invalid Speex header\n"); + } + if (header) { + avctx->channels = header->nb_channels; + spx_mode = header->mode; + speex_header_free(header); } else { switch (avctx->sample_rate) { case 8000: spx_mode = 0; break; @@ -69,6 +74,7 @@ static av_cold int libspeex_decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } avctx->sample_rate = 8000 << spx_mode; + s->frame_size = 160 << spx_mode; if (avctx->channels < 1 || avctx->channels > 2) { /* libspeex can handle mono or stereo if initialized as stereo */ @@ -76,6 +82,8 @@ static av_cold int libspeex_decode_init(AVCodecContext *avctx) "Decoding as stereo.\n", avctx->channels); avctx->channels = 2; } + avctx->channel_layout = avctx->channels == 2 ? AV_CH_LAYOUT_STEREO : + AV_CH_LAYOUT_MONO; speex_bits_init(&s->bits); s->dec_state = speex_decoder_init(mode); @@ -84,10 +92,6 @@ static av_cold int libspeex_decode_init(AVCodecContext *avctx) return -1; } - if (!s->header) { - speex_decoder_ctl(s->dec_state, SPEEX_GET_FRAME_SIZE, &s->frame_size); - } - if (avctx->channels == 2) { SpeexCallback callback; callback.callback_id = SPEEX_INBAND_STEREO; @@ -120,10 +124,12 @@ static int libspeex_decode_frame(AVCodecContext *avctx, void *data, } output = (int16_t *)s->frame.data[0]; - /* if there is not enough data left for the smallest possible frame, - reset the libspeex buffer using the current packet, otherwise ignore - the current packet and keep decoding frames from the libspeex buffer. */ - if (speex_bits_remaining(&s->bits) < 43) { + /* if there is not enough data left for the smallest possible frame or the + next 5 bits are a terminator code, reset the libspeex buffer using the + current packet, otherwise ignore the current packet and keep decoding + frames from the libspeex buffer. */ + if (speex_bits_remaining(&s->bits) < 5 || + speex_bits_peek_unsigned(&s->bits, 5) == 0x1F) { /* check for flush packet */ if (!buf || !buf_size) { *got_frame_ptr = 0; @@ -153,7 +159,6 @@ 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); |