Mercurial > mplayer.hg
annotate libmpcodecs/ad_speex.c @ 27980:21779d5ea61c
Create a separate codecs.conf entry for Tremor and use it if MPlayer is
with Tremor support instead of libvorbis. Previously MPlayer would show
the same output on the console when decoding with libvorbis and Tremor.
author | diego |
---|---|
date | Mon, 24 Nov 2008 08:31:44 +0000 |
parents | a95ed9a69caf |
children | bbb6ebec87a0 |
rev | line source |
---|---|
16916 | 1 /** |
2 * Speex decoder by Reimar Döffinger <Reimar.Doeffinger@stud.uni-karlsruhe.de> | |
20962
a95ed9a69caf
Put files fully owned by my under GPL v2 "or later"
reimar
parents:
18879
diff
changeset
|
3 * License: GPL v2 or later |
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) | |
6 */ | |
7 #include "config.h" | |
18157
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
8 #include <stdlib.h> |
16916 | 9 #include <speex/speex.h> |
10 #include <speex/speex_stereo.h> | |
11 #include <speex/speex_header.h> | |
12 #include "ad_internal.h" | |
13 | |
14 static ad_info_t info = { | |
15 "Speex audio decoder", | |
16 "speex", | |
17 "Reimar Döffinger", | |
18 "", | |
19 "" | |
20 }; | |
21 | |
22 LIBAD_EXTERN(speex) | |
23 | |
24 typedef struct { | |
25 SpeexBits bits; | |
26 void *dec_context; | |
27 SpeexStereoState stereo; | |
28 SpeexHeader *hdr; | |
29 } context_t; | |
30 | |
18157
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
31 #define MAX_FRAMES_PER_PACKET 100 |
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
32 |
16916 | 33 static int preinit(sh_audio_t *sh) { |
18157
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
34 sh->audio_out_minsize = 2 * 320 * MAX_FRAMES_PER_PACKET * 2 * sizeof(short); |
16916 | 35 return 1; |
36 } | |
37 | |
38 static int init(sh_audio_t *sh) { | |
18879 | 39 context_t *ctx = calloc(1, sizeof(context_t)); |
16916 | 40 const SpeexMode *spx_mode; |
41 const SpeexStereoState st_st = SPEEX_STEREO_STATE_INIT; // hack | |
42 if (!sh->wf || sh->wf->cbSize < 80) { | |
43 mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Missing extradata!\n"); | |
44 return 0; | |
45 } | |
46 ctx->hdr = speex_packet_to_header((char *)&sh->wf[1], sh->wf->cbSize); | |
47 if (ctx->hdr->nb_channels != 1 && ctx->hdr->nb_channels != 2) { | |
48 mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Invalid number of channels (%i), " | |
49 "assuming mono\n", ctx->hdr->nb_channels); | |
50 ctx->hdr->nb_channels = 1; | |
51 } | |
18157
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
52 if (ctx->hdr->frames_per_packet > MAX_FRAMES_PER_PACKET) { |
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
53 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
|
54 "assuming 1\n", ctx->hdr->frames_per_packet); |
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
55 ctx->hdr->frames_per_packet = 1; |
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
56 } |
16916 | 57 switch (ctx->hdr->mode) { |
58 case 0: | |
59 spx_mode = &speex_nb_mode; break; | |
60 case 1: | |
61 spx_mode = &speex_wb_mode; break; | |
62 case 2: | |
63 spx_mode = &speex_uwb_mode; break; | |
64 default: | |
18157
2c7219c38e56
bug fixes: left-over mode variable used uninitialized,
reimar
parents:
17429
diff
changeset
|
65 mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Unknown speex mode (%i)\n", ctx->hdr->mode); |
16916 | 66 spx_mode = &speex_nb_mode; |
67 } | |
68 ctx->dec_context = speex_decoder_init(spx_mode); | |
69 speex_bits_init(&ctx->bits); | |
70 memcpy(&ctx->stereo, &st_st, sizeof(ctx->stereo)); // hack part 2 | |
71 sh->channels = ctx->hdr->nb_channels; | |
72 sh->samplerate = ctx->hdr->rate; | |
73 sh->samplesize = 2; | |
74 sh->sample_format = AF_FORMAT_S16_NE; | |
75 sh->context = ctx; | |
76 return 1; | |
77 } | |
78 | |
79 static void uninit(sh_audio_t *sh) { | |
80 context_t *ctx = sh->context; | |
81 if (ctx) { | |
82 speex_bits_destroy(&ctx->bits); | |
83 speex_decoder_destroy(ctx->dec_context); | |
84 if (ctx->hdr) | |
17429
7dac2afa70aa
Use free instead of speex_free - since speex_free does not appear in the
reimar
parents:
16916
diff
changeset
|
85 free(ctx->hdr); |
16916 | 86 free(ctx); |
87 } | |
88 ctx = NULL; | |
89 } | |
90 | |
91 static int decode_audio(sh_audio_t *sh, unsigned char *buf, | |
92 int minlen, int maxlen) { | |
93 context_t *ctx = sh->context; | |
94 int len, framelen, framesamples; | |
95 char *packet; | |
96 int i, err; | |
97 speex_decoder_ctl(ctx->dec_context, SPEEX_GET_FRAME_SIZE, &framesamples); | |
98 framelen = framesamples * ctx->hdr->nb_channels * sizeof(short); | |
99 if (maxlen < ctx->hdr->frames_per_packet * framelen) { | |
100 mp_msg(MSGT_DECAUDIO, MSGL_V, "maxlen too small in decode_audio\n"); | |
101 return -1; | |
102 } | |
103 len = ds_get_packet(sh->ds, (unsigned char **)&packet); | |
104 if (len <= 0) return -1; | |
105 speex_bits_read_from(&ctx->bits, packet, len); | |
106 i = ctx->hdr->frames_per_packet; | |
107 do { | |
108 err = speex_decode_int(ctx->dec_context, &ctx->bits, (short *)buf); | |
109 if (err == -2) | |
110 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Error decoding file.\n"); | |
111 if (ctx->hdr->nb_channels == 2) | |
112 speex_decode_stereo_int((short *)buf, framesamples, &ctx->stereo); | |
113 buf = &buf[framelen]; | |
114 } while (--i > 0); | |
115 return ctx->hdr->frames_per_packet * framelen; | |
116 } | |
117 | |
118 static int control(sh_audio_t *sh, int cmd, void *arg, ...) { | |
119 return CONTROL_UNKNOWN; | |
120 } | |
121 |