HEVC ES parser: optionally normalize VPS/SPS/PPS placement

This commit is contained in:
Moritz Bunkus 2021-03-03 22:15:40 +01:00
parent e6c853ddf0
commit 90e9d2feab
No known key found for this signature in database
GPG Key ID: 74AF00ADF2E32C85
2 changed files with 36 additions and 4 deletions

View File

@ -106,6 +106,11 @@ es_parser_c::discard_actual_frames(bool discard) {
m_discard_actual_frames = discard;
}
void
es_parser_c::normalize_parameter_sets(bool normalize) {
m_normalize_parameter_sets = normalize;
}
void
es_parser_c::add_bytes(unsigned char *buffer,
size_t size) {
@ -226,6 +231,25 @@ es_parser_c::add_timestamp(int64_t timestamp) {
++m_stats.num_timestamps_in;
}
void
es_parser_c::add_parameter_sets_to_extra_data() {
std::vector<memory_cptr> old_extra_data;
for (auto const &data : m_extra_data)
if (old_extra_data.empty() || (*data != *old_extra_data.back()))
old_extra_data.emplace_back(data);
m_extra_data.clear();
m_extra_data.reserve(m_vps_list.size() + m_sps_list.size() + m_pps_list.size() + old_extra_data.size());
auto create_nalu_and_add = [this](memory_cptr const &nalu) { m_extra_data.push_back(create_nalu_with_size(nalu)); };
std::for_each(m_vps_list.begin(), m_vps_list.end(), create_nalu_and_add);
std::for_each(m_sps_list.begin(), m_sps_list.end(), create_nalu_and_add);
std::for_each(m_pps_list.begin(), m_pps_list.end(), create_nalu_and_add);
std::copy( old_extra_data.begin(), old_extra_data.end(), std::back_inserter(m_extra_data));
}
void
es_parser_c::flush_incomplete_frame() {
if (!m_have_incomplete_frame || !m_hevcc_ready)
@ -287,6 +311,9 @@ es_parser_c::handle_slice_nalu(memory_cptr const &nalu,
m_b_frames_since_keyframe = false;
cleanup();
if (m_normalize_parameter_sets)
add_parameter_sets_to_extra_data();
} else
m_b_frames_since_keyframe |= is_b_slice;
@ -344,7 +371,8 @@ es_parser_c::handle_vps_nalu(memory_cptr const &nalu) {
m_codec_private.vps_data_id = vps_info.id;
}
m_extra_data.push_back(create_nalu_with_size(nalu));
if (!m_normalize_parameter_sets)
m_extra_data.push_back(create_nalu_with_size(nalu));
}
void
@ -386,7 +414,8 @@ es_parser_c::handle_sps_nalu(memory_cptr const &nalu) {
} else
use_sps_info = false;
m_extra_data.push_back(create_nalu_with_size(parsed_nalu));
if (!m_normalize_parameter_sets)
m_extra_data.push_back(create_nalu_with_size(parsed_nalu));
// Update codec private if needed
if (-1 == m_codec_private.sps_data_id)
@ -450,7 +479,8 @@ es_parser_c::handle_pps_nalu(memory_cptr const &nalu) {
m_hevcc_changed = true;
}
m_extra_data.push_back(create_nalu_with_size(nalu));
if (!m_normalize_parameter_sets)
m_extra_data.push_back(create_nalu_with_size(nalu));
}
void

View File

@ -81,7 +81,7 @@ protected:
bool m_have_incomplete_frame{};
std::deque<std::pair<memory_cptr, uint64_t>> m_unhandled_nalus;
bool m_simple_picture_order{}, m_discard_actual_frames{};
bool m_simple_picture_order{}, m_discard_actual_frames{}, m_normalize_parameter_sets{};
debugging_option_c m_debug_keyframe_detection{"hevc_parser|hevc_keyframe_detection"}, m_debug_nalu_types{"hevc_parser|hevc_nalu_types"}, m_debug_timestamps{"hevc_parser|hevc_timestamps"}, m_debug_sps_info{"hevc_parser|hevc_sps|hevc_sps_info"}, m_debug_parameter_sets{"hevc_parser|hevc_parameter_sets"};
static std::unordered_map<int, std::string> ms_nalu_names_by_type;
@ -175,6 +175,7 @@ public:
}
void discard_actual_frames(bool discard = true);
void normalize_parameter_sets(bool normalize = true);
int get_num_skipped_frames() const {
return m_num_skipped_frames;
@ -218,6 +219,7 @@ protected:
void calculate_frame_order();
void calculate_frame_timestamps();
void calculate_frame_references_and_update_stats();
void add_parameter_sets_to_extra_data();
static void init_nalu_names();
};