Mercurial > libavcodec.hg
annotate ac3_parser.c @ 7983:47f50599b368 libavcodec
x264 has removed the b-rdo and bime options, and instead integrated
them into the subme number to attempt to reduce the number of
unnecessary options. subme now scales up to 9.
Patch by Jason Garett-Glaser %darkshikari A gmail P com%
author | gpoirier |
---|---|
date | Thu, 02 Oct 2008 19:05:35 +0000 |
parents | e5f7a43f63ae |
children | c34d5e164b22 |
rev | line source |
---|---|
4941 | 1 /* |
7470
1a93d3bbe3ee
cosmetics: make all references to AC-3 capitalized and hyphenated
jbr
parents:
7138
diff
changeset
|
2 * AC-3 parser |
4941 | 3 * Copyright (c) 2003 Fabrice Bellard. |
4 * Copyright (c) 2003 Michael Niedermayer. | |
5 * | |
6 * This file is part of FFmpeg. | |
7 * | |
8 * FFmpeg is free software; you can redistribute it and/or | |
9 * modify it under the terms of the GNU Lesser General Public | |
10 * License as published by the Free Software Foundation; either | |
11 * version 2.1 of the License, or (at your option) any later version. | |
12 * | |
13 * FFmpeg is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Lesser General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Lesser General Public | |
19 * License along with FFmpeg; if not, write to the Free Software | |
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
21 */ | |
22 | |
23 #include "parser.h" | |
24 #include "ac3_parser.h" | |
25 #include "aac_ac3_parser.h" | |
26 #include "bitstream.h" | |
27 | |
28 | |
29 #define AC3_HEADER_SIZE 7 | |
30 | |
31 | |
32 static const uint8_t eac3_blocks[4] = { | |
33 1, 2, 3, 6 | |
34 }; | |
35 | |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
36 |
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
37 int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) |
4941 | 38 { |
6116 | 39 int frame_size_code; |
4941 | 40 |
41 memset(hdr, 0, sizeof(*hdr)); | |
42 | |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
43 hdr->sync_word = get_bits(gbc, 16); |
4941 | 44 if(hdr->sync_word != 0x0B77) |
5680 | 45 return AC3_PARSE_ERROR_SYNC; |
4941 | 46 |
6117 | 47 /* read ahead to bsid to distinguish between AC-3 and E-AC-3 */ |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
48 hdr->bitstream_id = show_bits_long(gbc, 29) & 0x1F; |
6117 | 49 if(hdr->bitstream_id > 16) |
5680 | 50 return AC3_PARSE_ERROR_BSID; |
4941 | 51 |
7011
77f607fb4e8b
get the number of blocks from the ac3 parser and use in the ac3 decoder.
jbr
parents:
6671
diff
changeset
|
52 hdr->num_blocks = 6; |
77f607fb4e8b
get the number of blocks from the ac3 parser and use in the ac3 decoder.
jbr
parents:
6671
diff
changeset
|
53 |
7016 | 54 /* set default mix levels */ |
7019
81d5c68233e5
move mix level tables from parser to decoder. have parser read bitstream value instead of using an index to a table in the decoder.
jbr
parents:
7018
diff
changeset
|
55 hdr->center_mix_level = 1; // -4.5dB |
81d5c68233e5
move mix level tables from parser to decoder. have parser read bitstream value instead of using an index to a table in the decoder.
jbr
parents:
7018
diff
changeset
|
56 hdr->surround_mix_level = 1; // -6.0dB |
7016 | 57 |
6117 | 58 if(hdr->bitstream_id <= 10) { |
6118 | 59 /* Normal AC-3 */ |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
60 hdr->crc1 = get_bits(gbc, 16); |
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
61 hdr->sr_code = get_bits(gbc, 2); |
6118 | 62 if(hdr->sr_code == 3) |
63 return AC3_PARSE_ERROR_SAMPLE_RATE; | |
4941 | 64 |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
65 frame_size_code = get_bits(gbc, 6); |
6118 | 66 if(frame_size_code > 37) |
67 return AC3_PARSE_ERROR_FRAME_SIZE; | |
4941 | 68 |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
69 skip_bits(gbc, 5); // skip bsid, already got it |
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
70 |
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
71 skip_bits(gbc, 3); // skip bitstream mode |
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
72 hdr->channel_mode = get_bits(gbc, 3); |
4941 | 73 |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
74 if(hdr->channel_mode == AC3_CHMODE_STEREO) { |
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
75 skip_bits(gbc, 2); // skip dsurmod |
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
76 } else { |
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
77 if((hdr->channel_mode & 1) && hdr->channel_mode != AC3_CHMODE_MONO) |
7019
81d5c68233e5
move mix level tables from parser to decoder. have parser read bitstream value instead of using an index to a table in the decoder.
jbr
parents:
7018
diff
changeset
|
78 hdr->center_mix_level = get_bits(gbc, 2); |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
79 if(hdr->channel_mode & 4) |
7019
81d5c68233e5
move mix level tables from parser to decoder. have parser read bitstream value instead of using an index to a table in the decoder.
jbr
parents:
7018
diff
changeset
|
80 hdr->surround_mix_level = get_bits(gbc, 2); |
6118 | 81 } |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
82 hdr->lfe_on = get_bits1(gbc); |
4941 | 83 |
6118 | 84 hdr->sr_shift = FFMAX(hdr->bitstream_id, 8) - 8; |
85 hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code] >> hdr->sr_shift; | |
86 hdr->bit_rate = (ff_ac3_bitrate_tab[frame_size_code>>1] * 1000) >> hdr->sr_shift; | |
87 hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; | |
88 hdr->frame_size = ff_ac3_frame_size_tab[frame_size_code][hdr->sr_code] * 2; | |
6651
abc8176ddf88
Make most of E-AC-3 work without breaking regression tests.
michael
parents:
6645
diff
changeset
|
89 hdr->frame_type = EAC3_FRAME_TYPE_AC3_CONVERT; //EAC3_FRAME_TYPE_INDEPENDENT; |
7012 | 90 hdr->substreamid = 0; |
6117 | 91 } else { |
92 /* Enhanced AC-3 */ | |
93 hdr->crc1 = 0; | |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
94 hdr->frame_type = get_bits(gbc, 2); |
6540
b0d44aec1ec0
change name from stream type to frame type in AC3 code
bwolowiec
parents:
6539
diff
changeset
|
95 if(hdr->frame_type == EAC3_FRAME_TYPE_RESERVED) |
b0d44aec1ec0
change name from stream type to frame type in AC3 code
bwolowiec
parents:
6539
diff
changeset
|
96 return AC3_PARSE_ERROR_FRAME_TYPE; |
6529 | 97 |
7012 | 98 hdr->substreamid = get_bits(gbc, 3); |
6117 | 99 |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
100 hdr->frame_size = (get_bits(gbc, 11) + 1) << 1; |
6117 | 101 if(hdr->frame_size < AC3_HEADER_SIZE) |
102 return AC3_PARSE_ERROR_FRAME_SIZE; | |
103 | |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
104 hdr->sr_code = get_bits(gbc, 2); |
6117 | 105 if (hdr->sr_code == 3) { |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
106 int sr_code2 = get_bits(gbc, 2); |
6117 | 107 if(sr_code2 == 3) |
108 return AC3_PARSE_ERROR_SAMPLE_RATE; | |
109 hdr->sample_rate = ff_ac3_sample_rate_tab[sr_code2] / 2; | |
110 hdr->sr_shift = 1; | |
111 } else { | |
7011
77f607fb4e8b
get the number of blocks from the ac3 parser and use in the ac3 decoder.
jbr
parents:
6671
diff
changeset
|
112 hdr->num_blocks = eac3_blocks[get_bits(gbc, 2)]; |
6117 | 113 hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code]; |
114 hdr->sr_shift = 0; | |
115 } | |
116 | |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
117 hdr->channel_mode = get_bits(gbc, 3); |
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
118 hdr->lfe_on = get_bits1(gbc); |
6117 | 119 |
120 hdr->bit_rate = (uint32_t)(8.0 * hdr->frame_size * hdr->sample_rate / | |
7011
77f607fb4e8b
get the number of blocks from the ac3 parser and use in the ac3 decoder.
jbr
parents:
6671
diff
changeset
|
121 (hdr->num_blocks * 256.0)); |
6117 | 122 hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; |
123 } | |
4941 | 124 |
125 return 0; | |
126 } | |
127 | |
6671
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
128 int ff_ac3_parse_header_full(GetBitContext *gbc, AC3HeaderInfo *hdr){ |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
129 int ret, i; |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
130 ret = ff_ac3_parse_header(gbc, hdr); |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
131 if(!ret){ |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
132 if(hdr->bitstream_id>10){ |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
133 /* Enhanced AC-3 */ |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
134 skip_bits(gbc, 5); // skip bitstream id |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
135 |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
136 /* skip dialog normalization and compression gain */ |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
137 for (i = 0; i < (hdr->channel_mode ? 1 : 2); i++) { |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
138 skip_bits(gbc, 5); // skip dialog normalization |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
139 if (get_bits1(gbc)) { |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
140 skip_bits(gbc, 8); //skip Compression gain word |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
141 } |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
142 } |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
143 /* dependent stream channel map */ |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
144 if (hdr->frame_type == EAC3_FRAME_TYPE_DEPENDENT && get_bits1(gbc)) { |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
145 hdr->channel_map = get_bits(gbc, 16); //custom channel map |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
146 return 0; |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
147 } |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
148 } |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
149 //default channel map based on acmod and lfeon |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
150 hdr->channel_map = ff_eac3_default_chmap[hdr->channel_mode]; |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
151 if(hdr->lfe_on) |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
152 hdr->channel_map |= AC3_CHMAP_LFE; |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
153 } |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
154 return ret; |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
155 } |
2d0b86dfe5bb
add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
bwolowiec
parents:
6661
diff
changeset
|
156 |
6643 | 157 static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, |
158 int *need_next_header, int *new_frame_start) | |
4941 | 159 { |
160 int err; | |
6642
866b9ade048c
Change aac and ac3 parsers to use ff_combine_frame().
michael
parents:
6639
diff
changeset
|
161 uint64_t tmp = be2me_64(state); |
4941 | 162 AC3HeaderInfo hdr; |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
163 GetBitContext gbc; |
4941 | 164 |
6661
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
165 init_get_bits(&gbc, ((uint8_t *)&tmp)+8-AC3_HEADER_SIZE, 54); |
a409fbf1f42b
change ff_ac3_parse_header() to take a GetBitContext instead of const char*
bwolowiec
parents:
6651
diff
changeset
|
166 err = ff_ac3_parse_header(&gbc, &hdr); |
4941 | 167 |
6117 | 168 if(err < 0) |
4941 | 169 return 0; |
170 | |
6527
32b984487899
Pass AACAC3ParseContext to sync() instead of individual arguments. Patch by
jbr
parents:
6517
diff
changeset
|
171 hdr_info->sample_rate = hdr.sample_rate; |
32b984487899
Pass AACAC3ParseContext to sync() instead of individual arguments. Patch by
jbr
parents:
6517
diff
changeset
|
172 hdr_info->bit_rate = hdr.bit_rate; |
32b984487899
Pass AACAC3ParseContext to sync() instead of individual arguments. Patch by
jbr
parents:
6517
diff
changeset
|
173 hdr_info->channels = hdr.channels; |
32b984487899
Pass AACAC3ParseContext to sync() instead of individual arguments. Patch by
jbr
parents:
6517
diff
changeset
|
174 hdr_info->samples = AC3_FRAME_SIZE; |
6539
04763b6fd4f0
removal of stream_type in AACAC3ParseContext and adding AACAC3FrameFlag
bwolowiec
parents:
6530
diff
changeset
|
175 |
6651
abc8176ddf88
Make most of E-AC-3 work without breaking regression tests.
michael
parents:
6645
diff
changeset
|
176 *need_next_header = (hdr.frame_type != EAC3_FRAME_TYPE_AC3_CONVERT); |
abc8176ddf88
Make most of E-AC-3 work without breaking regression tests.
michael
parents:
6645
diff
changeset
|
177 *new_frame_start = (hdr.frame_type != EAC3_FRAME_TYPE_DEPENDENT); |
6118 | 178 return hdr.frame_size; |
4941 | 179 } |
180 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6118
diff
changeset
|
181 static av_cold int ac3_parse_init(AVCodecParserContext *s1) |
4941 | 182 { |
4942
b42e963c8149
cosmetics: rename for consistency after previous aac and ac3 parsers move
aurel
parents:
4941
diff
changeset
|
183 AACAC3ParseContext *s = s1->priv_data; |
4941 | 184 s->header_size = AC3_HEADER_SIZE; |
185 s->sync = ac3_sync; | |
186 return 0; | |
187 } | |
188 | |
189 | |
190 AVCodecParser ac3_parser = { | |
7769 | 191 { CODEC_ID_AC3, CODEC_ID_EAC3 }, |
4942
b42e963c8149
cosmetics: rename for consistency after previous aac and ac3 parsers move
aurel
parents:
4941
diff
changeset
|
192 sizeof(AACAC3ParseContext), |
4941 | 193 ac3_parse_init, |
4942
b42e963c8149
cosmetics: rename for consistency after previous aac and ac3 parsers move
aurel
parents:
4941
diff
changeset
|
194 ff_aac_ac3_parse, |
7138 | 195 ff_parse_close, |
4941 | 196 }; |