diff --git a/ChangeLog b/ChangeLog index 62d539129..87b721f95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2015-03-28 Moritz Bunkus + * mkvmerge: enhancement: Implemented support for core-less DTS + streams consisting solely of XLL extension sub-streams. + * mkvmerge: new feature: track selection can be done by language codes as well. Affects the options --audio-tracks, --button-tracks, --subtitle-tracks and --video-tracks. Works only diff --git a/src/common/dts.cpp b/src/common/dts.cpp index 44e4bd647..b0332852c 100644 --- a/src/common/dts.cpp +++ b/src/common/dts.cpp @@ -48,6 +48,13 @@ static const channel_arrangement channel_arrangements[16] = { // other modes are not defined as of yet }; +static unsigned int const s_substream_sample_rates[16] = { + 8000, 16000, 32000, 64000, + 128000, 22050, 44100, 88200, + 176400, 352800, 12000, 24000, + 48000, 96000, 192000, 384000 +}; + static const int core_samplefreqs[16] = { -1, 8000, 16000, 32000, -1, -1, 11025, 22050, 44100, -1, -1, 12000, 24000, 48000, -1, -1 @@ -552,16 +559,50 @@ header_t::decode_lbr_header(bit_reader_c &bc, return true; } +bool +header_t::decode_xll_header(bit_reader_c &bc, + substream_asset_t &asset) { + bc.set_bit_position(asset.xll_offset * 8); + if (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; + + return true; + + // // Decode common header. + // bc.skip_bits(4); // version + // auto header_size = bc.get_bits(8); + // auto frame_size_bits = bc.get_bits(5); + // bc.skip_bits(frame_size_bits); // frame size + + // auto num_channel_sets = bc.get_bits(4); + // if (!num_channel_sets) + // return false; + + // bc.skip_bits(4); // num segments in frame + // auto num_samples_in_segment = 1 << bc.get_bits(4); + + // bc.set_bit_position(asset.xll_offset * 8 + header_size); + + // // Decode first channel set sub-header. + // bc.skip_bits(10); // channel set header size + // auto channel_set_ll_channel = bc.get_bits(4); + // bc.skip_bits(channel_set_ll_channel); // residual channel encode + // bc.skip_bits(5 + 5); // bit resolution, bit width + + // auto sampling_frequency_idx = bc.get_bits(4); + // auto sampling_frequency_modifier = bc.get_bits(2); + // if (!has_core && !(asset.extension_mask & exss_lbr)) + // core_sampling_frequency = substream_assets[0].max_sample_rate; + + // return true; +} + bool header_t::decode_asset(bit_reader_c &bc, substream_asset_t &asset) { - static unsigned int const s_substream_sample_rates[16] = { - 8000, 16000, 32000, 64000, - 128000, 22050, 44100, 88200, - 176400, 352800, 12000, 24000, - 48000, 96000, 192000, 384000 - }; - auto descriptor_pos = bc.get_bit_position(); auto descriptor_size = bc.get_bits(9) + 1; asset.asset_index = bc.get_bits(3); @@ -708,6 +749,9 @@ header_t::decode_asset(bit_reader_c &bc, if ((asset.extension_mask & exss_lbr) && !decode_lbr_header(bc, asset)) return false; + if ((asset.extension_mask & exss_xll) && !decode_xll_header(bc, asset)) + return false; + if (asset.extension_mask & exss_xll) dts_type = dts_type_e::master_audio; diff --git a/src/common/dts.h b/src/common/dts.h index 1c397a4f5..7e80bb3e8 100644 --- a/src/common/dts.h +++ b/src/common/dts.h @@ -26,6 +26,7 @@ enum class sync_word_e { core = 0x7ffe8001 , exss = 0x64582025 , lbr = 0x0a801921 + , xll = 0x41a29547 }; enum class frametype_e { @@ -236,6 +237,7 @@ public: protected: bool decode_asset(bit_reader_c &bc, substream_asset_t &asset); bool decode_lbr_header(bit_reader_c &bc, substream_asset_t &asset); + bool decode_xll_header(bit_reader_c &bc, substream_asset_t &asset); void parse_lbr_parameters(bit_reader_c &bc, substream_asset_t &asset); void parse_xll_parameters(bit_reader_c &bc, substream_asset_t &asset); diff --git a/tests/results.txt b/tests/results.txt index cc7791f76..47dbb2785 100644 --- a/tests/results.txt +++ b/tests/results.txt @@ -329,3 +329,4 @@ T_480dts_express:564af1cf4765e27e054d248ccb214cd6-f4a3abe81bdf0fb40a6ba8c0983e3e T_481dts_hd_high_resolution:18be2234293a4ca12ecfa0c1648e853e-edb2e77c3a778f2fd0b3fe5db71637c1:passed:20150326-184450:1.647462876 T_482hevc_no_aspect_ratio_in_sps:6ee3a0bc21ccabde46a8c7af049b120e-3d1417ef349f58a50c768a13b6daf2d4-3f56f42c30cdffd70c4992a1eaeb2332:passed:20150327-125855:0.880932303 T_483select_tracks_by_language:29372d441ceb28c4619b67bb4341ad31+3c1bb1b57f532c27a6e4ee3f5d9490f2+3c1bb1b57f532c27a6e4ee3f5d9490f2+3c1bb1b57f532c27a6e4ee3f5d9490f2+8addc95582a81fae7df19cf954945fe3:passed:20150328-191349:0.156972906 +T_484dts_without_core_xll_substream:f562501d11cc5c773bae34670b50d7b4:passed:20150328-221149:0.468020256 diff --git a/tests/test-484dts_without_core_xll_substream.rb b/tests/test-484dts_without_core_xll_substream.rb new file mode 100755 index 000000000..9f0581f59 --- /dev/null +++ b/tests/test-484dts_without_core_xll_substream.rb @@ -0,0 +1,5 @@ +#!/usr/bin/ruby -w + +# T_484dts_without_core_xll_substream +describe "mkvmerge / DTS file without cores, only XLL extension substreams" +test_merge "data/dts/xll-no-core.dts"