97 static GstFlowReturn onNewSample(GstAppSink *appsink, gpointer userData);
101 static GstPadProbeReturn appsinkBufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer userData);
103 void _logFrameStats() const;
105 quint64 _deliveredFrames() const noexcept;
108 void _pushQosUpstream(GstAppSink *appsink, GstBuffer *buffer);
110 void _refreshLatency();
114 void _deliverFrame(QPointer<QVideoSink> sink, QVideoFrame &&frame, int64_t ptsNs);
117 void _onSmoothingTick();
119 QTimer _telemetryEmitTimer;
122 mutable QMutex _stateMutex;
124 QPointer<QVideoSink> _videoSink;
128 GstPad *_appsinkProbePad =
nullptr;
129 gulong _appsinkProbeId = 0;
130 std::atomic<quint64> _appsinkInputFrames{0};
135 std::atomic<bool> _flushing{
false};
138 std::atomic<bool> _active{
true};
143 std::atomic<int> _streamOrientation{
static_cast<int>(GST_VIDEO_ORIENTATION_IDENTITY)};
146 std::atomic<quint64> _refreshPeriodNs{0};
150 static constexpr int kSmoothingRingCapacity = 3;
151 static constexpr int64_t kSmoothingThresholdNs = 70 * 1000000;
152 struct SmoothingEntry {
157 std::atomic<bool> _smoothingEnabled{
false};
158 mutable QMutex _smoothingMutex;
159 QList<SmoothingEntry> _smoothingRing;
160 QTimer _smoothingTickTimer;
161 QElapsedTimer _smoothingClock;
162 int64_t _smoothingFirstPtsNs = -1;
163 qint64 _smoothingFirstClockNs = 0;
164 std::atomic<quint64> _smoothingDroppedFrames{0};
166 std::atomic<int64_t> _lastDeliveredPtsNs{-1};
169 GstCaps *_cachedCapsKey =
nullptr;
170 GstVideoInfo _cachedInfo{};
171 QVideoFrameFormat _cachedFormat;
172 int _cachedPixelFormat = 0;
173 QString _cachedAllocatorName;
177 mutable std::atomic<qint64> _lastStatsAtNs{0};
178 mutable std::atomic<quint64> _lastStatsTotal{0};
182 quint64 _lastEmittedFrameTotal = 0;
185 std::atomic<GstVideoFormat> _lastWarnedFormat{GST_VIDEO_FORMAT_UNKNOWN};
189 std::atomic<quint64> _cpuFrames{0};
191#if defined(QGC_HAS_ANY_GPU_PATH)
192 bool _gpuPathEnabled =
false;
194#if defined(QGC_HAS_GST_DMABUF_GPU_PATH)
197 EGLDisplay _eglDisplay = EGL_NO_DISPLAY;
198 std::atomic<quint64> _gpuFrames{0};
200#if defined(QGC_HAS_GST_GLMEMORY_GPU_PATH)
201 std::atomic<quint64> _glFrames{0};
203#if defined(QGC_HAS_GST_D3D11_GPU_PATH)
204 std::atomic<quint64> _d3d11Frames{0};
206#if defined(QGC_HAS_GST_D3D12_GPU_PATH)
207 std::atomic<quint64> _d3d12Frames{0};
209#if defined(QGC_HAS_GST_IOSURFACE_GPU_PATH)
210 std::atomic<quint64> _iosurfaceFrames{0};
212#if defined(QGC_HAS_GST_AHARDWAREBUFFER_GPU_PATH)
213 EGLDisplay _ahwbEglDisplay = EGL_NO_DISPLAY;
214 std::atomic<quint64> _ahwbFrames{0};
218 bool _qosUpstreamEnabled =
true;
220 quint64 _qosSampleCount = 0;
222 double _qosAvgRate = 1.0;
223 GstClockTime _qosLastPts = GST_CLOCK_TIME_NONE;
224 GstClockTime _qosLastArrivalNs = 0;
225 static constexpr quint64 kQosWarmup = 10;
226 static constexpr int kQosInterval = 8;
229 GstClockTime _pipelineMinLatencyNs = 0;
230 bool _latencyValid =
false;
231 std::atomic<bool> _latencyRefreshPending{
false};
232 static constexpr quint64 kLatencyRefreshInterval = 256;