diff --git a/server/WebApi.cpp b/server/WebApi.cpp index dc50b2ed..887b1736 100755 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -378,8 +378,16 @@ Value makeMediaSourceJson(MediaSource &media){ auto video_track = dynamic_pointer_cast(track); obj["width"] = video_track->getVideoWidth(); obj["height"] = video_track->getVideoHeight(); - obj["fps"] = round(video_track->getVideoFps()); obj["key_frames"] = video_track->getVideoKeyFrames(); + int gop_size = video_track->getVideoGopSize(); + int gop_interval_ms = video_track->getVideoGopInterval(); + float fps = video_track->getVideoFps(); + if (fps <= 1) { + fps = gop_size * 1000.0 / gop_interval_ms; + } + obj["fps"] = round(fps); + obj["gop_size"] = gop_size; + obj["gop_interval_ms"] = gop_interval_ms; break; } default: diff --git a/src/Extension/Frame.h b/src/Extension/Frame.h index 2ba0c94e..4328e544 100644 --- a/src/Extension/Frame.h +++ b/src/Extension/Frame.h @@ -15,6 +15,7 @@ #include #include #include "Util/List.h" +#include "Util/TimeTicker.h" #include "Network/Buffer.h" namespace mediakit { @@ -311,10 +312,7 @@ public: */ bool inputFrame(const Frame::Ptr &frame) override { std::lock_guard lck(_mtx); - ++_frames; - if (frame->keyFrame() && frame->getTrackType() == TrackVideo) { - ++_video_key_frames; - } + doStatistics(frame); bool ret = false; for (auto &pr : _delegates) { if (pr.second->inputFrame(frame)) { @@ -353,7 +351,37 @@ public: return _frames; } + size_t getVideoGopSize() const { + std::lock_guard lck(_mtx); + return _gop_size; + } + + size_t getVideoGopInterval() const { + std::lock_guard lck(_mtx); + return _gop_interval_ms; + } + private: + void doStatistics(const Frame::Ptr &frame) { + if (!frame->configFrame() && !frame->dropAble()) { + // 忽略配置帧与可丢弃的帧 + ++_frames; + if (frame->keyFrame() && frame->getTrackType() == TrackVideo) { + // 遇视频关键帧时统计 + ++_video_key_frames; + _gop_size = _frames - _last_frames; + _gop_interval_ms = _ticker.elapsedTime(); + _last_frames = _frames; + _ticker.resetTime(); + } + } + } + +private: + toolkit::Ticker _ticker; + size_t _gop_interval_ms = 0; + size_t _gop_size = 0; + uint64_t _last_frames = 0; uint64_t _frames = 0; uint64_t _video_key_frames = 0; mutable std::recursive_mutex _mtx;