Mercurial > libavcodec.hg
annotate libspeexdec.c @ 8991:ca768cb2bfb6 libavcodec
Use last decoded SPS as current SPS in order to parse picture timing SEI
correctly. This works around an apparent H.264 standard deficiency.
Patch by Ivan Schreter, schreter gmx net
| author | cehoyos |
|---|---|
| date | Fri, 20 Feb 2009 16:20:01 +0000 |
| parents | 4bb782c7793e |
| children | 54bc8a2727b0 |
| rev | line source |
|---|---|
| 8047 | 1 /* |
| 2 * Copyright (C) 2008 David Conrad | |
| 3 * | |
| 4 * This file is part of FFmpeg. | |
| 5 * | |
| 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. | |
| 10 * | |
| 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. | |
| 15 * | |
| 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 | |
| 19 */ | |
| 20 | |
| 21 #include "avcodec.h" | |
| 22 #include <speex/speex.h> | |
| 23 #include <speex/speex_header.h> | |
| 24 #include <speex/speex_stereo.h> | |
| 25 #include <speex/speex_callbacks.h> | |
| 26 | |
| 27 typedef struct { | |
| 28 SpeexBits bits; | |
| 29 SpeexStereoState stereo; | |
| 30 void *dec_state; | |
| 31 SpeexHeader *header; | |
| 32 } LibSpeexContext; | |
| 33 | |
| 34 | |
| 35 static av_cold int libspeex_decode_init(AVCodecContext *avctx) | |
| 36 { | |
| 37 LibSpeexContext *s = avctx->priv_data; | |
| 38 const SpeexMode *mode; | |
| 39 | |
| 40 // defaults in the case of a missing header | |
| 41 if (avctx->sample_rate <= 8000) | |
| 42 mode = &speex_nb_mode; | |
| 43 else if (avctx->sample_rate <= 16000) | |
| 44 mode = &speex_wb_mode; | |
| 45 else | |
| 46 mode = &speex_uwb_mode; | |
| 47 | |
| 48 if (avctx->extradata_size >= 80) | |
| 49 s->header = speex_packet_to_header(avctx->extradata, avctx->extradata_size); | |
| 50 | |
| 51 avctx->sample_fmt = SAMPLE_FMT_S16; | |
| 52 if (s->header) { | |
| 53 avctx->sample_rate = s->header->rate; | |
| 54 avctx->channels = s->header->nb_channels; | |
| 55 avctx->frame_size = s->header->frame_size; | |
| 56 | |
| 57 mode = speex_lib_get_mode(s->header->mode); | |
| 58 if (!mode) { | |
| 59 av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", s->header->mode); | |
| 60 return -1; | |
| 61 } | |
| 62 } else | |
|
8768
4bb782c7793e
cosmetics: Fix a few typos and use a consistent codec long name.
diego
parents:
8047
diff
changeset
|
63 av_log(avctx, AV_LOG_INFO, "Missing Speex header, assuming defaults.\n"); |
| 8047 | 64 |
| 65 if (avctx->channels > 2) { | |
|
8768
4bb782c7793e
cosmetics: Fix a few typos and use a consistent codec long name.
diego
parents:
8047
diff
changeset
|
66 av_log(avctx, AV_LOG_ERROR, "Only stereo and mono are supported.\n"); |
| 8047 | 67 return -1; |
| 68 } | |
| 69 | |
| 70 speex_bits_init(&s->bits); | |
| 71 s->dec_state = speex_decoder_init(mode); | |
| 72 if (!s->dec_state) { | |
|
8768
4bb782c7793e
cosmetics: Fix a few typos and use a consistent codec long name.
diego
parents:
8047
diff
changeset
|
73 av_log(avctx, AV_LOG_ERROR, "Error initializing libspeex decoder.\n"); |
| 8047 | 74 return -1; |
| 75 } | |
| 76 | |
| 77 if (!s->header) | |
| 78 speex_decoder_ctl(s->dec_state, SPEEX_GET_FRAME_SIZE, &avctx->frame_size); | |
| 79 | |
| 80 if (avctx->channels == 2) { | |
| 81 SpeexCallback callback; | |
| 82 callback.callback_id = SPEEX_INBAND_STEREO; | |
| 83 callback.func = speex_std_stereo_request_handler; | |
| 84 callback.data = &s->stereo; | |
| 85 s->stereo = (SpeexStereoState)SPEEX_STEREO_STATE_INIT; | |
| 86 speex_decoder_ctl(s->dec_state, SPEEX_SET_HANDLER, &callback); | |
| 87 } | |
| 88 return 0; | |
| 89 } | |
| 90 | |
| 91 static int libspeex_decode_frame(AVCodecContext *avctx, | |
| 92 void *data, int *data_size, | |
| 93 const uint8_t *buf, int buf_size) | |
| 94 { | |
| 95 LibSpeexContext *s = avctx->priv_data; | |
| 96 int16_t *output = data, *end; | |
| 97 int i, num_samples; | |
| 98 | |
| 99 num_samples = avctx->frame_size * avctx->channels; | |
| 100 end = output + *data_size/2; | |
| 101 | |
| 102 speex_bits_read_from(&s->bits, buf, buf_size); | |
| 103 | |
| 104 for (i = 0; speex_bits_remaining(&s->bits) && output + num_samples < end; i++) { | |
| 105 int ret = speex_decode_int(s->dec_state, &s->bits, output); | |
| 106 if (ret <= -2) { | |
|
8768
4bb782c7793e
cosmetics: Fix a few typos and use a consistent codec long name.
diego
parents:
8047
diff
changeset
|
107 av_log(avctx, AV_LOG_ERROR, "Error decoding Speex frame.\n"); |
| 8047 | 108 return -1; |
| 109 } else if (ret == -1) | |
| 110 // end of stream | |
| 111 break; | |
| 112 | |
| 113 if (avctx->channels == 2) | |
| 114 speex_decode_stereo_int(output, avctx->frame_size, &s->stereo); | |
| 115 | |
| 116 output += num_samples; | |
| 117 } | |
| 118 | |
| 119 *data_size = i * avctx->channels * avctx->frame_size * 2; | |
| 120 return buf_size; | |
| 121 } | |
| 122 | |
| 123 static av_cold int libspeex_decode_close(AVCodecContext *avctx) | |
| 124 { | |
| 125 LibSpeexContext *s = avctx->priv_data; | |
| 126 | |
| 127 speex_header_free(s->header); | |
| 128 speex_bits_destroy(&s->bits); | |
| 129 speex_decoder_destroy(s->dec_state); | |
| 130 | |
| 131 return 0; | |
| 132 } | |
| 133 | |
| 134 AVCodec libspeex_decoder = { | |
| 135 "libspeex", | |
| 136 CODEC_TYPE_AUDIO, | |
| 137 CODEC_ID_SPEEX, | |
| 138 sizeof(LibSpeexContext), | |
| 139 libspeex_decode_init, | |
| 140 NULL, | |
| 141 libspeex_decode_close, | |
| 142 libspeex_decode_frame, | |
|
8768
4bb782c7793e
cosmetics: Fix a few typos and use a consistent codec long name.
diego
parents:
8047
diff
changeset
|
143 .long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"), |
| 8047 | 144 }; |
