From ba9c82fc2490d7a8699a934e0091a19295ae6926 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Mon, 12 Jul 2010 15:23:06 +0200 Subject: [PATCH] Use header removal compression for MPEG-4 part 10 tracks with 4 bytes NALU size length --- ChangeLog | 4 ++++ TODO | 2 -- src/common/compression.cpp | 12 +++++++++++- src/common/compression.h | 6 ++++++ src/common/mpeg4_p10.h | 4 ++++ src/output/p_avc.cpp | 3 +++ src/output/p_mpeg4_p10.cpp | 13 ++++++++----- 7 files changed, 36 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4c87589d0..9d2b22d48 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2010-07-12 Moritz Bunkus + * mkvmerge: enhancement: Header removal compression has been + enabled by default for MPEG-4 part 10 (AVC/h.264) video tracks + with a NALU size field length of four bytes. + * mkvmerge: bug fix: Header removal compression has been deactivated for MPEG-4 part 2 (aka DivX/Xvid) video tracks due to incompatibility with packed bitstreams. diff --git a/TODO b/TODO index f729c26df..eda12f5b7 100644 --- a/TODO +++ b/TODO @@ -6,6 +6,4 @@ https://www.bunkus.org/bugzilla/buglist.cgi?query_format=advanced&product=mkvtoo Apart from that as a short reminder list for myself for the near future: -- Enable header removal compression for MPEG-4 part 10 if the NALU size length is 4 (bug 519) - - Write attachments before the clusters (bug 516) diff --git a/src/common/compression.cpp b/src/common/compression.cpp index fa04baa24..c641eb130 100644 --- a/src/common/compression.cpp +++ b/src/common/compression.cpp @@ -27,7 +27,7 @@ using namespace libmatroska; const char *compression_methods[] = { - "unspecified", "zlib", "bz2", "lzo", "header_removal", "mpeg4_p2", "dirac", "dts", "ac3", "mp3", "analyze_header_removal", "none" + "unspecified", "zlib", "bz2", "lzo", "header_removal", "mpeg4_p2", "mpeg4_p10", "dirac", "dts", "ac3", "mp3", "analyze_header_removal", "none" }; static const int compression_method_map[] = { @@ -37,6 +37,7 @@ static const int compression_method_map[] = { 2, // lzo1x 3, // header removal 3, // mpeg4_p2 is header removal + 3, // mpeg4_p10 is header removal 3, // dirac is header removal 3, // dts is header removal 3, // ac3 is header removal @@ -373,6 +374,12 @@ mpeg4_p2_compressor_c::mpeg4_p2_compressor_c() { set_bytes(bytes); } +mpeg4_p10_compressor_c::mpeg4_p10_compressor_c() { + memory_cptr bytes = memory_c::alloc(1); + bytes->get_buffer()[0] = 0; + set_bytes(bytes); +} + dirac_compressor_c::dirac_compressor_c() { memory_cptr bytes = memory_c::alloc(4); put_uint32_be(bytes->get_buffer(), DIRAC_SYNC_WORD); @@ -443,6 +450,9 @@ compressor_c::create(const char *method) { if (!strcasecmp(method, compression_methods[COMPRESSION_MPEG4_P2])) return compressor_ptr(new mpeg4_p2_compressor_c()); + if (!strcasecmp(method, compression_methods[COMPRESSION_MPEG4_P10])) + return compressor_ptr(new mpeg4_p10_compressor_c()); + if (!strcasecmp(method, compression_methods[COMPRESSION_DIRAC])) return compressor_ptr(new dirac_compressor_c()); diff --git a/src/common/compression.h b/src/common/compression.h index d6860e7e0..dac2a5282 100644 --- a/src/common/compression.h +++ b/src/common/compression.h @@ -32,6 +32,7 @@ enum compression_method_e { COMPRESSION_LZO, COMPRESSION_HEADER_REMOVAL, COMPRESSION_MPEG4_P2, + COMPRESSION_MPEG4_P10, COMPRESSION_DIRAC, COMPRESSION_DTS, COMPRESSION_AC3, @@ -165,6 +166,11 @@ public: mpeg4_p2_compressor_c(); }; +class MTX_DLL_API mpeg4_p10_compressor_c: public header_removal_compressor_c { +public: + mpeg4_p10_compressor_c(); +}; + class MTX_DLL_API dirac_compressor_c: public header_removal_compressor_c { public: dirac_compressor_c(); diff --git a/src/common/mpeg4_p10.h b/src/common/mpeg4_p10.h index 3542a6d19..d954205f0 100644 --- a/src/common/mpeg4_p10.h +++ b/src/common/mpeg4_p10.h @@ -274,6 +274,10 @@ namespace mpeg4 { m_nalu_size_length = nalu_size_length; }; + int get_nalu_size_length() { + return m_nalu_size_length; + }; + void ignore_nalu_size_length_errors() { m_ignore_nalu_size_length_errors = true; }; diff --git a/src/output/p_avc.cpp b/src/output/p_avc.cpp index 54a5a715e..cfc5e1e50 100644 --- a/src/output/p_avc.cpp +++ b/src/output/p_avc.cpp @@ -61,6 +61,9 @@ mpeg4_p10_es_video_packetizer_c(generic_reader_c *p_reader, // duration/FPS itself. if (m_ti.m_ext_timecodes.empty()) m_timecode_factory.clear(); + + if (4 == m_parser.get_nalu_size_length()) + set_default_compression_method(COMPRESSION_MPEG4_P10); } void diff --git a/src/output/p_mpeg4_p10.cpp b/src/output/p_mpeg4_p10.cpp index d3f97025d..7f684e0af 100644 --- a/src/output/p_mpeg4_p10.cpp +++ b/src/output/p_mpeg4_p10.cpp @@ -33,13 +33,15 @@ mpeg4_p10_video_packetizer_c(generic_reader_c *p_reader, , m_nalu_size_len_dst(0) , m_max_nalu_size(0) { - m_relaxed_timecode_checking = true; - if ((NULL != m_ti.m_private_data) && (0 < m_ti.m_private_size)) { - setup_nalu_size_len_change(); + setup_nalu_size_len_change(); + + if ((NULL != m_ti.m_private_data) && (0 < m_ti.m_private_size)) set_codec_private(m_ti.m_private_data, m_ti.m_private_size); - } + + if (4 == m_nalu_size_len_dst) + set_default_compression_method(COMPRESSION_MPEG4_P10); } void @@ -78,7 +80,7 @@ mpeg4_p10_video_packetizer_c::process(packet_cptr packet) { m_ref_timecode = packet->timecode; - if (m_nalu_size_len_dst) + if (m_nalu_size_len_dst && (m_nalu_size_len_dst != m_nalu_size_len_src)) change_nalu_size_len(packet); add_packet(packet); @@ -111,6 +113,7 @@ mpeg4_p10_video_packetizer_c::setup_nalu_size_len_change() { return; m_nalu_size_len_src = (m_ti.m_private_data[4] & 0x03) + 1; + m_nalu_size_len_dst = m_nalu_size_len_src; if (!m_ti.m_nalu_size_length || (m_ti.m_nalu_size_length == m_nalu_size_len_src)) return;