From bae32648e6a8063d4efcb2026a28311d83f27196 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Wed, 10 Aug 2016 20:33:35 +0200 Subject: [PATCH] DTS: use XLL extension's sample rate for track headers if present Fixes #1762. --- ChangeLog | 6 ++++++ src/common/dts.cpp | 16 ++++++++++++++-- src/common/dts.h | 2 ++ src/input/r_dts.cpp | 2 +- src/input/r_mpeg_ps.cpp | 2 +- src/input/r_mpeg_ts.cpp | 2 +- src/input/r_qtmp4.cpp | 2 +- src/output/p_dts.cpp | 4 ++-- tests/results.txt | 1 + tests/test-557dts_hd_ma_xll_extension.rb | 17 +++++++++++++++++ 10 files changed, 46 insertions(+), 8 deletions(-) create mode 100755 tests/test-557dts_hd_ma_xll_extension.rb diff --git a/ChangeLog b/ChangeLog index 8de34091f..7f57d2af5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-08-10 Moritz Bunkus + + * mkvmerge: DTS bug fix: if present mkvmerge will use an XLL + extension's sample rate information as the sample rate to put into + the track headers. Fixes #1762. + 2016-08-06 Moritz Bunkus * mkvmerge: new feature: added support for reading Apple ProRes diff --git a/src/common/dts.cpp b/src/common/dts.cpp index f7a6dd73a..4d33d470c 100644 --- a/src/common/dts.cpp +++ b/src/common/dts.cpp @@ -367,6 +367,14 @@ header_t::get_total_num_audio_channels() return get_core_num_audio_channels(); } +unsigned int +header_t::get_effective_sampling_frequency() + const { + if (extension_sampling_frequency && *extension_sampling_frequency) + return *extension_sampling_frequency; + return core_sampling_frequency; +} + codec_c::specialization_e header_t::get_codec_specialization() const { @@ -591,8 +599,12 @@ header_t::decode_xll_header(bit_reader_c &bc, if (asset.xll_sync_present && (bc.get_bits(32) != static_cast(sync_word_e::xll))) return false; - if (!has_core && !(asset.extension_mask & exss_lbr)) - core_sampling_frequency = substream_assets[0].max_sample_rate; + if (!(asset.extension_mask & exss_lbr)) { + if (!has_core) + core_sampling_frequency = substream_assets[0].max_sample_rate; + else + extension_sampling_frequency.reset(substream_assets[0].max_sample_rate); + } return true; diff --git a/src/common/dts.h b/src/common/dts.h index e6f55e866..4de56ba20 100644 --- a/src/common/dts.h +++ b/src/common/dts.h @@ -129,6 +129,7 @@ struct header_t { // -1 for "invalid" unsigned int core_sampling_frequency{}; + boost::optional extension_sampling_frequency; // in bit per second, or -1 == "open", -2 == "variable", -3 == "lossless" int transmission_bitrate{}; @@ -232,6 +233,7 @@ public: unsigned int get_core_num_audio_channels() const; unsigned int get_total_num_audio_channels() const; codec_c::specialization_e get_codec_specialization() const; + unsigned int get_effective_sampling_frequency() const; void print() const; diff --git a/src/input/r_dts.cpp b/src/input/r_dts.cpp index e1949b9b3..318ba6ff4 100644 --- a/src/input/r_dts.cpp +++ b/src/input/r_dts.cpp @@ -184,7 +184,7 @@ void dts_reader_c::identify() { auto info = mtx::id::info_c{}; info.add(mtx::id::audio_channels, m_dtsheader.get_total_num_audio_channels()); - info.add(mtx::id::audio_sampling_frequency, m_dtsheader.core_sampling_frequency); + info.add(mtx::id::audio_sampling_frequency, m_dtsheader.get_effective_sampling_frequency()); info.add(mtx::id::audio_bits_per_sample, std::max(m_dtsheader.source_pcm_resolution, 0)); id_result_container(); diff --git a/src/input/r_mpeg_ps.cpp b/src/input/r_mpeg_ps.cpp index 8209bb719..acd0c3763 100644 --- a/src/input/r_mpeg_ps.cpp +++ b/src/input/r_mpeg_ps.cpp @@ -811,7 +811,7 @@ mpeg_ps_reader_c::new_stream_a_dts(mpeg_ps_id_t id, } track->a_channels = track->dts_header.get_total_num_audio_channels(); - track->a_sample_rate = track->dts_header.core_sampling_frequency; + track->a_sample_rate = track->dts_header.get_effective_sampling_frequency(); track->codec.set_specialization(track->dts_header.get_codec_specialization()); } diff --git a/src/input/r_mpeg_ts.cpp b/src/input/r_mpeg_ts.cpp index 5b24a3f24..dbc49bf80 100644 --- a/src/input/r_mpeg_ts.cpp +++ b/src/input/r_mpeg_ts.cpp @@ -343,7 +343,7 @@ mpeg_ts_track_c::new_stream_a_dts() { m_apply_dts_timestamp_fix = true; a_channels = a_dts_header.get_total_num_audio_channels(); - a_sample_rate = a_dts_header.core_sampling_frequency; + a_sample_rate = a_dts_header.get_effective_sampling_frequency(); codec.set_specialization(a_dts_header.get_codec_specialization()); diff --git a/src/input/r_qtmp4.cpp b/src/input/r_qtmp4.cpp index 953e79940..8f622988b 100644 --- a/src/input/r_qtmp4.cpp +++ b/src/input/r_qtmp4.cpp @@ -2878,7 +2878,7 @@ qtmp4_demuxer_c::derive_track_params_from_dts_audio_bitstream() { return; a_channels = header.get_total_num_audio_channels(); - a_samplerate = header.core_sampling_frequency; + a_samplerate = header.get_effective_sampling_frequency(); a_bitdepth = std::max(header.source_pcm_resolution, 0); } diff --git a/src/output/p_dts.cpp b/src/output/p_dts.cpp index ba99c07d2..ea687d33b 100644 --- a/src/output/p_dts.cpp +++ b/src/output/p_dts.cpp @@ -107,7 +107,7 @@ dts_packetizer_c::get_dts_packet(mtx::dts::header_t &dtsheader, void dts_packetizer_c::set_headers() { set_codec_id(MKV_A_DTS); - set_audio_sampling_freq(m_first_header.core_sampling_frequency); + set_audio_sampling_freq(m_first_header.get_effective_sampling_frequency()); set_audio_channels(m_reduce_to_core ? m_first_header.get_core_num_audio_channels() : m_first_header.get_total_num_audio_channels()); set_track_default_duration(m_first_header.get_packet_length_in_nanoseconds().to_ns()); if (m_first_header.source_pcm_resolution > 0) @@ -140,7 +140,7 @@ dts_packetizer_c::queue_available_packets(bool flushing) { m_first_header.core_sampling_frequency = dtsheader.core_sampling_frequency; m_timestamp_calculator = timestamp_calculator_c{static_cast(m_first_header.core_sampling_frequency)}; - set_audio_sampling_freq(m_first_header.core_sampling_frequency); + set_audio_sampling_freq(m_first_header.get_effective_sampling_frequency()); rerender_track_headers(); } diff --git a/tests/results.txt b/tests/results.txt index ee62ebee4..43045d40e 100644 --- a/tests/results.txt +++ b/tests/results.txt @@ -402,3 +402,4 @@ T_553ogg_kate:ad870277b84e9eb854e892efe7d492cc-31c5c4be58498e0253793ddc95800822- T_554ogg_vp8:843834e486d4ee8ca971099a5cfc7ee3-769563129b815fcb24af9e4a630bf34b:passed:20160729-190454:0.02847642 T_555appending_with_square_brackets:cd1bfe07d702f4729d40d7f4476dfc41-cd1bfe07d702f4729d40d7f4476dfc41-cd1bfe07d702f4729d40d7f4476dfc41-cd1bfe07d702f4729d40d7f4476dfc41-cd1bfe07d702f4729d40d7f4476dfc41-cd1bfe07d702f4729d40d7f4476dfc41:passed:20160730-115423:0.309106233 T_556prores:cefc5f55889463321b03075bcf9f5e7b-5fbfaf0b69674d62d4edb2e3d1f05eb4-42d78339046f12ae6885ffa3a7b4ac4c-f13f5e34d64f730ff73ba61a6f4cb00e-36827931dbfa0097418745e669892fd1-36827931dbfa0097418745e669892fd1:passed:20160806-201730:0.656227356 +T_557dts_hd_ma_xll_extension:96000-192000-7f61832d35165f4600c0ac06b3a109dc-7f61832d35165f4600c0ac06b3a109dc:passed:20160810-203155:1.196256604 diff --git a/tests/test-557dts_hd_ma_xll_extension.rb b/tests/test-557dts_hd_ma_xll_extension.rb new file mode 100755 index 000000000..c2a846814 --- /dev/null +++ b/tests/test-557dts_hd_ma_xll_extension.rb @@ -0,0 +1,17 @@ +#!/usr/bin/ruby -w + +# T_557dts_hd_ma_xll_extension +describe "mkvmerge / DTS-HD Master Audio with XLL extensions and sample rate > 48 kHz" + +files = %w{96 192}.map { |r| "data/dts/dts-hd-ma-#{r}khz.dts" } + +files.each do |file| + test "detected sample rate of #{file}" do + identify_json(file)["tracks"]. + map { |t| t["properties"]["audio_sampling_frequency"].to_s }. + join("+") + end +end + +test_merge files.join(' '), :output => "#{tmp}-1", :keep_tmp => true +test_merge "#{tmp}-1"