annotate ac3dec.c @ 4166:eced83504436 libavcodec

mp3 header (de)compression bitstream filter this will make mp3 frames 4 bytes smaller, it will not give you binary identical mp3 files, but it will give you mp3 files which decode to binary identical output this will only work in containers providing at least packet size, sample_rate and number of channels bugreports about mp3 files for which this fails are welcome and this is experimental (dont expect compatibility and dont even expect to be able to decompress what you compressed, hell dont even expect this to work without editing the source a little)
author michael
date Fri, 10 Nov 2006 01:41:53 +0000
parents c8c591fe26f8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
1 /*
986e461dc072 Initial revision
glantau
parents:
diff changeset
2 * AC3 decoder
429
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
3 * Copyright (c) 2001 Fabrice Bellard.
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
4 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
5 * This file is part of FFmpeg.
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
6 *
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
429
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
9 * License as published by the Free Software Foundation; either
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
11 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
429
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
15 * Lesser General Public License for more details.
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
16 *
429
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
3036
0b546eab515d Update licensing information: The FSF changed postal address.
diego
parents: 2979
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
20 */
1106
1e39f273ecd6 per file doxy
michaelni
parents: 1064
diff changeset
21
1e39f273ecd6 per file doxy
michaelni
parents: 1064
diff changeset
22 /**
1e39f273ecd6 per file doxy
michaelni
parents: 1064
diff changeset
23 * @file ac3dec.c
1e39f273ecd6 per file doxy
michaelni
parents: 1064
diff changeset
24 * AC3 decoder.
1e39f273ecd6 per file doxy
michaelni
parents: 1064
diff changeset
25 */
1e39f273ecd6 per file doxy
michaelni
parents: 1064
diff changeset
26
1e39f273ecd6 per file doxy
michaelni
parents: 1064
diff changeset
27 //#define DEBUG
1e39f273ecd6 per file doxy
michaelni
parents: 1064
diff changeset
28
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
29 #include "avcodec.h"
986e461dc072 Initial revision
glantau
parents:
diff changeset
30 #include "libac3/ac3.h"
986e461dc072 Initial revision
glantau
parents:
diff changeset
31
986e461dc072 Initial revision
glantau
parents:
diff changeset
32 /* currently, I use libac3 which is Copyright (C) Aaron Holtzman and
986e461dc072 Initial revision
glantau
parents:
diff changeset
33 released under the GPL license. I may reimplement it someday... */
986e461dc072 Initial revision
glantau
parents:
diff changeset
34 typedef struct AC3DecodeState {
1064
b32afefe7d33 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 429
diff changeset
35 uint8_t inbuf[4096]; /* input buffer */
b32afefe7d33 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 429
diff changeset
36 uint8_t *inbuf_ptr;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
37 int frame_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
38 int flags;
314
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
39 int channels;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
40 ac3_state_t state;
986e461dc072 Initial revision
glantau
parents:
diff changeset
41 } AC3DecodeState;
986e461dc072 Initial revision
glantau
parents:
diff changeset
42
986e461dc072 Initial revision
glantau
parents:
diff changeset
43 static int ac3_decode_init(AVCodecContext *avctx)
986e461dc072 Initial revision
glantau
parents:
diff changeset
44 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
45 AC3DecodeState *s = avctx->priv_data;
986e461dc072 Initial revision
glantau
parents:
diff changeset
46
986e461dc072 Initial revision
glantau
parents:
diff changeset
47 ac3_init ();
986e461dc072 Initial revision
glantau
parents:
diff changeset
48 s->inbuf_ptr = s->inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
49 s->frame_size = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
50 return 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
51 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
52
986e461dc072 Initial revision
glantau
parents:
diff changeset
53 stream_samples_t samples;
986e461dc072 Initial revision
glantau
parents:
diff changeset
54
986e461dc072 Initial revision
glantau
parents:
diff changeset
55 /**** the following two functions comes from ac3dec */
986e461dc072 Initial revision
glantau
parents:
diff changeset
56 static inline int blah (int32_t i)
986e461dc072 Initial revision
glantau
parents:
diff changeset
57 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
58 if (i > 0x43c07fff)
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
59 return 32767;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
60 else if (i < 0x43bf8000)
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
61 return -32768;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
62 else
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
63 return i - 0x43c00000;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
64 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
65
1064
b32afefe7d33 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 429
diff changeset
66 static inline void float_to_int (float * _f, int16_t * s16, int nchannels)
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
67 {
314
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
68 int i, j, c;
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
69 int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
70
314
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
71 j = 0;
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
72 nchannels *= 256;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
73 for (i = 0; i < 256; i++) {
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
74 for (c = 0; c < nchannels; c += 256)
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
75 s16[j++] = blah (f[i + c]);
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
76 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
77 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
78
986e461dc072 Initial revision
glantau
parents:
diff changeset
79 /**** end */
986e461dc072 Initial revision
glantau
parents:
diff changeset
80
986e461dc072 Initial revision
glantau
parents:
diff changeset
81 #define HEADER_SIZE 7
986e461dc072 Initial revision
glantau
parents:
diff changeset
82
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2846
diff changeset
83 static int ac3_decode_frame(AVCodecContext *avctx,
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
84 void *data, int *data_size,
1064
b32afefe7d33 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 429
diff changeset
85 uint8_t *buf, int buf_size)
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
86 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
87 AC3DecodeState *s = avctx->priv_data;
1064
b32afefe7d33 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 429
diff changeset
88 uint8_t *buf_ptr;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
89 int flags, i, len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
90 int sample_rate, bit_rate;
986e461dc072 Initial revision
glantau
parents:
diff changeset
91 short *out_samples = data;
986e461dc072 Initial revision
glantau
parents:
diff changeset
92 float level;
323
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
93 static const int ac3_channels[8] = {
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
94 2, 1, 2, 3, 3, 4, 4, 5
314
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
95 };
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
96
986e461dc072 Initial revision
glantau
parents:
diff changeset
97 buf_ptr = buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
98 while (buf_size > 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
99 len = s->inbuf_ptr - s->inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
100 if (s->frame_size == 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
101 /* no header seen : find one. We need at least 7 bytes to parse it */
986e461dc072 Initial revision
glantau
parents:
diff changeset
102 len = HEADER_SIZE - len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
103 if (len > buf_size)
986e461dc072 Initial revision
glantau
parents:
diff changeset
104 len = buf_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
105 memcpy(s->inbuf_ptr, buf_ptr, len);
986e461dc072 Initial revision
glantau
parents:
diff changeset
106 buf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
107 s->inbuf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
108 buf_size -= len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
109 if ((s->inbuf_ptr - s->inbuf) == HEADER_SIZE) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
110 len = ac3_syncinfo (s->inbuf, &s->flags, &sample_rate, &bit_rate);
986e461dc072 Initial revision
glantau
parents:
diff changeset
111 if (len == 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
112 /* no sync found : move by one byte (inefficient, but simple!) */
986e461dc072 Initial revision
glantau
parents:
diff changeset
113 memcpy(s->inbuf, s->inbuf + 1, HEADER_SIZE - 1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
114 s->inbuf_ptr--;
986e461dc072 Initial revision
glantau
parents:
diff changeset
115 } else {
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
116 s->frame_size = len;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
117 /* update codec info */
986e461dc072 Initial revision
glantau
parents:
diff changeset
118 avctx->sample_rate = sample_rate;
314
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
119 s->channels = ac3_channels[s->flags & 7];
318
21697f35a9ca - Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for
pulento
parents: 314
diff changeset
120 if (s->flags & AC3_LFE)
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
121 s->channels++;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
122 if (avctx->channels == 0)
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
123 /* No specific number of channel requested */
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
124 avctx->channels = s->channels;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
125 else if (s->channels < avctx->channels) {
2846
40765c51a7a9 Compilation fixes part 1 patch by (Arvind R. and Burkhard Plaum, plaum, ipf uni-stuttgart de)
michael
parents: 2028
diff changeset
126 av_log( avctx, AV_LOG_INFO, "ac3dec: AC3 Source channels are less than specified: output to %d channels.. (frmsize: %d)\n", s->channels, len);
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
127 avctx->channels = s->channels;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
128 }
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
129 avctx->bit_rate = bit_rate;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
130 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
131 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
132 } else if (len < s->frame_size) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
133 len = s->frame_size - len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
134 if (len > buf_size)
986e461dc072 Initial revision
glantau
parents:
diff changeset
135 len = buf_size;
323
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
136
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
137 memcpy(s->inbuf_ptr, buf_ptr, len);
986e461dc072 Initial revision
glantau
parents:
diff changeset
138 buf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
139 s->inbuf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
140 buf_size -= len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
141 } else {
318
21697f35a9ca - Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for
pulento
parents: 314
diff changeset
142 flags = s->flags;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
143 if (avctx->channels == 1)
986e461dc072 Initial revision
glantau
parents:
diff changeset
144 flags = AC3_MONO;
318
21697f35a9ca - Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for
pulento
parents: 314
diff changeset
145 else if (avctx->channels == 2)
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
146 flags = AC3_STEREO;
318
21697f35a9ca - Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for
pulento
parents: 314
diff changeset
147 else
21697f35a9ca - Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for
pulento
parents: 314
diff changeset
148 flags |= AC3_ADJUST_LEVEL;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
149 level = 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
150 if (ac3_frame (&s->state, s->inbuf, &flags, &level, 384)) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
151 fail:
986e461dc072 Initial revision
glantau
parents:
diff changeset
152 s->inbuf_ptr = s->inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
153 s->frame_size = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
154 continue;
986e461dc072 Initial revision
glantau
parents:
diff changeset
155 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
156 for (i = 0; i < 6; i++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
157 if (ac3_block (&s->state))
986e461dc072 Initial revision
glantau
parents:
diff changeset
158 goto fail;
318
21697f35a9ca - Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for
pulento
parents: 314
diff changeset
159 float_to_int (*samples, out_samples + i * 256 * avctx->channels, avctx->channels);
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
160 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
161 s->inbuf_ptr = s->inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
162 s->frame_size = 0;
1064
b32afefe7d33 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 429
diff changeset
163 *data_size = 6 * avctx->channels * 256 * sizeof(int16_t);
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
164 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
165 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
166 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
167 return buf_ptr - buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
168 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
169
986e461dc072 Initial revision
glantau
parents:
diff changeset
170 static int ac3_decode_end(AVCodecContext *s)
986e461dc072 Initial revision
glantau
parents:
diff changeset
171 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
172 return 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
173 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
174
986e461dc072 Initial revision
glantau
parents:
diff changeset
175 AVCodec ac3_decoder = {
986e461dc072 Initial revision
glantau
parents:
diff changeset
176 "ac3",
986e461dc072 Initial revision
glantau
parents:
diff changeset
177 CODEC_TYPE_AUDIO,
986e461dc072 Initial revision
glantau
parents:
diff changeset
178 CODEC_ID_AC3,
986e461dc072 Initial revision
glantau
parents:
diff changeset
179 sizeof(AC3DecodeState),
986e461dc072 Initial revision
glantau
parents:
diff changeset
180 ac3_decode_init,
986e461dc072 Initial revision
glantau
parents:
diff changeset
181 NULL,
986e461dc072 Initial revision
glantau
parents:
diff changeset
182 ac3_decode_end,
986e461dc072 Initial revision
glantau
parents:
diff changeset
183 ac3_decode_frame,
986e461dc072 Initial revision
glantau
parents:
diff changeset
184 };