@@ -63,26 +63,61 @@ void SnapshotManager::convert(uint64_t seqnum, QVideoFrame frame, WallClock time
6363 m_converted_snapshot = std::move (snapshot);
6464 }
6565
66- // if (timestamp > m_converted_snapshot.timestamp){
67- // }
6866 m_active_conversions--;
69- // m_pending_conversions.erase(seqnum);
7067 m_cv.notify_all ();
7168}
72- void SnapshotManager::dispatch_conversion (uint64_t seqnum, QVideoFrame frame, WallClock timestamp){
69+ bool SnapshotManager::try_dispatch_conversion (uint64_t seqnum, QVideoFrame frame, WallClock timestamp) noexcept {
7370 // Must call under the lock.
74- std::function<void ()> lambda = [=, this , frame = std::move (frame)](){
75- convert (seqnum, std::move (frame), timestamp);
76- };
77-
78- auto task = GlobalThreadPools::realtime_inference ().try_dispatch (lambda);
79- if (task){
80- // cout << "dispatch_conversion: Success..." << endl;
81- m_converting_seqnum = seqnum;
82- m_pending_conversions[seqnum] = std::move (task);
83- }else {
84- // cout << "dispatch_conversion: Failed..." << endl;
71+
72+ std::unique_ptr<AsyncTask>* task;
73+ try {
74+ task = &m_pending_conversions[seqnum];
75+
76+ // This frame is already being converted.
77+ if (*task){
78+ return false ;
79+ }
80+ }catch (...){
81+ return false ;
82+ }
83+
84+ try {
85+ std::function<void ()> lambda = [=, this , frame = std::move (frame)](){
86+ convert (seqnum, std::move (frame), timestamp);
87+
88+ std::lock_guard<std::mutex> lg (m_lock);
89+ if (m_queued_convert){
90+ m_queued_convert = false ;
91+ QVideoFrame frame;
92+ WallClock timestamp;
93+ uint64_t seqnum = m_cache.get_latest (frame, timestamp);
94+ if (m_converting_seqnum < seqnum){
95+ dispatch_conversion (seqnum, std::move (frame), timestamp);
96+ }
97+ }
98+ };
99+
100+ *task = GlobalThreadPools::realtime_inference ().try_dispatch (lambda);
101+
102+ // Dispatch was successful. We're done.
103+ if (*task){
104+ return true ;
105+ }
106+
107+ // Dispatch failed. Queue it for later.
85108 m_queued_convert = true ;
109+ }catch (...){
110+ m_pending_conversions.erase (seqnum);
111+ }
112+
113+ return false ;
114+ }
115+ void SnapshotManager::dispatch_conversion (uint64_t seqnum, QVideoFrame frame, WallClock timestamp) noexcept {
116+ // Must call under the lock.
117+ m_active_conversions++;
118+
119+ if (!try_dispatch_conversion (seqnum, std::move (frame), timestamp)){
120+ m_active_conversions--;
86121 }
87122
88123 // Cleanup finished tasks.
@@ -179,13 +214,7 @@ VideoSnapshot SnapshotManager::snapshot_recent_nonblocking(){
179214 // Dispatch this frame for conversion.
180215 if (m_converting_seqnum < seqnum){
181216// cout << "snapshot_recent_nonblocking(): Dispatching..." << endl;
182- try {
183- m_active_conversions++;
184- dispatch_conversion (seqnum, std::move (frame), timestamp);
185- }catch (...){
186- m_active_conversions--;
187- throw ;
188- }
217+ dispatch_conversion (seqnum, std::move (frame), timestamp);
189218 }
190219
191220 // Cached snapshot isn't too old. Return it.
0 commit comments