From 2ef8fd6187a097a74ec7026975f79c1aa91ab74c Mon Sep 17 00:00:00 2001 From: Jean Christophe DE RYCK Date: Mon, 6 Jan 2020 19:52:57 +0200 Subject: [PATCH] FPS info read from VPS and SPS fps info can be either in VPS or SPS nal, or both, or none. tsMuxer reads fps from VPS nal only. This patch allows tsMuxer to find fps in SPS when not present in VPS. Plus bug sorted out in flags reading (8 bits in lieu of 1 bit) --- tsMuxer/hevc.cpp | 16 +++++++++------- tsMuxer/hevc.h | 2 +- tsMuxer/hevcStreamReader.cpp | 14 ++++++++++---- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/tsMuxer/hevc.cpp b/tsMuxer/hevc.cpp index 38ecc50..7cc7bc6 100644 --- a/tsMuxer/hevc.cpp +++ b/tsMuxer/hevc.cpp @@ -237,10 +237,7 @@ void HevcVpsUnit::setFPS(double fps) double HevcVpsUnit::getFPS() const { - if (num_units_in_tick != 0) - return time_scale/(float)num_units_in_tick; - else - return 0; + return num_units_in_tick ? time_scale / (float)num_units_in_tick : 0; } string HevcVpsUnit::getDescription() const @@ -372,9 +369,9 @@ void HevcSpsUnit::vui_parameters() extractUEGolombCode(); // chroma_sample_loc_type_bottom_field ue(v) } - m_reader.skipBits(8); // neutral_chroma_indication_flag u(1) - m_reader.skipBits(8); // field_seq_flag u(1) - m_reader.skipBits(8); // frame_field_info_present_flag u(1) + m_reader.skipBit(); // neutral_chroma_indication_flag u(1) + m_reader.skipBit(); // field_seq_flag u(1) + m_reader.skipBit(); // frame_field_info_present_flag u(1) bool default_display_window_flag = m_reader.getBit(); if( default_display_window_flag ) { extractUEGolombCode(); // def_disp_win_left_offset ue(v) @@ -767,6 +764,11 @@ int HevcSpsUnit::deserialize() } } +double HevcSpsUnit::getFPS() const +{ + return num_units_in_tick ? time_scale / (float)num_units_in_tick : 0; +} + string HevcSpsUnit::getDescription() const { string result = getProfileString(); diff --git a/tsMuxer/hevc.h b/tsMuxer/hevc.h index b200492..8c3c9e6 100644 --- a/tsMuxer/hevc.h +++ b/tsMuxer/hevc.h @@ -121,7 +121,7 @@ struct HevcSpsUnit: public HevcUnitWithProfile { HevcSpsUnit(); int deserialize() override; - + double getFPS() const; std::string getDescription() const; public: int vps_id; diff --git a/tsMuxer/hevcStreamReader.cpp b/tsMuxer/hevcStreamReader.cpp index 672dbd2..ff6f59d 100644 --- a/tsMuxer/hevcStreamReader.cpp +++ b/tsMuxer/hevcStreamReader.cpp @@ -60,7 +60,8 @@ CheckStreamRez HEVCStreamReader::checkStream(uint8_t* buffer, int len) m_vps->decodeBuffer(nal, nextNal); if (m_vps->deserialize()) return rez; - updateFPS(m_vps, nal, nextNal, 0); + m_spsPpsFound = true; + if (m_vps->num_units_in_tick) updateFPS(m_vps, nal, nextNal, 0); break; } case NAL_SPS: { @@ -69,6 +70,8 @@ CheckStreamRez HEVCStreamReader::checkStream(uint8_t* buffer, int len) m_sps->decodeBuffer(nal, nextNal); if (m_sps->deserialize() != 0) return rez; + m_spsPpsFound = true; + updateFPS(m_sps, nal, nextNal, 0); break; } case NAL_PPS: { @@ -171,8 +174,10 @@ int HEVCStreamReader::getStreamHDR() const double HEVCStreamReader::getStreamFPS(void * curNalUnit) { - HevcVpsUnit* vps = (HevcVpsUnit*) curNalUnit; - return vps->getFPS(); + double fps = 0; + if (m_vps) fps = m_vps->getFPS(); + if (fps == 0 && m_sps) fps = m_sps->getFPS(); + return fps; } bool HEVCStreamReader::isSlice(int nalType) const @@ -302,7 +307,7 @@ int HEVCStreamReader::intDecodeNAL(uint8_t* buff) m_spsPpsFound = true; m_vpsCounter++; m_vpsSizeDiff = 0; - updateFPS(m_vps, curPos, nextNalWithStartCode, 0); + if (m_vps->num_units_in_tick) updateFPS(m_vps, curPos, nextNalWithStartCode, 0); nextNal += m_vpsSizeDiff; storeBuffer(m_vpsBuffer, curPos, nextNalWithStartCode); break; @@ -314,6 +319,7 @@ int HEVCStreamReader::intDecodeNAL(uint8_t* buff) if (rez) return rez; m_spsPpsFound = true; + updateFPS(m_sps, curPos, nextNalWithStartCode, 0); storeBuffer(m_spsBuffer, curPos, nextNalWithStartCode); break; case NAL_PPS: