Mercurial > mplayer.hg
annotate libmpcodecs/ad_speex.c @ 30086:f72ea7a67421
Introduce a sh_common struct that contains the parts in common by the audio, video
and sub "stream headers".
One reason for this is to help avoid/make more obvious things like members with
the same function but different name (extradata vs. codecdata etc.), or members
with the same name but different semantics (pts for audio vs. pts for video).
author | reimar |
---|---|
date | Sun, 27 Dec 2009 14:40:56 +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 |