Mercurial > mplayer.hg
annotate libmpcodecs/ad_speex.c @ 33179:218edd8fc782
Cosmetic: Format to MPlayer coding style.
Additionally: remove needless includes, group and sort includes, group
and sort variables, rename gtkAOFakeSurround declaration gtkAOSurround,
add #ifdefs to variable declarations, group statements by adding or
removing new lines to ease reading, move assignments outside conditions,
add parentheses, avoid mixing declaration and code, revise comments and
add new ones.
author | ib |
---|---|
date | Fri, 15 Apr 2011 14:30:58 +0000 |
parents | 1baaacf00bbb |
children | 1ff13ad1bc59 |
rev | line source |
---|---|
30421
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
1 /* |
16916 | 2 * Speex decoder by Reimar Döffinger <Reimar.Doeffinger@stud.uni-karlsruhe.de> |
30421
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
3 * |
16916 | 4 * This code may be be relicensed under the terms of the GNU LGPL when it |
5 * becomes part of the FFmpeg project (ffmpeg.org) | |
30421
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
6 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
7 * This file is part of MPlayer. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
8 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
9 * MPlayer is free software; you can redistribute it and/or modify |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
10 * it under the terms of the GNU General Public License as published by |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
11 * the Free Software Foundation; either version 2 of the License, or |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
12 * (at your option) any later version. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
13 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
14 * MPlayer is distributed in the hope that it will be useful, |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
17 * GNU General Public License for more details. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
18 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
19 * You should have received a copy of the GNU General Public License along |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
20 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
16916 | 22 */ |
30421
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
20962
diff
changeset
|
23 |
16916 | 24 #include "config.h" |
18157
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
25 #include <stdlib.h> |
16916 | 26 #include <speex/speex.h> |
27 #include <speex/speex_stereo.h> | |
28 #include <speex/speex_header.h> | |
29 #include "ad_internal.h" | |
30 | |
30504
cc27da5d7286
Mark all ad_info_t/vd_info_t structure declarations as const.
diego
parents:
30421
diff
changeset
|
31 static const ad_info_t info = { |
16916 | 32 "Speex audio decoder", |
33 "speex", | |
34 "Reimar Döffinger", | |
35 "", | |
36 "" | |
37 }; | |
38 | |
39 LIBAD_EXTERN(speex) | |
40 | |
41 typedef struct { | |
42 SpeexBits bits; | |
43 void *dec_context; | |
44 SpeexStereoState stereo; | |
45 SpeexHeader *hdr; | |
46 } context_t; | |
47 | |
18157
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
48 #define MAX_FRAMES_PER_PACKET 100 |
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
49 |
16916 | 50 static int preinit(sh_audio_t *sh) { |
18157
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
51 sh->audio_out_minsize = 2 * 320 * MAX_FRAMES_PER_PACKET * 2 * sizeof(short); |
16916 | 52 return 1; |
53 } | |
54 | |
30842
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
55 static int read_le32(const uint8_t **src) { |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
56 const uint8_t *p = *src; |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
57 *src += 4; |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
58 return p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24); |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
59 } |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
60 |
16916 | 61 static int init(sh_audio_t *sh) { |
18879 | 62 context_t *ctx = calloc(1, sizeof(context_t)); |
30842
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
63 const uint8_t *hdr = (const uint8_t *)(sh->wf + 1); |
16916 | 64 const SpeexMode *spx_mode; |
65 const SpeexStereoState st_st = SPEEX_STEREO_STATE_INIT; // hack | |
66 if (!sh->wf || sh->wf->cbSize < 80) { | |
67 mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Missing extradata!\n"); | |
32602 | 68 goto err_out; |
16916 | 69 } |
70 ctx->hdr = speex_packet_to_header((char *)&sh->wf[1], sh->wf->cbSize); | |
30842
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
71 if (!ctx->hdr && sh->wf->cbSize == 0x72 && hdr[0] == 1 && hdr[1] == 0) { |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
72 // speex.acm format: raw SpeexHeader dump |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
73 ctx->hdr = calloc(1, sizeof(*ctx->hdr)); |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
74 hdr += 2; |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
75 hdr += 8; // identifier string |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
76 hdr += 20; // version string |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
77 ctx->hdr->speex_version_id = read_le32(&hdr); |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
78 ctx->hdr->header_size = read_le32(&hdr); |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
79 ctx->hdr->rate = read_le32(&hdr); |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
80 ctx->hdr->mode = read_le32(&hdr); |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
81 ctx->hdr->mode_bitstream_version = read_le32(&hdr); |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
82 ctx->hdr->nb_channels = read_le32(&hdr); |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
83 ctx->hdr->bitrate = read_le32(&hdr); |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
84 ctx->hdr->frame_size = read_le32(&hdr); |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
85 ctx->hdr->vbr = read_le32(&hdr); |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
86 ctx->hdr->frames_per_packet = read_le32(&hdr); |
482aa22c785e
Support extradata format of the speex.acm windows codec formerly available
reimar
parents:
30841
diff
changeset
|
87 } |
30841 | 88 if (!ctx->hdr) { |
89 mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Invalid extradata!\n"); | |
32602 | 90 goto err_out; |
30841 | 91 } |
16916 | 92 if (ctx->hdr->nb_channels != 1 && ctx->hdr->nb_channels != 2) { |
93 mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Invalid number of channels (%i), " | |
94 "assuming mono\n", ctx->hdr->nb_channels); | |
95 ctx->hdr->nb_channels = 1; | |
96 } | |
18157
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
97 if (ctx->hdr->frames_per_packet > MAX_FRAMES_PER_PACKET) { |
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
98 mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Invalid number of frames per packet (%i), " |
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
99 "assuming 1\n", ctx->hdr->frames_per_packet); |
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
100 ctx->hdr->frames_per_packet = 1; |
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
101 } |
16916 | 102 switch (ctx->hdr->mode) { |
103 case 0: | |
104 spx_mode = &speex_nb_mode; break; | |
105 case 1: | |
106 spx_mode = &speex_wb_mode; break; | |
107 case 2: | |
108 spx_mode = &speex_uwb_mode; break; | |
109 default: | |
18157
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
110 mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Unknown speex mode (%i)\n", ctx->hdr->mode); |
16916 | 111 spx_mode = &speex_nb_mode; |
112 } | |
113 ctx->dec_context = speex_decoder_init(spx_mode); | |
114 speex_bits_init(&ctx->bits); | |
115 memcpy(&ctx->stereo, &st_st, sizeof(ctx->stereo)); // hack part 2 | |
116 sh->channels = ctx->hdr->nb_channels; | |
117 sh->samplerate = ctx->hdr->rate; | |
118 sh->samplesize = 2; | |
119 sh->sample_format = AF_FORMAT_S16_NE; | |
120 sh->context = ctx; | |
121 return 1; | |
32602 | 122 |
123 err_out: | |
124 if (ctx) | |
125 free(ctx->hdr); | |
126 free(ctx); | |
127 return 0; | |
16916 | 128 } |
129 | |
130 static void uninit(sh_audio_t *sh) { | |
131 context_t *ctx = sh->context; | |
132 if (ctx) { | |
133 speex_bits_destroy(&ctx->bits); | |
134 speex_decoder_destroy(ctx->dec_context); | |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
30842
diff
changeset
|
135 free(ctx->hdr); |
16916 | 136 free(ctx); |
137 } | |
138 ctx = NULL; | |
139 } | |
140 | |
141 static int decode_audio(sh_audio_t *sh, unsigned char *buf, | |
142 int minlen, int maxlen) { | |
32617
1baaacf00bbb
Improve speex codec pts handling, make audio timestamps work reasonably
reimar
parents:
32602
diff
changeset
|
143 double pts; |
16916 | 144 context_t *ctx = sh->context; |
145 int len, framelen, framesamples; | |
146 char *packet; | |
147 int i, err; | |
148 speex_decoder_ctl(ctx->dec_context, SPEEX_GET_FRAME_SIZE, &framesamples); | |
149 framelen = framesamples * ctx->hdr->nb_channels * sizeof(short); | |
150 if (maxlen < ctx->hdr->frames_per_packet * framelen) { | |
151 mp_msg(MSGT_DECAUDIO, MSGL_V, "maxlen too small in decode_audio\n"); | |
152 return -1; | |
153 } | |
32617
1baaacf00bbb
Improve speex codec pts handling, make audio timestamps work reasonably
reimar
parents:
32602
diff
changeset
|
154 len = ds_get_packet_pts(sh->ds, (unsigned char **)&packet, &pts); |
16916 | 155 if (len <= 0) return -1; |
32617
1baaacf00bbb
Improve speex codec pts handling, make audio timestamps work reasonably
reimar
parents:
32602
diff
changeset
|
156 if (sh->pts == MP_NOPTS_VALUE) |
1baaacf00bbb
Improve speex codec pts handling, make audio timestamps work reasonably
reimar
parents:
32602
diff
changeset
|
157 sh->pts = 0; |
1baaacf00bbb
Improve speex codec pts handling, make audio timestamps work reasonably
reimar
parents:
32602
diff
changeset
|
158 if (pts != MP_NOPTS_VALUE) { |
1baaacf00bbb
Improve speex codec pts handling, make audio timestamps work reasonably
reimar
parents:
32602
diff
changeset
|
159 sh->pts = pts; |
1baaacf00bbb
Improve speex codec pts handling, make audio timestamps work reasonably
reimar
parents:
32602
diff
changeset
|
160 sh->pts_bytes = 0; |
1baaacf00bbb
Improve speex codec pts handling, make audio timestamps work reasonably
reimar
parents:
32602
diff
changeset
|
161 } |
16916 | 162 speex_bits_read_from(&ctx->bits, packet, len); |
163 i = ctx->hdr->frames_per_packet; | |
164 do { | |
165 err = speex_decode_int(ctx->dec_context, &ctx->bits, (short *)buf); | |
166 if (err == -2) | |
167 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Error decoding file.\n"); | |
168 if (ctx->hdr->nb_channels == 2) | |
169 speex_decode_stereo_int((short *)buf, framesamples, &ctx->stereo); | |
170 buf = &buf[framelen]; | |
171 } while (--i > 0); | |
32617
1baaacf00bbb
Improve speex codec pts handling, make audio timestamps work reasonably
reimar
parents:
32602
diff
changeset
|
172 sh->pts_bytes += ctx->hdr->frames_per_packet * framelen; |
16916 | 173 return ctx->hdr->frames_per_packet * framelen; |
174 } | |
175 | |
176 static int control(sh_audio_t *sh, int cmd, void *arg, ...) { | |
177 return CONTROL_UNKNOWN; | |
178 } |