DTS: use XLL extension's sample rate for track headers if present

Fixes #1762.
This commit is contained in:
Moritz Bunkus 2016-08-10 20:33:35 +02:00
parent ef6d4a8315
commit bae32648e6
10 changed files with 46 additions and 8 deletions

View File

@ -1,3 +1,9 @@
2016-08-10 Moritz Bunkus <moritz@bunkus.org>
* 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 <moritz@bunkus.org>
* mkvmerge: new feature: added support for reading Apple ProRes

View File

@ -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<uint32_t>(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;

View File

@ -129,6 +129,7 @@ struct header_t {
// -1 for "invalid"
unsigned int core_sampling_frequency{};
boost::optional<unsigned int> 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;

View File

@ -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();

View File

@ -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());
}

View File

@ -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());

View File

@ -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);
}

View File

@ -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<int64_t>(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();
}

View File

@ -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

View File

@ -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"