Skip to content

Commit e2ebfdf

Browse files
committed
Misc. profiling to help debug poor UI perf with 4 videos.
1 parent 3e04ec3 commit e2ebfdf

File tree

7 files changed

+94
-22
lines changed

7 files changed

+94
-22
lines changed

SerialPrograms/Source/CommonFramework/VideoPipeline/Backends/CameraWidgetQt6.5.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,9 @@ CameraVideoSource::CameraVideoSource(
9191
const CameraInfo& info,
9292
Resolution desired_resolution
9393
)
94-
: VideoSource(true)
94+
: VideoSource(logger, true)
9595
, m_logger(logger)
96+
, m_last_frame(logger)
9697
, m_snapshot_manager(logger, m_last_frame)
9798
{
9899
if (!info){

SerialPrograms/Source/CommonFramework/VideoPipeline/Backends/CameraWidgetQt6.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,9 @@ CameraVideoSource::CameraVideoSource(
8484
const CameraInfo& info,
8585
Resolution desired_resolution
8686
)
87-
: VideoSource(true)
87+
: VideoSource(logger, true)
8888
, m_logger(logger)
89+
, m_last_frame(logger)
8990
, m_snapshot_manager(logger, m_last_frame)
9091
{
9192
if (!info){

SerialPrograms/Source/CommonFramework/VideoPipeline/Backends/QVideoFrameCache.h

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,52 +12,93 @@
1212
#include <QVideoFrame>
1313
#include "Common/Cpp/Time.h"
1414
#include "Common/Cpp/Concurrency/SpinLock.h"
15+
#include "CommonFramework/Tools/StatAccumulator.h"
16+
17+
//#define PA_PROFILE_QVideoFrameCache
1518

1619
namespace PokemonAutomation{
1720

1821

1922

2023
class QVideoFrameCache{
2124
public:
22-
QVideoFrameCache()
25+
QVideoFrameCache(Logger& logger)
26+
#ifdef PA_PROFILE_QVideoFrameCache
27+
: m_logger(logger)
28+
, m_last_frame_timestamp(WallClock::min())
29+
#else
2330
: m_last_frame_timestamp(WallClock::min())
31+
#endif
2432
, m_last_frame_seqnum(0)
33+
#ifdef PA_PROFILE_QVideoFrameCache
34+
, m_stats_lock("QVideoFrameCache::push_frame()-Lock", "ms", 1000, std::chrono::seconds(10))
35+
, m_stats_push_frame("QVideoFrameCache::push_frame()-All", "ms", 1000, std::chrono::seconds(10))
36+
#endif
2537
{}
2638

2739
uint64_t seqnum() const{
2840
return m_last_frame_seqnum.load(std::memory_order_relaxed);
2941
}
3042
uint64_t get_latest(QVideoFrame& frame, WallClock& timestamp) const{
31-
WriteSpinLock lg(m_frame_lock);
43+
WriteSpinLock lg(m_frame_lock, "QVideoFrameCache::get_latest()");
3244
frame = m_last_frame;
3345
timestamp = m_last_frame_timestamp;
3446
return seqnum();
3547
}
3648

3749
bool push_frame(QVideoFrame frame, WallClock timestamp){
38-
WriteSpinLock lg(m_frame_lock);
50+
#ifdef PA_PROFILE_QVideoFrameCache
51+
WallClock time0 = current_time();
52+
#endif
53+
54+
WriteSpinLock lg(m_frame_lock, "QVideoFrameCache::push_frame()");
55+
56+
#ifdef PA_PROFILE_QVideoFrameCache
57+
{
58+
WallClock time1 = current_time();
59+
uint32_t microseconds = (uint32_t)std::chrono::duration_cast<std::chrono::microseconds>(time1 - time0).count();
60+
m_stats_lock.report_data(m_logger, microseconds);
61+
}
62+
#endif
3963

4064
// Skip duplicate frames.
4165
if (frame.startTime() != -1 && frame.startTime() <= m_last_frame.startTime()){
4266
return false;
4367
}
4468

45-
m_last_frame = frame;
69+
m_last_frame = std::move(frame);
4670
m_last_frame_timestamp = timestamp;
4771
uint64_t seqnum = m_last_frame_seqnum.load(std::memory_order_relaxed);
4872
seqnum++;
4973
m_last_frame_seqnum.store(seqnum, std::memory_order_relaxed);
5074

75+
#ifdef PA_PROFILE_QVideoFrameCache
76+
{
77+
WallClock time1 = current_time();
78+
uint32_t microseconds = (uint32_t)std::chrono::duration_cast<std::chrono::microseconds>(time1 - time0).count();
79+
m_stats_push_frame.report_data(m_logger, microseconds);
80+
}
81+
#endif
82+
5183
return true;
5284
}
5385

5486

5587
private:
88+
#ifdef PA_PROFILE_QVideoFrameCache
89+
Logger& m_logger;
90+
#endif
91+
5692
mutable SpinLock m_frame_lock;
5793

5894
QVideoFrame m_last_frame;
5995
WallClock m_last_frame_timestamp;
6096
std::atomic<uint64_t> m_last_frame_seqnum;
97+
98+
#ifdef PA_PROFILE_QVideoFrameCache
99+
PeriodicStatsReporterI32 m_stats_lock;
100+
PeriodicStatsReporterI32 m_stats_push_frame;
101+
#endif
61102
};
62103

63104

SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSource.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,33 @@
99
namespace PokemonAutomation{
1010

1111

12+
13+
VideoSource::VideoSource(Logger& m_logger, bool allow_watchdog_reset)
14+
: m_logger(m_logger)
15+
, m_allow_watchdog_reset(allow_watchdog_reset)
16+
, m_stats_report_source_frame("VideoSource::report_source_frame()", "ms", 1000, std::chrono::seconds(60))
17+
, m_stats_report_rendered_frame("VideoSource::report_rendered_frame()", "ms", 1000, std::chrono::seconds(60))
18+
, m_sanitizer("VideoSource")
19+
{}
20+
21+
22+
void VideoSource::report_source_frame(std::shared_ptr<const VideoFrame> frame){
23+
auto scope_check = m_sanitizer.check_scope();
24+
WallClock time0 = current_time();
25+
m_source_frame_listeners.run_method_unique(&VideoFrameListener::on_frame, frame);
26+
WallClock time1 = current_time();
27+
auto microseconds = (uint32_t)std::chrono::duration_cast<std::chrono::microseconds>(time1 - time0).count();
28+
m_stats_report_source_frame.report_data(m_logger, microseconds);
29+
}
30+
void VideoSource::report_rendered_frame(WallClock timestamp){
31+
auto scope_check = m_sanitizer.check_scope();
32+
WallClock time0 = current_time();
33+
m_rendered_frame_listeners.run_method_unique(&RenderedFrameListener::on_rendered_frame, timestamp);
34+
WallClock time1 = current_time();
35+
auto microseconds = (uint32_t)std::chrono::duration_cast<std::chrono::microseconds>(time1 - time0).count();
36+
m_stats_report_rendered_frame.report_data(m_logger, microseconds);
37+
}
38+
39+
40+
1241
}

SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSource.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "Common/Cpp/ImageResolution.h"
1313
#include "Common/Cpp/ListenerSet.h"
1414
#include "CommonFramework/VideoPipeline/VideoFeed.h"
15+
#include "CommonFramework/Tools/StatAccumulator.h"
1516

1617
class QWidget;
1718

@@ -45,10 +46,7 @@ class VideoSource{
4546

4647

4748
public:
48-
VideoSource(bool allow_watchdog_reset)
49-
: m_allow_watchdog_reset(allow_watchdog_reset)
50-
, m_sanitizer("VideoSource")
51-
{}
49+
VideoSource(Logger& m_logger, bool allow_watchdog_reset);
5250
virtual ~VideoSource() = default;
5351

5452

@@ -65,27 +63,29 @@ class VideoSource{
6563

6664

6765
protected:
68-
void report_source_frame(std::shared_ptr<const VideoFrame> frame){
69-
auto scope_check = m_sanitizer.check_scope();
70-
m_source_frame_listeners.run_method_unique(&VideoFrameListener::on_frame, frame);
71-
}
66+
// These are not thread-safe.
67+
68+
void report_source_frame(std::shared_ptr<const VideoFrame> frame);
69+
7270
// Called by UI to report a frame is rendered
73-
void report_rendered_frame(WallClock timestamp){
74-
auto scope_check = m_sanitizer.check_scope();
75-
m_rendered_frame_listeners.run_method_unique(&RenderedFrameListener::on_rendered_frame, timestamp);
76-
}
71+
void report_rendered_frame(WallClock timestamp);
7772

7873

7974
public:
8075
virtual QWidget* make_display_QtWidget(QWidget* parent) = 0;
8176

8277

8378
private:
79+
Logger& m_logger;
80+
8481
ListenerSet<VideoFrameListener> m_source_frame_listeners;
8582
ListenerSet<RenderedFrameListener> m_rendered_frame_listeners;
8683

8784
const bool m_allow_watchdog_reset;
8885

86+
PeriodicStatsReporterI32 m_stats_report_source_frame;
87+
PeriodicStatsReporterI32 m_stats_report_rendered_frame;
88+
8989
LifetimeSanitizer m_sanitizer;
9090
};
9191

SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSources/VideoSource_StillImage.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,15 @@ JsonValue VideoSourceDescriptor_StillImage::to_json() const{
6161

6262
std::unique_ptr<VideoSource> VideoSourceDescriptor_StillImage::make_VideoSource(Logger& logger, Resolution resolution) const{
6363
// cout << "make_VideoSource: " << m_path << endl;
64-
return std::make_unique<VideoSource_StillImage>(path(), resolution);
64+
return std::make_unique<VideoSource_StillImage>(logger, path(), resolution);
6565
}
6666

6767

6868

6969

7070

71-
VideoSource_StillImage::VideoSource_StillImage(const std::string& path, Resolution resolution)
72-
: VideoSource(false)
71+
VideoSource_StillImage::VideoSource_StillImage(Logger& logger, const std::string& path, Resolution resolution)
72+
: VideoSource(logger, false)
7373
, m_original_image(QString::fromStdString(path))
7474
{
7575
m_snapshot = VideoSnapshot(

SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSources/VideoSource_StillImage.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class VideoSourceDescriptor_StillImage : public VideoSourceDescriptor{
5252

5353
class VideoSource_StillImage : public VideoSource{
5454
public:
55-
VideoSource_StillImage(const std::string& path, Resolution resolution);
55+
VideoSource_StillImage(Logger& logger, const std::string& path, Resolution resolution);
5656

5757
const std::string path() const{
5858
return m_path;

0 commit comments

Comments
 (0)