Mercurial > libavcodec.hg
comparison aacdec.c @ 12483:0159a19bfff7 libavcodec
aacdec: Rework channel mapping compatibility hacks.
For a PCE based configuration map the channels solely based on tags.
For an indexed configuration map the channels solely based on position.
This works with all known exotic samples including al17, elem_id0, bad_concat,
and lfe_is_sce.
author | alexc |
---|---|
date | Fri, 10 Sep 2010 18:01:48 +0000 |
parents | 65619c2230e7 |
children |
comparison
equal
deleted
inserted
replaced
12482:8cafb4db28cb | 12483:0159a19bfff7 |
---|---|
111 | 111 |
112 static const char overread_err[] = "Input buffer exhausted before END element found\n"; | 112 static const char overread_err[] = "Input buffer exhausted before END element found\n"; |
113 | 113 |
114 static ChannelElement *get_che(AACContext *ac, int type, int elem_id) | 114 static ChannelElement *get_che(AACContext *ac, int type, int elem_id) |
115 { | 115 { |
116 /* Some buggy encoders appear to set all elem_ids to zero and rely on | 116 // For PCE based channel configurations map the channels solely based on tags. |
117 channels always occurring in the same order. This is expressly forbidden | 117 if (!ac->m4ac.chan_config) { |
118 by the spec but we will try to work around it. | |
119 */ | |
120 int err_printed = 0; | |
121 while (ac->tags_seen_this_frame[type][elem_id] && elem_id < MAX_ELEM_ID) { | |
122 if (ac->output_configured < OC_LOCKED && !err_printed) { | |
123 av_log(ac->avctx, AV_LOG_WARNING, "Duplicate channel tag found, attempting to remap.\n"); | |
124 err_printed = 1; | |
125 } | |
126 elem_id++; | |
127 } | |
128 if (elem_id == MAX_ELEM_ID) | |
129 return NULL; | |
130 ac->tags_seen_this_frame[type][elem_id] = 1; | |
131 | |
132 if (ac->tag_che_map[type][elem_id]) { | |
133 return ac->tag_che_map[type][elem_id]; | 118 return ac->tag_che_map[type][elem_id]; |
134 } | 119 } |
135 if (ac->tags_mapped >= tags_per_config[ac->m4ac.chan_config]) { | 120 // For indexed channel configurations map the channels solely based on position. |
136 return NULL; | |
137 } | |
138 switch (ac->m4ac.chan_config) { | 121 switch (ac->m4ac.chan_config) { |
139 case 7: | 122 case 7: |
140 if (ac->tags_mapped == 3 && type == TYPE_CPE) { | 123 if (ac->tags_mapped == 3 && type == TYPE_CPE) { |
141 ac->tags_mapped++; | 124 ac->tags_mapped++; |
142 return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][2]; | 125 return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][2]; |
240 &channels))) | 223 &channels))) |
241 return ret; | 224 return ret; |
242 } | 225 } |
243 | 226 |
244 memset(ac->tag_che_map, 0, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0])); | 227 memset(ac->tag_che_map, 0, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0])); |
245 ac->tags_mapped = 0; | |
246 | 228 |
247 avctx->channel_layout = aac_channel_layout[channel_config - 1]; | 229 avctx->channel_layout = aac_channel_layout[channel_config - 1]; |
248 } else { | 230 } else { |
249 /* Allocate or free elements depending on if they are in the | 231 /* Allocate or free elements depending on if they are in the |
250 * current program configuration. | 232 * current program configuration. |
261 return ret; | 243 return ret; |
262 } | 244 } |
263 } | 245 } |
264 | 246 |
265 memcpy(ac->tag_che_map, ac->che, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0])); | 247 memcpy(ac->tag_che_map, ac->che, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0])); |
266 ac->tags_mapped = 4 * MAX_ELEM_ID; | |
267 | 248 |
268 avctx->channel_layout = 0; | 249 avctx->channel_layout = 0; |
269 } | 250 } |
270 | 251 |
271 avctx->channels = channels; | 252 avctx->channels = channels; |
1962 av_log(ac->avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->m4ac.sampling_index); | 1943 av_log(ac->avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->m4ac.sampling_index); |
1963 return -1; | 1944 return -1; |
1964 } | 1945 } |
1965 } | 1946 } |
1966 | 1947 |
1967 memset(ac->tags_seen_this_frame, 0, sizeof(ac->tags_seen_this_frame)); | 1948 ac->tags_mapped = 0; |
1968 // parse | 1949 // parse |
1969 while ((elem_type = get_bits(&gb, 3)) != TYPE_END) { | 1950 while ((elem_type = get_bits(&gb, 3)) != TYPE_END) { |
1970 elem_id = get_bits(&gb, 4); | 1951 elem_id = get_bits(&gb, 4); |
1971 | 1952 |
1972 if (elem_type < TYPE_DSE) { | 1953 if (elem_type < TYPE_DSE) { |