From 7fe61d48c6318f52d780772c809740fe5c9f19ed Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Sat, 20 Feb 2021 14:12:31 +0100 Subject: [PATCH] rename namespace mpeg4::p2 to mtx::mpeg4_p2 --- src/common/mpeg4_p2.cpp | 183 +++++++++++++++-------------- src/common/mpeg4_p2.h | 30 ++--- src/output/p_mpeg4_p2.cpp | 26 ++-- src/output/p_mpeg4_p2.h | 4 +- src/output/p_video_for_windows.cpp | 4 +- 5 files changed, 127 insertions(+), 120 deletions(-) diff --git a/src/common/mpeg4_p2.cpp b/src/common/mpeg4_p2.cpp index 2cde3021e..c1fd6e32e 100644 --- a/src/common/mpeg4_p2.cpp +++ b/src/common/mpeg4_p2.cpp @@ -15,31 +15,26 @@ #include "common/common_pch.h" #include "common/bit_reader.h" +#include "common/debugging.h" #include "common/endian.h" #include "common/math.h" #include "common/mm_io.h" #include "common/mm_mem_io.h" #include "common/mpeg4_p2.h" -namespace mpeg4 { - namespace p2 { - static bool find_vol_header(mtx::bits::reader_c &bits); - static bool parse_vol_header(const unsigned char *buffer, int buffer_size, config_data_t &config_data); - static bool extract_par_internal(const unsigned char *buffer, int buffer_size, uint32_t &par_num, uint32_t &par_den); - static void parse_frame(video_frame_t &frame, const unsigned char *buffer, const mpeg4::p2::config_data_t &config_data); - } -} +namespace mtx::mpeg4_p2 { -mpeg4::p2::config_data_t::config_data_t() - : m_time_increment_bits(0) - , m_width(0) - , m_height(0) - , m_width_height_found(false) -{ -} +namespace { -static bool -mpeg4::p2::find_vol_header(mtx::bits::reader_c &bits) { +debugging_option_c s_debug{"mpeg4_p2"}; + +bool find_vol_header(mtx::bits::reader_c &bits); +bool parse_vol_header(const unsigned char *buffer, int buffer_size, config_data_t &config_data); +bool extract_par_internal(const unsigned char *buffer, int buffer_size, uint32_t &par_num, uint32_t &par_den); +void parse_frame(video_frame_t &frame, const unsigned char *buffer, const config_data_t &config_data); + +bool +find_vol_header(mtx::bits::reader_c &bits) { uint32_t marker; while (!bits.eof()) { @@ -62,10 +57,10 @@ mpeg4::p2::find_vol_header(mtx::bits::reader_c &bits) { return false; } -static bool -mpeg4::p2::parse_vol_header(const unsigned char *buffer, - int buffer_size, - mpeg4::p2::config_data_t &config_data) { +bool +parse_vol_header(unsigned char const *buffer, + int buffer_size, + config_data_t &config_data) { mtx::bits::reader_c bits(buffer, buffer_size); if (!find_vol_header(bits)) @@ -129,43 +124,11 @@ mpeg4::p2::parse_vol_header(const unsigned char *buffer, return true; } -/** Extract the widht and height from a MPEG4 video frame - - This function searches a buffer containing a MPEG4 video frame - for the width and height. - - \param buffer The buffer containing the MPEG4 video frame. - \param buffer_size The size of the buffer in bytes. - \param width The width, if found, is stored in this variable. - \param height The height, if found, is stored in this variable. - - \return \c true if width and height were found and \c false - otherwise. -*/ bool -mpeg4::p2::extract_size(const unsigned char *buffer, - int buffer_size, - uint32_t &width, - uint32_t &height) { - try { - mpeg4::p2::config_data_t config_data; - if (!parse_vol_header(buffer, buffer_size, config_data) || !config_data.m_width_height_found) - return false; - - width = config_data.m_width; - height = config_data.m_height; - - return true; - } catch (...) { - return false; - } -} - -static bool -mpeg4::p2::extract_par_internal(const unsigned char *buffer, - int buffer_size, - uint32_t &par_num, - uint32_t &par_den) { +extract_par_internal(unsigned char const *buffer, + int buffer_size, + uint32_t &par_num, + uint32_t &par_den) { const uint32_t ar_nums[16] = {0, 1, 12, 10, 16, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; const uint32_t ar_dens[16] = {1, 1, 11, 11, 11, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; uint32_t aspect_ratio_info, num, den; @@ -205,6 +168,65 @@ mpeg4::p2::extract_par_internal(const unsigned char *buffer, return false; } +void +parse_frame(video_frame_t &frame, + unsigned char const *buffer, + config_data_t const &config_data) { + static const frame_type_e s_frame_type_map[4] = { FRAME_TYPE_I, FRAME_TYPE_P, FRAME_TYPE_B, FRAME_TYPE_P }; + + mtx::bits::reader_c bc(&buffer[ frame.pos + 4 ], frame.size); + + frame.type = s_frame_type_map[ bc.get_bits(2) ]; + + while (bc.get_bit()) + ; // modulo time base + bc.skip_bits(1 + config_data.m_time_increment_bits + 1); // marker, vop time increment, marker + + frame.is_coded = bc.get_bit(); +} + +} // anonymous namespace + +config_data_t::config_data_t() + : m_time_increment_bits(0) + , m_width(0) + , m_height(0) + , m_width_height_found(false) +{ +} + +/** Extract the widht and height from a MPEG4 video frame + + This function searches a buffer containing a MPEG4 video frame + for the width and height. + + \param buffer The buffer containing the MPEG4 video frame. + \param buffer_size The size of the buffer in bytes. + \param width The width, if found, is stored in this variable. + \param height The height, if found, is stored in this variable. + + \return \c true if width and height were found and \c false + otherwise. +*/ +bool +extract_size(unsigned char const *buffer, + int buffer_size, + uint32_t &width, + uint32_t &height) { + try { + config_data_t config_data; + if (!parse_vol_header(buffer, buffer_size, config_data) || !config_data.m_width_height_found) + return false; + + width = config_data.m_width; + height = config_data.m_height; + + return true; + } catch (...) { + return false; + } +} + /** Extract the pixel aspect ratio from a MPEG4 video frame This function searches a buffer containing a MPEG4 video frame @@ -220,10 +242,10 @@ mpeg4::p2::extract_par_internal(const unsigned char *buffer, otherwise. */ bool -mpeg4::p2::extract_par(const unsigned char *buffer, - int buffer_size, - uint32_t &par_num, - uint32_t &par_den) { +extract_par(unsigned char const *buffer, + int buffer_size, + uint32_t &par_num, + uint32_t &par_den) { try { return extract_par_internal(buffer, buffer_size, par_num, par_den); } catch (...) { @@ -231,23 +253,6 @@ mpeg4::p2::extract_par(const unsigned char *buffer, } } -static void -mpeg4::p2::parse_frame(video_frame_t &frame, - const unsigned char *buffer, - const mpeg4::p2::config_data_t &config_data) { - static const frame_type_e s_frame_type_map[4] = { FRAME_TYPE_I, FRAME_TYPE_P, FRAME_TYPE_B, FRAME_TYPE_P }; - - mtx::bits::reader_c bc(&buffer[ frame.pos + 4 ], frame.size); - - frame.type = s_frame_type_map[ bc.get_bits(2) ]; - - while (bc.get_bit()) - ; // modulo time base - bc.skip_bits(1 + config_data.m_time_increment_bits + 1); // marker, vop time increment, marker - - frame.is_coded = bc.get_bit(); -} - /** Find frame boundaries and frame types in a packed video frame This function searches a buffer containing one or more MPEG4 video frames @@ -263,10 +268,10 @@ mpeg4::p2::parse_frame(video_frame_t &frame, a dummy frame) then \a frames will contain no elements. */ void -mpeg4::p2::find_frame_types(const unsigned char *buffer, - int buffer_size, - std::vector &frames, - const mpeg4::p2::config_data_t &config_data) { +find_frame_types(unsigned char const *buffer, + int buffer_size, + std::vector &frames, + config_data_t const &config_data) { frames.clear(); mxdebug_if(s_debug, fmt::format("\nmpeg4_frames: start search in {0} bytes\n", buffer_size)); @@ -339,9 +344,9 @@ mpeg4::p2::find_frame_types(const unsigned char *buffer, a memory_c object otherwise. This object has to be deleted manually. */ memory_cptr -mpeg4::p2::parse_config_data(const unsigned char *buffer, - int buffer_size, - mpeg4::p2::config_data_t &config_data) { +parse_config_data(unsigned char const *buffer, + int buffer_size, + config_data_t &config_data) { if (5 > buffer_size) return nullptr; @@ -378,7 +383,7 @@ mpeg4::p2::parse_config_data(const unsigned char *buffer, if (-1 != vol_offset) try { - mpeg4::p2::config_data_t cfg_data; + config_data_t cfg_data; if (parse_vol_header(&buffer[ vol_offset ], buffer_size - vol_offset, cfg_data)) config_data.m_time_increment_bits = cfg_data.m_time_increment_bits; @@ -417,7 +422,7 @@ mpeg4::p2::parse_config_data(const unsigned char *buffer, \return true if the FourCC refers to a MPEG-4 part 2 video codec. */ bool -mpeg4::p2::is_fourcc(const void *fourcc) { +is_fourcc(void const *fourcc) { static const char *mpeg4_p2_fourccs[] = { "MP42", "DIV2", "DIVX", "XVID", "DX50", "FMP4", "DXGM", nullptr @@ -438,7 +443,7 @@ mpeg4::p2::is_fourcc(const void *fourcc) { \return true if the FourCC refers to a MPEG-4 part 2 video codec. */ bool -mpeg4::p2::is_v3_fourcc(const void *fourcc) { +is_v3_fourcc(void const *fourcc) { static const char *mpeg4_p2_v3_fourccs[] = { "DIV3", "MPG3", "MP43", "AP41", // Angel Potion @@ -451,3 +456,5 @@ mpeg4::p2::is_v3_fourcc(const void *fourcc) { return true; return false; } + +} // namespace mtx::mpeg4_p2 diff --git a/src/common/mpeg4_p2.h b/src/common/mpeg4_p2.h index 1598ce340..8beac0458 100644 --- a/src/common/mpeg4_p2.h +++ b/src/common/mpeg4_p2.h @@ -16,6 +16,8 @@ #include "common/common_pch.h" +namespace mtx::mpeg4_p2 { + /** Start code for a MPEG-4 part 2 (?) video object plain */ #define MPEGVIDEO_VOP_START_CODE 0x000001b6 #define MPEGVIDEO_VOL_START_CODE 0x00000120 @@ -115,22 +117,20 @@ struct video_frame_t { } }; -namespace mpeg4 { - namespace p2 { - struct config_data_t { - int m_time_increment_bits; - int m_width, m_height; - bool m_width_height_found; +struct config_data_t { + int m_time_increment_bits; + int m_width, m_height; + bool m_width_height_found; - config_data_t(); - }; + config_data_t(); +}; - bool is_fourcc(const void *fourcc); - bool is_v3_fourcc(const void *fourcc); +bool is_fourcc(const void *fourcc); +bool is_v3_fourcc(const void *fourcc); + +bool extract_par(const unsigned char *buffer, int buffer_size, uint32_t &par_num, uint32_t &par_den); +bool extract_size(const unsigned char *buffer, int buffer_size, uint32_t &width, uint32_t &height); +void find_frame_types(const unsigned char *buffer, int buffer_size, std::vector &frames, const config_data_t &config_data); +memory_cptr parse_config_data(const unsigned char *buffer, int buffer_size, config_data_t &config_data); - bool extract_par(const unsigned char *buffer, int buffer_size, uint32_t &par_num, uint32_t &par_den); - bool extract_size(const unsigned char *buffer, int buffer_size, uint32_t &width, uint32_t &height); - void find_frame_types(const unsigned char *buffer, int buffer_size, std::vector &frames, const config_data_t &config_data); - memory_cptr parse_config_data(const unsigned char *buffer, int buffer_size, config_data_t &config_data); - } } diff --git a/src/output/p_mpeg4_p2.cpp b/src/output/p_mpeg4_p2.cpp index b712e01f4..4d9c8f2f9 100644 --- a/src/output/p_mpeg4_p2.cpp +++ b/src/output/p_mpeg4_p2.cpp @@ -110,8 +110,8 @@ mpeg4_p2_video_packetizer_c::process_non_native(packet_cptr packet) { mxerror_tid(m_ti.m_fname, m_ti.m_id, Y("Cannot convert non-native MPEG4 video frames into native ones if the source container " "provides neither timestamps nor a number of frames per second.\n")); - std::vector frames; - mpeg4::p2::find_frame_types(packet->data->get_buffer(), packet->data->get_size(), frames, m_config_data); + std::vector frames; + mtx::mpeg4_p2::find_frame_types(packet->data->get_buffer(), packet->data->get_size(), frames, m_config_data); for (auto &frame : frames) { if (!frame.is_coded) { @@ -138,22 +138,22 @@ mpeg4_p2_video_packetizer_c::process_non_native(packet_cptr packet) { continue; } - if (FRAME_TYPE_I == frame.type) + if (mtx::mpeg4_p2::FRAME_TYPE_I == frame.type) ++m_statistics.m_num_i_frames; - else if (FRAME_TYPE_P == frame.type) + else if (mtx::mpeg4_p2::FRAME_TYPE_P == frame.type) ++m_statistics.m_num_p_frames; else ++m_statistics.m_num_b_frames; // Maybe we can flush queued frames now. But only if we don't have // a B frame. - if (FRAME_TYPE_B != frame.type) + if (mtx::mpeg4_p2::FRAME_TYPE_B != frame.type) flush_frames(false); frame.data = (unsigned char *)safememdup(packet->data->get_buffer() + frame.pos, frame.size); frame.timestamp = -1; - if (FRAME_TYPE_B == frame.type) + if (mtx::mpeg4_p2::FRAME_TYPE_B == frame.type) m_b_frames.push_back(frame); else m_ref_frames.push_back(frame); @@ -169,7 +169,7 @@ mpeg4_p2_video_packetizer_c::extract_config_data(packet_cptr &packet) { if (m_ti.m_private_data) return; - m_ti.m_private_data = memory_cptr{mpeg4::p2::parse_config_data(packet->data->get_buffer(), packet->data->get_size(), m_config_data)}; + m_ti.m_private_data = memory_cptr{mtx::mpeg4_p2::parse_config_data(packet->data->get_buffer(), packet->data->get_size(), m_config_data)}; if (!m_ti.m_private_data) mxerror_tid(m_ti.m_fname, m_ti.m_id, Y("Could not find the codec configuration data in the first MPEG-4 part 2 video frame. This track cannot be stored in native mode.\n")); @@ -270,7 +270,7 @@ mpeg4_p2_video_packetizer_c::flush_frames(bool end_of_file) { return; if (m_ref_frames.size() == 1) { - video_frame_t &frame = m_ref_frames.front(); + auto &frame = m_ref_frames.front(); // The first frame in the file. Only apply the timestamp, nothing else. if (-1 == frame.timestamp) { @@ -280,14 +280,14 @@ mpeg4_p2_video_packetizer_c::flush_frames(bool end_of_file) { return; } - video_frame_t &bref_frame = m_ref_frames.front(); - video_frame_t &fref_frame = m_ref_frames.back(); + auto &bref_frame = m_ref_frames.front(); + auto &fref_frame = m_ref_frames.back(); for (auto &frame : m_b_frames) get_next_timestamp_and_duration(frame.timestamp, frame.duration); get_next_timestamp_and_duration(fref_frame.timestamp, fref_frame.duration); - add_packet(new packet_t(memory_c::take_ownership(fref_frame.data, fref_frame.size), fref_frame.timestamp, fref_frame.duration, FRAME_TYPE_P == fref_frame.type ? bref_frame.timestamp : VFT_IFRAME)); + add_packet(new packet_t(memory_c::take_ownership(fref_frame.data, fref_frame.size), fref_frame.timestamp, fref_frame.duration, mtx::mpeg4_p2::FRAME_TYPE_P == fref_frame.type ? bref_frame.timestamp : VFT_IFRAME)); for (auto &frame : m_b_frames) add_packet(new packet_t(memory_c::take_ownership(frame.data, frame.size), frame.timestamp, frame.duration, bref_frame.timestamp, fref_frame.timestamp)); @@ -315,7 +315,7 @@ mpeg4_p2_video_packetizer_c::extract_aspect_ratio(const unsigned char *buffer, } uint32_t num, den; - if (mpeg4::p2::extract_par(buffer, size, num, den)) { + if (mtx::mpeg4_p2::extract_par(buffer, size, num, den)) { m_aspect_ratio_extracted = true; set_video_aspect_ratio((double)m_hvideo_pixel_width / (double)m_hvideo_pixel_height * (double)num / (double)den, false, OPTION_SOURCE_BITSTREAM); @@ -342,7 +342,7 @@ mpeg4_p2_video_packetizer_c::extract_size(const unsigned char *buffer, uint32_t xtr_width, xtr_height; - if (mpeg4::p2::extract_size(buffer, size, xtr_width, xtr_height)) { + if (mtx::mpeg4_p2::extract_size(buffer, size, xtr_width, xtr_height)) { m_size_extracted = true; if (!m_reader->m_appending && ((xtr_width != static_cast(m_hvideo_pixel_width)) || (xtr_height != static_cast(m_hvideo_pixel_height)))) { diff --git a/src/output/p_mpeg4_p2.h b/src/output/p_mpeg4_p2.h index 9cd362fc7..1d9ee4108 100644 --- a/src/output/p_mpeg4_p2.h +++ b/src/output/p_mpeg4_p2.h @@ -46,12 +46,12 @@ protected: } }; - std::deque m_ref_frames, m_b_frames; + std::deque m_ref_frames, m_b_frames; std::deque m_available_timestamps; int64_t m_timestamps_generated, m_previous_timestamp; bool m_aspect_ratio_extracted, m_input_is_native, m_output_is_native; bool m_size_extracted; - mpeg4::p2::config_data_t m_config_data; + mtx::mpeg4_p2::config_data_t m_config_data; statistics_t m_statistics; public: diff --git a/src/output/p_video_for_windows.cpp b/src/output/p_video_for_windows.cpp index d2a737f34..bb123c295 100644 --- a/src/output/p_video_for_windows.cpp +++ b/src/output/p_video_for_windows.cpp @@ -53,10 +53,10 @@ video_for_windows_packetizer_c::check_fourcc() { memcpy(fourcc, &reinterpret_cast(m_ti.m_private_data->get_buffer())->bi_compression, 4); fourcc[4] = 0; - if (mpeg4::p2::is_v3_fourcc(fourcc)) + if (mtx::mpeg4_p2::is_v3_fourcc(fourcc)) m_codec_type = video_for_windows_packetizer_c::ct_div3; - else if (mpeg4::p2::is_fourcc(fourcc)) + else if (mtx::mpeg4_p2::is_fourcc(fourcc)) m_codec_type = video_for_windows_packetizer_c::ct_mpeg4_p2; }