~ubuntu-branches/ubuntu/saucy/gst-libav1.0/saucy-proposed

« back to all changes in this revision

Viewing changes to gst-libs/ext/libav/libavcodec/libspeexdec.c

  • Committer: Package Import Robot
  • Author(s): Sebastian Dröge
  • Date: 2013-07-30 09:00:15 UTC
  • mfrom: (1.1.16) (7.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20130730090015-sc1ou2yssu7q5w4e
Tags: 1.1.3-1
* New upstream development snapshot:
  + debian/control:
    - Build depend on GStreamer and gst-plugins-base >= 1.1.3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include <speex/speex_header.h>
23
23
#include <speex/speex_stereo.h>
24
24
#include <speex/speex_callbacks.h>
 
25
 
 
26
#include "libavutil/channel_layout.h"
 
27
#include "libavutil/common.h"
25
28
#include "avcodec.h"
 
29
#include "internal.h"
26
30
 
27
31
typedef struct {
28
32
    AVFrame frame;
29
33
    SpeexBits bits;
30
34
    SpeexStereoState stereo;
31
35
    void *dec_state;
32
 
    SpeexHeader *header;
33
36
    int frame_size;
34
37
} LibSpeexContext;
35
38
 
38
41
{
39
42
    LibSpeexContext *s = avctx->priv_data;
40
43
    const SpeexMode *mode;
41
 
 
42
 
    // defaults in the case of a missing header
43
 
    if (avctx->sample_rate <= 8000)
44
 
        mode = &speex_nb_mode;
45
 
    else if (avctx->sample_rate <= 16000)
46
 
        mode = &speex_wb_mode;
47
 
    else
48
 
        mode = &speex_uwb_mode;
49
 
 
50
 
    if (avctx->extradata_size >= 80)
51
 
        s->header = speex_packet_to_header(avctx->extradata, avctx->extradata_size);
 
44
    SpeexHeader *header = NULL;
 
45
    int spx_mode;
52
46
 
53
47
    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
54
 
    if (s->header) {
55
 
        avctx->sample_rate = s->header->rate;
56
 
        avctx->channels    = s->header->nb_channels;
57
 
        avctx->frame_size  = s->frame_size = s->header->frame_size;
58
 
        if (s->header->frames_per_packet)
59
 
            avctx->frame_size *= s->header->frames_per_packet;
60
 
 
61
 
        mode = speex_lib_get_mode(s->header->mode);
62
 
        if (!mode) {
63
 
            av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", s->header->mode);
64
 
            return AVERROR_INVALIDDATA;
 
48
    if (avctx->extradata && avctx->extradata_size >= 80) {
 
49
        header = speex_packet_to_header(avctx->extradata,
 
50
                                        avctx->extradata_size);
 
51
        if (!header)
 
52
            av_log(avctx, AV_LOG_WARNING, "Invalid Speex header\n");
 
53
    }
 
54
    if (header) {
 
55
        avctx->channels    = header->nb_channels;
 
56
        spx_mode           = header->mode;
 
57
        speex_header_free(header);
 
58
    } else {
 
59
        switch (avctx->sample_rate) {
 
60
        case 8000:  spx_mode = 0; break;
 
61
        case 16000: spx_mode = 1; break;
 
62
        case 32000: spx_mode = 2; break;
 
63
        default:
 
64
            /* libspeex can handle any mode if initialized as ultra-wideband */
 
65
            av_log(avctx, AV_LOG_WARNING, "Invalid sample rate: %d\n"
 
66
                                          "Decoding as 32kHz ultra-wideband\n",
 
67
                                          avctx->sample_rate);
 
68
            spx_mode = 2;
65
69
        }
66
 
    } else
67
 
        av_log(avctx, AV_LOG_INFO, "Missing Speex header, assuming defaults.\n");
68
 
 
69
 
    if (avctx->channels > 2) {
70
 
        av_log(avctx, AV_LOG_ERROR, "Only stereo and mono are supported.\n");
71
 
        return AVERROR(EINVAL);
72
 
    }
 
70
    }
 
71
 
 
72
    mode = speex_lib_get_mode(spx_mode);
 
73
    if (!mode) {
 
74
        av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", spx_mode);
 
75
        return AVERROR_INVALIDDATA;
 
76
    }
 
77
    avctx->sample_rate = 8000 << spx_mode;
 
78
    s->frame_size      =  160 << spx_mode;
 
79
 
 
80
    if (avctx->channels < 1 || avctx->channels > 2) {
 
81
        /* libspeex can handle mono or stereo if initialized as stereo */
 
82
        av_log(avctx, AV_LOG_ERROR, "Invalid channel count: %d.\n"
 
83
                                    "Decoding as stereo.\n", avctx->channels);
 
84
        avctx->channels = 2;
 
85
    }
 
86
    avctx->channel_layout = avctx->channels == 2 ? AV_CH_LAYOUT_STEREO :
 
87
                                                   AV_CH_LAYOUT_MONO;
73
88
 
74
89
    speex_bits_init(&s->bits);
75
90
    s->dec_state = speex_decoder_init(mode);
78
93
        return -1;
79
94
    }
80
95
 
81
 
    if (!s->header) {
82
 
        speex_decoder_ctl(s->dec_state, SPEEX_GET_FRAME_SIZE, &s->frame_size);
83
 
    }
84
 
 
85
96
    if (avctx->channels == 2) {
86
97
        SpeexCallback callback;
87
98
        callback.callback_id = SPEEX_INBAND_STEREO;
108
119
 
109
120
    /* get output buffer */
110
121
    s->frame.nb_samples = s->frame_size;
111
 
    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
 
122
    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
112
123
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
113
124
        return ret;
114
125
    }
115
126
    output = (int16_t *)s->frame.data[0];
116
127
 
117
 
    /* if there is not enough data left for the smallest possible frame,
118
 
       reset the libspeex buffer using the current packet, otherwise ignore
119
 
       the current packet and keep decoding frames from the libspeex buffer. */
120
 
    if (speex_bits_remaining(&s->bits) < 43) {
 
128
    /* if there is not enough data left for the smallest possible frame or the
 
129
       next 5 bits are a terminator code, reset the libspeex buffer using the
 
130
       current packet, otherwise ignore the current packet and keep decoding
 
131
       frames from the libspeex buffer. */
 
132
    if (speex_bits_remaining(&s->bits) < 5 ||
 
133
        speex_bits_peek_unsigned(&s->bits, 5) == 0x1F) {
121
134
        /* check for flush packet */
122
135
        if (!buf || !buf_size) {
123
136
            *got_frame_ptr = 0;
147
160
{
148
161
    LibSpeexContext *s = avctx->priv_data;
149
162
 
150
 
    speex_header_free(s->header);
151
163
    speex_bits_destroy(&s->bits);
152
164
    speex_decoder_destroy(s->dec_state);
153
165
 
163
175
AVCodec ff_libspeex_decoder = {
164
176
    .name           = "libspeex",
165
177
    .type           = AVMEDIA_TYPE_AUDIO,
166
 
    .id             = CODEC_ID_SPEEX,
 
178
    .id             = AV_CODEC_ID_SPEEX,
167
179
    .priv_data_size = sizeof(LibSpeexContext),
168
180
    .init           = libspeex_decode_init,
169
181
    .close          = libspeex_decode_close,
170
182
    .decode         = libspeex_decode_frame,
171
183
    .flush          = libspeex_decode_flush,
172
184
    .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DELAY | CODEC_CAP_DR1,
173
 
    .long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"),
 
185
    .long_name      = NULL_IF_CONFIG_SMALL("libspeex Speex"),
174
186
};