mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-25 04:11:44 +00:00
AAC ADTS parser: parse program_config_element in frame for channel detection
The `program_config_element` (PCE) in the frame is authoritative regarding the number of channels encoded in the frame. The container information might be wrong (e.g. the ADTS headers containing a channel configuration of 0, which is invalid). Therefore parse the PCE if it's located at the start of the frame and override the ADTS header content. Fixes #2107.
This commit is contained in:
parent
515b3b2fae
commit
958af14d27
10
NEWS.md
10
NEWS.md
@ -1,3 +1,13 @@
|
||||
# Version ?
|
||||
|
||||
## Bug fixes
|
||||
|
||||
* mkvmerge: AAC ADTS parser: mkvmerge will now parse the
|
||||
`program_config_element` if it is located at the start of an AAC frame in
|
||||
order to determine the actual number of channels. This overrides invalid
|
||||
channel configurations in the ADTS headers, for example. Fixes #2107.
|
||||
|
||||
|
||||
# Version 16.0.0 "Protest" 2017-09-30
|
||||
|
||||
## New features and enhancements
|
||||
|
@ -111,7 +111,7 @@ create_audio_specific_config(audio_config_t const &audio_config) {
|
||||
|
||||
write_object_type(audio_config.profile + 1);
|
||||
write_sampling_frequency(audio_config.sample_rate);
|
||||
w.put_bits(4, audio_config.channels);
|
||||
w.put_bits(4, audio_config.channels == 8 ? 7 : audio_config.channels);
|
||||
|
||||
if (audio_config.ga_specific_config && audio_config.ga_specific_config_bit_size) {
|
||||
bit_reader_c r{audio_config.ga_specific_config->get_buffer(), audio_config.ga_specific_config->get_size()};
|
||||
@ -564,6 +564,11 @@ parser_c::decode_adts_header(unsigned char const *buffer,
|
||||
if (frame.m_header.bytes <= frame.m_header.header_byte_size)
|
||||
return { failure, 1 };
|
||||
|
||||
auto data_start_position = bc.get_bit_position();
|
||||
if (bc.get_bits(3) == 0x05)
|
||||
frame.m_header.parse_program_config_element(bc);
|
||||
bc.set_bit_position(data_start_position);
|
||||
|
||||
if (m_copy_data) {
|
||||
frame.m_data = memory_c::alloc(frame.m_header.data_byte_size);
|
||||
bc.get_bytes(frame.m_data->get_buffer(), frame.m_header.data_byte_size);
|
||||
@ -1100,6 +1105,20 @@ header_c::parse_audio_specific_config(const unsigned char *data,
|
||||
parse_audio_specific_config(bc, look_for_sync_extension);
|
||||
}
|
||||
|
||||
void
|
||||
header_c::parse_program_config_element(bit_reader_c &bc) {
|
||||
m_bc = &bc;
|
||||
|
||||
try {
|
||||
read_program_config_element();
|
||||
|
||||
} catch (mtx::exception &ex) {
|
||||
mxdebug_if(s_debug_parse_data, boost::format("aac::parse_audio_specific_config: exception: %1%\n") % ex);
|
||||
}
|
||||
|
||||
m_bc = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
operator ==(const header_c &h1,
|
||||
const header_c &h2) {
|
||||
|
@ -91,6 +91,7 @@ public:
|
||||
|
||||
void parse_audio_specific_config(const unsigned char *data, size_t size, bool look_for_sync_extension = true);
|
||||
void parse_audio_specific_config(bit_reader_c &bc, bool look_for_sync_extension = true);
|
||||
void parse_program_config_element(bit_reader_c &bc);
|
||||
|
||||
protected:
|
||||
int read_object_type();
|
||||
|
@ -462,3 +462,4 @@ T_613vorbis_in_mp4:bcf052d24ed82ff0de57425259d075db:passed:20170910-175618:0.014
|
||||
T_614white_colour_coordinates_from_mkv:916ae39f45a435c0b526d875c378e199-916ae39f45a435c0b526d875c378e199:passed:20170916-112249:0.094985684
|
||||
T_615opus_discard_padding_in_the_middle:1b2e18413bab72c0d669a406fc403b38:passed:20170924-230527:0.025602623
|
||||
T_616more_than_128_tracks:221a656c73308a4d530fb2cbf3fd339c-221a656c73308a4d530fb2cbf3fd339c:passed:20170925-201313:0.570145315
|
||||
T_617aac_adts_parse_program_config_element_for_channels:87463bd00d95fb4d8311e81e871f61e5:passed:20171001-201657:0.037546681
|
||||
|
5
tests/test-617aac_adts_parse_program_config_element_for_channels.rb
Executable file
5
tests/test-617aac_adts_parse_program_config_element_for_channels.rb
Executable file
@ -0,0 +1,5 @@
|
||||
#!/usr/bin/ruby -w
|
||||
|
||||
# T_617aac_adts_parse_program_config_element_for_channels
|
||||
describe "mkvmerge / AAC in ADTS with channel_config == 0, but with program_config_element at start signalling 7.1 channels"
|
||||
test_merge "data/aac/adts_0_channels_but_program_config_element_at_start.aac"
|
Loading…
Reference in New Issue
Block a user