annotate ac3_parser.c @ 6170:8cbfc9d75833 libavcodec

Put some disabled functions that are only used in the test program in cabac.c under TEST as preprocessor conditional, same as the test program.
author diego
date Wed, 23 Jan 2008 10:19:39 +0000
parents 76801e61ddc4
children 48759bfbd073
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
1 /*
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
2 * AC3 parser
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
3 * Copyright (c) 2003 Fabrice Bellard.
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
4 * Copyright (c) 2003 Michael Niedermayer.
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
5 *
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
6 * This file is part of FFmpeg.
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
7 *
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
12 *
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
16 * Lesser General Public License for more details.
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
17 *
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
21 */
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
22
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
23 #include "parser.h"
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
24 #include "ac3_parser.h"
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
25 #include "aac_ac3_parser.h"
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
26 #include "bitstream.h"
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
27
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
28
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
29 #define AC3_HEADER_SIZE 7
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
30
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
31
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
32 static const uint8_t eac3_blocks[4] = {
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
33 1, 2, 3, 6
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
34 };
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
35
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
36
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
37 int ff_ac3_parse_header(const uint8_t buf[7], AC3HeaderInfo *hdr)
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
38 {
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
39 GetBitContext gbc;
6116
4f8fcb40bf2c remove unneeded variables from AC3HeaderInfo
jbr
parents: 6005
diff changeset
40 int frame_size_code;
6117
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
41 int num_blocks;
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
42
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
43 memset(hdr, 0, sizeof(*hdr));
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
44
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
45 init_get_bits(&gbc, buf, 54);
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
46
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
47 hdr->sync_word = get_bits(&gbc, 16);
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
48 if(hdr->sync_word != 0x0B77)
5680
5ae5a74b0e4b better AC3 header error reporting
jbr
parents: 5331
diff changeset
49 return AC3_PARSE_ERROR_SYNC;
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
50
6117
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
51 /* read ahead to bsid to distinguish between AC-3 and E-AC-3 */
6005
7d9dddd54817 cosmetics: rename common ac3 variables
jbr
parents: 6003
diff changeset
52 hdr->bitstream_id = show_bits_long(&gbc, 29) & 0x1F;
6117
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
53 if(hdr->bitstream_id > 16)
5680
5ae5a74b0e4b better AC3 header error reporting
jbr
parents: 5331
diff changeset
54 return AC3_PARSE_ERROR_BSID;
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
55
6117
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
56 if(hdr->bitstream_id <= 10) {
6118
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
57 /* Normal AC-3 */
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
58 hdr->crc1 = get_bits(&gbc, 16);
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
59 hdr->sr_code = get_bits(&gbc, 2);
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
60 if(hdr->sr_code == 3)
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
61 return AC3_PARSE_ERROR_SAMPLE_RATE;
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
62
6118
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
63 frame_size_code = get_bits(&gbc, 6);
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
64 if(frame_size_code > 37)
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
65 return AC3_PARSE_ERROR_FRAME_SIZE;
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
66
6118
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
67 skip_bits(&gbc, 5); // skip bsid, already got it
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
68
6118
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
69 skip_bits(&gbc, 3); // skip bitstream mode
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
70 hdr->channel_mode = get_bits(&gbc, 3);
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
71 if((hdr->channel_mode & 1) && hdr->channel_mode != AC3_CHMODE_MONO) {
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
72 skip_bits(&gbc, 2); // skip center mix level
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
73 }
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
74 if(hdr->channel_mode & 4) {
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
75 skip_bits(&gbc, 2); // skip surround mix level
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
76 }
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
77 if(hdr->channel_mode == AC3_CHMODE_STEREO) {
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
78 skip_bits(&gbc, 2); // skip dolby surround mode
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
79 }
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
80 hdr->lfe_on = get_bits1(&gbc);
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
81
6118
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
82 hdr->sr_shift = FFMAX(hdr->bitstream_id, 8) - 8;
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
83 hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code] >> hdr->sr_shift;
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
84 hdr->bit_rate = (ff_ac3_bitrate_tab[frame_size_code>>1] * 1000) >> hdr->sr_shift;
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
85 hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on;
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
86 hdr->frame_size = ff_ac3_frame_size_tab[frame_size_code][hdr->sr_code] * 2;
6117
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
87 } else {
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
88 /* Enhanced AC-3 */
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
89 hdr->crc1 = 0;
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
90 skip_bits(&gbc, 2); // skip stream type
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
91 skip_bits(&gbc, 3); // skip substream id
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
92
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
93 hdr->frame_size = (get_bits(&gbc, 11) + 1) << 1;
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
94 if(hdr->frame_size < AC3_HEADER_SIZE)
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
95 return AC3_PARSE_ERROR_FRAME_SIZE;
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
96
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
97 hdr->sr_code = get_bits(&gbc, 2);
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
98 if (hdr->sr_code == 3) {
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
99 int sr_code2 = get_bits(&gbc, 2);
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
100 if(sr_code2 == 3)
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
101 return AC3_PARSE_ERROR_SAMPLE_RATE;
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
102 hdr->sample_rate = ff_ac3_sample_rate_tab[sr_code2] / 2;
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
103 hdr->sr_shift = 1;
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
104 num_blocks = 6;
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
105 } else {
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
106 num_blocks = eac3_blocks[get_bits(&gbc, 2)];
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
107 hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code];
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
108 hdr->sr_shift = 0;
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
109 }
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
110
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
111 hdr->channel_mode = get_bits(&gbc, 3);
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
112 hdr->lfe_on = get_bits1(&gbc);
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
113
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
114 hdr->bit_rate = (uint32_t)(8.0 * hdr->frame_size * hdr->sample_rate /
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
115 (num_blocks * 256.0));
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
116 hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on;
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
117 }
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
118
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
119 return 0;
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
120 }
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
121
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
122 static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate,
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
123 int *bit_rate, int *samples)
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
124 {
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
125 int err;
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
126 AC3HeaderInfo hdr;
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
127
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
128 err = ff_ac3_parse_header(buf, &hdr);
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
129
6117
01b1342e717b move E-AC3 header parsing to ff_ac3_parse_header()
jbr
parents: 6116
diff changeset
130 if(err < 0)
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
131 return 0;
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
132
6118
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
133 *sample_rate = hdr.sample_rate;
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
134 *bit_rate = hdr.bit_rate;
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
135 *channels = hdr.channels;
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
136 *samples = AC3_FRAME_SIZE;
76801e61ddc4 cosmetics: indentation after last commit
jbr
parents: 6117
diff changeset
137 return hdr.frame_size;
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
138 }
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
139
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
140 static int ac3_parse_init(AVCodecParserContext *s1)
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
141 {
4942
b42e963c8149 cosmetics: rename for consistency after previous aac and ac3 parsers move
aurel
parents: 4941
diff changeset
142 AACAC3ParseContext *s = s1->priv_data;
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
143 s->inbuf_ptr = s->inbuf;
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
144 s->header_size = AC3_HEADER_SIZE;
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
145 s->sync = ac3_sync;
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
146 return 0;
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
147 }
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
148
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
149
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
150 AVCodecParser ac3_parser = {
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
151 { CODEC_ID_AC3 },
4942
b42e963c8149 cosmetics: rename for consistency after previous aac and ac3 parsers move
aurel
parents: 4941
diff changeset
152 sizeof(AACAC3ParseContext),
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
153 ac3_parse_init,
4942
b42e963c8149 cosmetics: rename for consistency after previous aac and ac3 parsers move
aurel
parents: 4941
diff changeset
154 ff_aac_ac3_parse,
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
155 NULL,
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
156 };