From 3f2e213811a97df3644c341769f36d3b08c78092 Mon Sep 17 00:00:00 2001 From: Tom Yan Date: Sat, 6 Feb 2021 04:03:12 +0800 Subject: [PATCH 1/4] bluray: rename packet converter files --- ...erter.cpp => bluray_pcm_channel_layout_packet_converter.cpp} | 2 +- ...converter.h => bluray_pcm_channel_layout_packet_converter.h} | 0 src/input/r_mpeg_ts.cpp | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/input/{bluray_pcm_channel_removal_packet_converter.cpp => bluray_pcm_channel_layout_packet_converter.cpp} (96%) rename src/input/{bluray_pcm_channel_removal_packet_converter.h => bluray_pcm_channel_layout_packet_converter.h} (100%) diff --git a/src/input/bluray_pcm_channel_removal_packet_converter.cpp b/src/input/bluray_pcm_channel_layout_packet_converter.cpp similarity index 96% rename from src/input/bluray_pcm_channel_removal_packet_converter.cpp rename to src/input/bluray_pcm_channel_layout_packet_converter.cpp index 4d0472d24..cd0d0f431 100644 --- a/src/input/bluray_pcm_channel_removal_packet_converter.cpp +++ b/src/input/bluray_pcm_channel_layout_packet_converter.cpp @@ -13,7 +13,7 @@ #include "common/common_pch.h" -#include "input/bluray_pcm_channel_removal_packet_converter.h" +#include "input/bluray_pcm_channel_layout_packet_converter.h" #include "merge/generic_packetizer.h" bluray_pcm_channel_removal_packet_converter_c::bluray_pcm_channel_removal_packet_converter_c(std::size_t bytes_per_channel, diff --git a/src/input/bluray_pcm_channel_removal_packet_converter.h b/src/input/bluray_pcm_channel_layout_packet_converter.h similarity index 100% rename from src/input/bluray_pcm_channel_removal_packet_converter.h rename to src/input/bluray_pcm_channel_layout_packet_converter.h diff --git a/src/input/r_mpeg_ts.cpp b/src/input/r_mpeg_ts.cpp index 98ef670f6..536931cc2 100644 --- a/src/input/r_mpeg_ts.cpp +++ b/src/input/r_mpeg_ts.cpp @@ -40,7 +40,7 @@ #include "common/regex.h" #include "common/strings/formatting.h" #include "input/aac_framing_packet_converter.h" -#include "input/bluray_pcm_channel_removal_packet_converter.h" +#include "input/bluray_pcm_channel_layout_packet_converter.h" #include "input/dvbsub_pes_framing_removal_packet_converter.h" #include "input/r_mpeg_ts.h" #include "input/teletext_to_srt_packet_converter.h" From 8776c1697453f0d1d4673f16245d9e862afecdd8 Mon Sep 17 00:00:00 2001 From: Tom Yan Date: Sat, 6 Feb 2021 17:41:49 +0800 Subject: [PATCH 2/4] mpeg_ts: reorder channels for 6/7/8-ch PCM streams Blu-ray / M2TS adopts its own channel orders for PCM streams that have more than five channels (i.e. 5.1 / 7.0 / 7.1), while PCM in Matroska should be in channel orders that are defined for WAVEFORMATEXTENSIBLE. --- ...ay_pcm_channel_layout_packet_converter.cpp | 65 +++++++++++++++++-- ...uray_pcm_channel_layout_packet_converter.h | 13 ++-- src/input/r_mpeg_ts.cpp | 3 +- 3 files changed, 69 insertions(+), 12 deletions(-) diff --git a/src/input/bluray_pcm_channel_layout_packet_converter.cpp b/src/input/bluray_pcm_channel_layout_packet_converter.cpp index cd0d0f431..433b16597 100644 --- a/src/input/bluray_pcm_channel_layout_packet_converter.cpp +++ b/src/input/bluray_pcm_channel_layout_packet_converter.cpp @@ -6,7 +6,7 @@ see the file COPYING for details or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html - Removal of superfluous extra channel on Blu-ray PCM with odd number of channels + Fix channel layout for Blu-ray PCM Written by Moritz Bunkus . */ @@ -16,18 +16,28 @@ #include "input/bluray_pcm_channel_layout_packet_converter.h" #include "merge/generic_packetizer.h" -bluray_pcm_channel_removal_packet_converter_c::bluray_pcm_channel_removal_packet_converter_c(std::size_t bytes_per_channel, +bluray_pcm_channel_layout_packet_converter_c::bluray_pcm_channel_layout_packet_converter_c(std::size_t bytes_per_channel, std::size_t num_input_channels, std::size_t num_output_channels) : packet_converter_c{nullptr} , m_bytes_per_channel{bytes_per_channel} , m_num_input_channels{num_input_channels} , m_num_output_channels{num_output_channels} + , m_remap_buf_size{0} { + if (m_num_output_channels == 6) + m_remap_buf_size = m_bytes_per_channel * 3; + else if (m_num_output_channels == 7) + m_remap_buf_size = m_bytes_per_channel * 3; + else if (m_num_output_channels == 8) + m_remap_buf_size = m_bytes_per_channel * 5; + + if (m_remap_buf_size > 0) + m_remap_buf = memory_c::alloc(m_remap_buf_size); } -bool -bluray_pcm_channel_removal_packet_converter_c::convert(packet_cptr const &packet) { +void +bluray_pcm_channel_layout_packet_converter_c::removal(packet_cptr const &packet) { auto start_ptr = packet->data->get_buffer(); auto end_ptr = start_ptr + packet->data->get_size(); auto input_ptr = start_ptr; @@ -44,8 +54,53 @@ bluray_pcm_channel_removal_packet_converter_c::convert(packet_cptr const &packet } packet->data->set_size(output_ptr - start_ptr); +} + +void +bluray_pcm_channel_layout_packet_converter_c::remap(packet_cptr const &packet) { + auto start_ptr = packet->data->get_buffer(); + auto end_ptr = start_ptr + packet->data->get_size(); + + if (m_num_output_channels == 6) { // post-remap order: FL FR FC LFE BL BR + while (start_ptr != end_ptr) { + start_ptr += m_bytes_per_channel * 3; + memcpy(m_remap_buf->get_buffer(), start_ptr, m_remap_buf_size); + memcpy(start_ptr, m_remap_buf->get_buffer() + m_bytes_per_channel * 2, m_bytes_per_channel); + memcpy(start_ptr + m_bytes_per_channel, m_remap_buf->get_buffer(), m_bytes_per_channel * 2); + start_ptr += m_remap_buf_size; + } + } else if (m_num_output_channels == 7) { // post-remap order: FL FR FC BL BR SL SR + while (start_ptr != end_ptr) { + start_ptr += m_bytes_per_channel * 3; + memcpy(m_remap_buf->get_buffer(), start_ptr, m_remap_buf_size); + memcpy(start_ptr, m_remap_buf->get_buffer() + m_bytes_per_channel, m_bytes_per_channel * 2); + memcpy(start_ptr + m_bytes_per_channel * 2, m_remap_buf->get_buffer(), m_bytes_per_channel); + start_ptr += m_remap_buf_size + m_bytes_per_channel; + } + } else if (m_num_output_channels == 8) { // post-remap order: FL FR FC LFE BL BR SL SR + while (start_ptr != end_ptr) { + start_ptr += m_bytes_per_channel * 3; + memcpy(m_remap_buf->get_buffer(), start_ptr, m_remap_buf_size); + memcpy(start_ptr, m_remap_buf->get_buffer() + m_bytes_per_channel * 4, m_bytes_per_channel); + // BL and BR stay at the same place + memcpy(start_ptr + m_bytes_per_channel * 3, m_remap_buf->get_buffer(), m_bytes_per_channel); + memcpy(start_ptr + m_bytes_per_channel * 4, + m_remap_buf->get_buffer() + m_bytes_per_channel * 3, m_bytes_per_channel); + start_ptr += m_remap_buf_size; + } + } +} + +bool +bluray_pcm_channel_layout_packet_converter_c::convert(packet_cptr const &packet) { + // remove superfluous extra channel + if ((m_num_output_channels % 2) != 0) + removal(packet); + + // remap channels into WAVEFORMATEXTENSIBLE channel order + if (m_remap_buf) + remap(packet); m_ptzr->process(packet); - return true; } diff --git a/src/input/bluray_pcm_channel_layout_packet_converter.h b/src/input/bluray_pcm_channel_layout_packet_converter.h index 6a84957ac..36aabee94 100644 --- a/src/input/bluray_pcm_channel_layout_packet_converter.h +++ b/src/input/bluray_pcm_channel_layout_packet_converter.h @@ -6,7 +6,7 @@ see the file COPYING for details or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html - class definitions for the Blu-ray PCM channel removal converter + class definitions for the Blu-ray PCM channel layout converter Written by Moritz Bunkus . */ @@ -18,13 +18,16 @@ #include "common/truehd.h" #include "input/packet_converter.h" -class bluray_pcm_channel_removal_packet_converter_c: public packet_converter_c { +class bluray_pcm_channel_layout_packet_converter_c: public packet_converter_c { protected: - std::size_t m_bytes_per_channel, m_num_input_channels, m_num_output_channels; + std::size_t m_bytes_per_channel, m_num_input_channels, m_num_output_channels, m_remap_buf_size; + memory_cptr m_remap_buf; public: - bluray_pcm_channel_removal_packet_converter_c(std::size_t bytes_per_channel, std::size_t num_input_channels, std::size_t num_output_channels); - virtual ~bluray_pcm_channel_removal_packet_converter_c() {}; + bluray_pcm_channel_layout_packet_converter_c(std::size_t bytes_per_channel, std::size_t num_input_channels, std::size_t num_output_channels); + virtual ~bluray_pcm_channel_layout_packet_converter_c() {}; + virtual void removal(packet_cptr const &packet); + virtual void remap(packet_cptr const &packet); virtual bool convert(packet_cptr const &packet); }; diff --git a/src/input/r_mpeg_ts.cpp b/src/input/r_mpeg_ts.cpp index 536931cc2..c9fcdb198 100644 --- a/src/input/r_mpeg_ts.cpp +++ b/src/input/r_mpeg_ts.cpp @@ -433,8 +433,7 @@ track_c::new_stream_a_pcm() { if ((a_sample_rate == 0) || !mtx::included_in(a_bits_per_sample, 16, 24)) return FILE_STATUS_DONE; - if ((a_channels % 2) != 0) - converter = std::make_shared(a_bits_per_sample / 8, a_channels + 1, a_channels); + converter = std::make_shared(a_bits_per_sample / 8, a_channels + 1, a_channels); return 0; } From b687a0d4a49a111c657b514c622e248ba031e7c7 Mon Sep 17 00:00:00 2001 From: Tom Yan Date: Sat, 6 Feb 2021 21:22:05 +0800 Subject: [PATCH 3/4] bluray: use function pointer to call remap function --- ...ay_pcm_channel_layout_packet_converter.cpp | 84 +++++++++++-------- ...uray_pcm_channel_layout_packet_converter.h | 5 +- 2 files changed, 55 insertions(+), 34 deletions(-) diff --git a/src/input/bluray_pcm_channel_layout_packet_converter.cpp b/src/input/bluray_pcm_channel_layout_packet_converter.cpp index 433b16597..f779c8390 100644 --- a/src/input/bluray_pcm_channel_layout_packet_converter.cpp +++ b/src/input/bluray_pcm_channel_layout_packet_converter.cpp @@ -23,14 +23,19 @@ bluray_pcm_channel_layout_packet_converter_c::bluray_pcm_channel_layout_packet_c , m_bytes_per_channel{bytes_per_channel} , m_num_input_channels{num_input_channels} , m_num_output_channels{num_output_channels} - , m_remap_buf_size{0} + , m_remap_buf_size{} + , m_remap{} { - if (m_num_output_channels == 6) + if (m_num_output_channels == 6) { m_remap_buf_size = m_bytes_per_channel * 3; - else if (m_num_output_channels == 7) + m_remap = &bluray_pcm_channel_layout_packet_converter_c::remap_6ch; + } else if (m_num_output_channels == 7) { m_remap_buf_size = m_bytes_per_channel * 3; - else if (m_num_output_channels == 8) + m_remap = &bluray_pcm_channel_layout_packet_converter_c::remap_7ch; + } else if (m_num_output_channels == 8) { m_remap_buf_size = m_bytes_per_channel * 5; + m_remap = &bluray_pcm_channel_layout_packet_converter_c::remap_8ch; + } if (m_remap_buf_size > 0) m_remap_buf = memory_c::alloc(m_remap_buf_size); @@ -57,37 +62,50 @@ bluray_pcm_channel_layout_packet_converter_c::removal(packet_cptr const &packet) } void -bluray_pcm_channel_layout_packet_converter_c::remap(packet_cptr const &packet) { +bluray_pcm_channel_layout_packet_converter_c::remap_6ch(packet_cptr const &packet) { auto start_ptr = packet->data->get_buffer(); auto end_ptr = start_ptr + packet->data->get_size(); - if (m_num_output_channels == 6) { // post-remap order: FL FR FC LFE BL BR - while (start_ptr != end_ptr) { - start_ptr += m_bytes_per_channel * 3; - memcpy(m_remap_buf->get_buffer(), start_ptr, m_remap_buf_size); - memcpy(start_ptr, m_remap_buf->get_buffer() + m_bytes_per_channel * 2, m_bytes_per_channel); - memcpy(start_ptr + m_bytes_per_channel, m_remap_buf->get_buffer(), m_bytes_per_channel * 2); - start_ptr += m_remap_buf_size; - } - } else if (m_num_output_channels == 7) { // post-remap order: FL FR FC BL BR SL SR - while (start_ptr != end_ptr) { - start_ptr += m_bytes_per_channel * 3; - memcpy(m_remap_buf->get_buffer(), start_ptr, m_remap_buf_size); - memcpy(start_ptr, m_remap_buf->get_buffer() + m_bytes_per_channel, m_bytes_per_channel * 2); - memcpy(start_ptr + m_bytes_per_channel * 2, m_remap_buf->get_buffer(), m_bytes_per_channel); - start_ptr += m_remap_buf_size + m_bytes_per_channel; - } - } else if (m_num_output_channels == 8) { // post-remap order: FL FR FC LFE BL BR SL SR - while (start_ptr != end_ptr) { - start_ptr += m_bytes_per_channel * 3; - memcpy(m_remap_buf->get_buffer(), start_ptr, m_remap_buf_size); - memcpy(start_ptr, m_remap_buf->get_buffer() + m_bytes_per_channel * 4, m_bytes_per_channel); - // BL and BR stay at the same place - memcpy(start_ptr + m_bytes_per_channel * 3, m_remap_buf->get_buffer(), m_bytes_per_channel); - memcpy(start_ptr + m_bytes_per_channel * 4, - m_remap_buf->get_buffer() + m_bytes_per_channel * 3, m_bytes_per_channel); - start_ptr += m_remap_buf_size; - } + // post-remap order: FL FR FC LFE BL BR + while (start_ptr != end_ptr) { + start_ptr += m_bytes_per_channel * 3; + memcpy(m_remap_buf->get_buffer(), start_ptr, m_remap_buf_size); + memcpy(start_ptr, m_remap_buf->get_buffer() + m_bytes_per_channel * 2, m_bytes_per_channel); + memcpy(start_ptr + m_bytes_per_channel, m_remap_buf->get_buffer(), m_bytes_per_channel * 2); + start_ptr += m_remap_buf_size; + } +} + +void +bluray_pcm_channel_layout_packet_converter_c::remap_7ch(packet_cptr const &packet) { + auto start_ptr = packet->data->get_buffer(); + auto end_ptr = start_ptr + packet->data->get_size(); + + // post-remap order: FL FR FC BL BR SL SR + while (start_ptr != end_ptr) { + start_ptr += m_bytes_per_channel * 3; + memcpy(m_remap_buf->get_buffer(), start_ptr, m_remap_buf_size); + memcpy(start_ptr, m_remap_buf->get_buffer() + m_bytes_per_channel, m_bytes_per_channel * 2); + memcpy(start_ptr + m_bytes_per_channel * 2, m_remap_buf->get_buffer(), m_bytes_per_channel); + start_ptr += m_remap_buf_size + m_bytes_per_channel; + } +} + +void +bluray_pcm_channel_layout_packet_converter_c::remap_8ch(packet_cptr const &packet) { + auto start_ptr = packet->data->get_buffer(); + auto end_ptr = start_ptr + packet->data->get_size(); + + // post-remap order: FL FR FC LFE BL BR SL SR + while (start_ptr != end_ptr) { + start_ptr += m_bytes_per_channel * 3; + memcpy(m_remap_buf->get_buffer(), start_ptr, m_remap_buf_size); + memcpy(start_ptr, m_remap_buf->get_buffer() + m_bytes_per_channel * 4, m_bytes_per_channel); + // BL and BR stay at the same place + memcpy(start_ptr + m_bytes_per_channel * 3, m_remap_buf->get_buffer(), m_bytes_per_channel); + memcpy(start_ptr + m_bytes_per_channel * 4, + m_remap_buf->get_buffer() + m_bytes_per_channel * 3, m_bytes_per_channel); + start_ptr += m_remap_buf_size; } } @@ -99,7 +117,7 @@ bluray_pcm_channel_layout_packet_converter_c::convert(packet_cptr const &packet) // remap channels into WAVEFORMATEXTENSIBLE channel order if (m_remap_buf) - remap(packet); + (this->*m_remap)(packet); m_ptzr->process(packet); return true; diff --git a/src/input/bluray_pcm_channel_layout_packet_converter.h b/src/input/bluray_pcm_channel_layout_packet_converter.h index 36aabee94..a0a731591 100644 --- a/src/input/bluray_pcm_channel_layout_packet_converter.h +++ b/src/input/bluray_pcm_channel_layout_packet_converter.h @@ -22,12 +22,15 @@ class bluray_pcm_channel_layout_packet_converter_c: public packet_converter_c { protected: std::size_t m_bytes_per_channel, m_num_input_channels, m_num_output_channels, m_remap_buf_size; memory_cptr m_remap_buf; + void (bluray_pcm_channel_layout_packet_converter_c::*m_remap)(packet_cptr const &packet); public: bluray_pcm_channel_layout_packet_converter_c(std::size_t bytes_per_channel, std::size_t num_input_channels, std::size_t num_output_channels); virtual ~bluray_pcm_channel_layout_packet_converter_c() {}; virtual void removal(packet_cptr const &packet); - virtual void remap(packet_cptr const &packet); + virtual void remap_6ch(packet_cptr const &packet); + virtual void remap_7ch(packet_cptr const &packet); + virtual void remap_8ch(packet_cptr const &packet); virtual bool convert(packet_cptr const &packet); }; From 7f24c3fd5bde3b68de6d6215a3a969b16fe5b243 Mon Sep 17 00:00:00 2001 From: Tom Yan Date: Sat, 6 Feb 2021 21:31:14 +0800 Subject: [PATCH 4/4] bluray: truncate packet if not sample-aligned before remap --- src/input/bluray_pcm_channel_layout_packet_converter.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/input/bluray_pcm_channel_layout_packet_converter.cpp b/src/input/bluray_pcm_channel_layout_packet_converter.cpp index f779c8390..aeb113aff 100644 --- a/src/input/bluray_pcm_channel_layout_packet_converter.cpp +++ b/src/input/bluray_pcm_channel_layout_packet_converter.cpp @@ -116,8 +116,12 @@ bluray_pcm_channel_layout_packet_converter_c::convert(packet_cptr const &packet) removal(packet); // remap channels into WAVEFORMATEXTENSIBLE channel order - if (m_remap_buf) + if (m_remap_buf) { + auto remainder = packet->data->get_size() % (m_bytes_per_channel * m_num_output_channels); + if (remainder != 0) + packet->data->set_size(packet->data->get_size() - remainder); (this->*m_remap)(packet); + } m_ptzr->process(packet); return true;