mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2025-01-17 23:44:20 +00:00
AVC ES parser: report NALU statistics
This commit is contained in:
parent
abb66a5486
commit
4248d327ec
@ -29,6 +29,8 @@
|
||||
|
||||
namespace mtx { namespace avc {
|
||||
|
||||
std::map<int, std::string> es_parser_c::ms_nalu_names_by_type;
|
||||
|
||||
es_parser_c::es_parser_c()
|
||||
: m_nalu_size_length(4)
|
||||
, m_keep_ar_info(true)
|
||||
@ -60,32 +62,35 @@ es_parser_c::es_parser_c()
|
||||
, m_debug_sps_info{ "avc_parser|avc_sps|avc_sps_info"}
|
||||
, m_debug_sps_pps_changes{ "avc_parser|avc_sps_pps_changes"}
|
||||
{
|
||||
if (m_debug_nalu_types)
|
||||
if (m_debug_nalu_types || debugging_c::requested("avc_statistics"))
|
||||
init_nalu_names();
|
||||
}
|
||||
|
||||
es_parser_c::~es_parser_c() {
|
||||
mxdebug_if(debugging_c::requested("avc_statistics"),
|
||||
boost::format("AVC statistics: #frames: out %1% discarded %2% #timestamps: in %3% generated %4% discarded %5% num_fields: %6% num_frames: %7% num_sei_nalus: %8% num_idr_slices: %9%\n")
|
||||
% m_stats.num_frames_out % m_stats.num_frames_discarded % m_stats.num_timestamps_in % m_stats.num_timestamps_generated % m_stats.num_timestamps_discarded
|
||||
% m_stats.num_field_slices % m_stats.num_frame_slices % m_stats.num_sei_nalus % m_stats.num_idr_slices);
|
||||
|
||||
mxdebug_if(m_debug_timestamps, boost::format("stream_position %1% parsed_position %2%\n") % m_stream_position % m_parsed_position);
|
||||
|
||||
if (!debugging_c::requested("avc_num_slices_by_type"))
|
||||
if (!debugging_c::requested("avc_statistics"))
|
||||
return;
|
||||
|
||||
static const char *s_type_names[] = {
|
||||
mxdebug(boost::format("AVC statistics: #frames: out %1% discarded %2% #timestamps: in %3% generated %4% discarded %5% num_fields: %6% num_frames: %7% num_sei_nalus: %8% num_idr_slices: %9%\n")
|
||||
% m_stats.num_frames_out % m_stats.num_frames_discarded % m_stats.num_timestamps_in % m_stats.num_timestamps_generated % m_stats.num_timestamps_discarded
|
||||
% m_stats.num_field_slices % m_stats.num_frame_slices % m_stats.num_sei_nalus % m_stats.num_idr_slices);
|
||||
|
||||
static const char *s_slice_type_names[] = {
|
||||
"P", "B", "I", "SP", "SI",
|
||||
"P2", "B2", "I2", "SP2", "SI2",
|
||||
"unknown"
|
||||
};
|
||||
|
||||
int i;
|
||||
mxdebug("mpeg4::p10: Number of NALUs by type:\n");
|
||||
for (int i = 0, size = m_stats.num_nalus_by_type.size(); i < size; ++i)
|
||||
if (0 != m_stats.num_nalus_by_type[i])
|
||||
mxdebug(boost::format(" %1%: %2%\n") % get_nalu_type_name(i + 1) % m_stats.num_nalus_by_type[i]);
|
||||
|
||||
mxdebug("mpeg4::p10: Number of slices by type:\n");
|
||||
for (i = 0; 10 >= i; ++i)
|
||||
for (int i = 0, size = m_stats.num_slices_by_type.size(); i < size; ++i)
|
||||
if (0 != m_stats.num_slices_by_type[i])
|
||||
mxdebug(boost::format(" %1%: %2%\n") % s_type_names[i] % m_stats.num_slices_by_type[i]);
|
||||
mxdebug(boost::format(" %1%: %2%\n") % s_slice_type_names[i] % m_stats.num_slices_by_type[i]);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -481,6 +486,8 @@ es_parser_c::handle_nalu(memory_cptr const &nalu,
|
||||
|
||||
mxdebug_if(m_debug_nalu_types, boost::format("NALU type 0x%|1$02x| (%2%) at %3% size %4%\n") % type % get_nalu_type_name(type) % nalu_pos % nalu->get_size());
|
||||
|
||||
++m_stats.num_nalus_by_type[std::max(std::min(type, 13), 1) - 1];
|
||||
|
||||
switch (type) {
|
||||
case NALU_TYPE_SEQ_PARAM:
|
||||
flush_incomplete_frame();
|
||||
@ -964,26 +971,30 @@ es_parser_c::dump_info()
|
||||
}
|
||||
|
||||
std::string
|
||||
es_parser_c::get_nalu_type_name(int type)
|
||||
const {
|
||||
auto name = m_nalu_names_by_type.find(type);
|
||||
return (m_nalu_names_by_type.end() == name) ? "unknown" : name->second;
|
||||
es_parser_c::get_nalu_type_name(int type) {
|
||||
init_nalu_names();
|
||||
|
||||
auto name = ms_nalu_names_by_type.find(type);
|
||||
return (ms_nalu_names_by_type.end() == name) ? "unknown" : name->second;
|
||||
}
|
||||
|
||||
void
|
||||
es_parser_c::init_nalu_names() {
|
||||
m_nalu_names_by_type[NALU_TYPE_NON_IDR_SLICE] = "non IDR slice";
|
||||
m_nalu_names_by_type[NALU_TYPE_DP_A_SLICE] = "DP A slice";
|
||||
m_nalu_names_by_type[NALU_TYPE_DP_B_SLICE] = "DP B slice";
|
||||
m_nalu_names_by_type[NALU_TYPE_DP_C_SLICE] = "DP C slice";
|
||||
m_nalu_names_by_type[NALU_TYPE_IDR_SLICE] = "IDR slice";
|
||||
m_nalu_names_by_type[NALU_TYPE_SEI] = "SEI";
|
||||
m_nalu_names_by_type[NALU_TYPE_SEQ_PARAM] = "SEQ param";
|
||||
m_nalu_names_by_type[NALU_TYPE_PIC_PARAM] = "PIC param";
|
||||
m_nalu_names_by_type[NALU_TYPE_ACCESS_UNIT] = "access unit";
|
||||
m_nalu_names_by_type[NALU_TYPE_END_OF_SEQ] = "end of sequence";
|
||||
m_nalu_names_by_type[NALU_TYPE_END_OF_STREAM] = "end of stream";
|
||||
m_nalu_names_by_type[NALU_TYPE_FILLER_DATA] = "filler";
|
||||
if (!ms_nalu_names_by_type.empty())
|
||||
return;
|
||||
|
||||
ms_nalu_names_by_type[NALU_TYPE_NON_IDR_SLICE] = "non IDR slice";
|
||||
ms_nalu_names_by_type[NALU_TYPE_DP_A_SLICE] = "DP A slice";
|
||||
ms_nalu_names_by_type[NALU_TYPE_DP_B_SLICE] = "DP B slice";
|
||||
ms_nalu_names_by_type[NALU_TYPE_DP_C_SLICE] = "DP C slice";
|
||||
ms_nalu_names_by_type[NALU_TYPE_IDR_SLICE] = "IDR slice";
|
||||
ms_nalu_names_by_type[NALU_TYPE_SEI] = "SEI";
|
||||
ms_nalu_names_by_type[NALU_TYPE_SEQ_PARAM] = "SEQ param";
|
||||
ms_nalu_names_by_type[NALU_TYPE_PIC_PARAM] = "PIC param";
|
||||
ms_nalu_names_by_type[NALU_TYPE_ACCESS_UNIT] = "access unit";
|
||||
ms_nalu_names_by_type[NALU_TYPE_END_OF_SEQ] = "end of sequence";
|
||||
ms_nalu_names_by_type[NALU_TYPE_END_OF_STREAM] = "end of stream";
|
||||
ms_nalu_names_by_type[NALU_TYPE_FILLER_DATA] = "filler";
|
||||
}
|
||||
|
||||
}}
|
||||
|
@ -106,14 +106,15 @@ protected:
|
||||
bool m_ignore_nalu_size_length_errors, m_discard_actual_frames, m_simple_picture_order, m_first_cleanup, m_all_i_slices_are_key_frames;
|
||||
|
||||
debugging_option_c m_debug_keyframe_detection, m_debug_nalu_types, m_debug_timestamps, m_debug_sps_info, m_debug_sps_pps_changes;
|
||||
std::map<int, std::string> m_nalu_names_by_type;
|
||||
static std::map<int, std::string> ms_nalu_names_by_type;
|
||||
|
||||
struct stats_t {
|
||||
std::vector<int> num_slices_by_type;
|
||||
std::vector<int> num_slices_by_type, num_nalus_by_type;
|
||||
size_t num_frames_out{}, num_frames_discarded{}, num_timestamps_in{}, num_timestamps_generated{}, num_timestamps_discarded{}, num_field_slices{}, num_frame_slices{}, num_sei_nalus{}, num_idr_slices{};
|
||||
|
||||
stats_t()
|
||||
: num_slices_by_type(11, 0)
|
||||
, num_nalus_by_type(13, 0)
|
||||
{
|
||||
}
|
||||
} m_stats;
|
||||
@ -213,7 +214,7 @@ public:
|
||||
|
||||
void dump_info() const;
|
||||
|
||||
std::string get_nalu_type_name(int type) const;
|
||||
std::string get_nalu_type_name(int type);
|
||||
|
||||
bool has_stream_default_duration() const {
|
||||
return -1 != m_stream_default_duration;
|
||||
|
Loading…
Reference in New Issue
Block a user