Skip to content

Commit 4dc88ba

Browse files
committed
Frames queue implemented
1 parent 5aabca4 commit 4dc88ba

File tree

4 files changed

+111
-18
lines changed

4 files changed

+111
-18
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//
2+
// DiscoverManager.cpp
3+
// Moonlight
4+
//
5+
// Created by XITRIX on 31.03.2025.
6+
//
7+
8+
#include "AVFrameHolder.hpp"
9+
10+
AVFrameQueue::AVFrameQueue(size_t limit): limit(limit) {}
11+
12+
AVFrameQueue::~AVFrameQueue() {
13+
for (; !queue.empty(); queue.pop()) {
14+
AVFrame* frame = queue.front();
15+
av_frame_free(&frame);
16+
}
17+
18+
for (; !freeQueue.empty(); freeQueue.pop()) {
19+
AVFrame* frame = freeQueue.front();
20+
av_frame_free(&frame);
21+
}
22+
}
23+
24+
void AVFrameQueue::push(AVFrame* item) {
25+
std::lock_guard<std::mutex> lock(m_mutex);
26+
queue.push(item);
27+
28+
if (queue.size() > limit)
29+
queue.pop();
30+
}
31+
32+
AVFrame* AVFrameQueue::pop() {
33+
std::lock_guard<std::mutex> lock(m_mutex);
34+
35+
if (!queue.empty()) {
36+
AVFrame* item = queue.front();
37+
queue.pop();
38+
bufferFrame = item;
39+
} else {
40+
fakeFrameUsedStat ++;
41+
}
42+
43+
return bufferFrame;
44+
}
45+
46+
size_t AVFrameQueue::size() const {
47+
return queue.size();
48+
}
49+
50+
size_t AVFrameQueue::getFakeFrameUsage() const {
51+
return fakeFrameUsedStat;
52+
}
53+
54+
void AVFrameQueue::cleanup() {
55+
std::lock_guard<std::mutex> lock(m_mutex);
56+
fakeFrameUsedStat = 0;
57+
bufferFrame = nullptr;
58+
queue = {};
59+
}
Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,64 @@
1+
#pragma once
2+
13
#include "Singleton.hpp"
24
#include <mutex>
35
#include <functional>
6+
#include <queue>
47

58
extern "C" {
69
#include <libavcodec/avcodec.h>
710
}
811

9-
#pragma once
12+
#define m_frames_count 4
13+
14+
class AVFrameQueue {
15+
public:
16+
explicit AVFrameQueue(size_t limit = m_frames_count - 1);
17+
~AVFrameQueue();
18+
19+
void push(AVFrame* item);
20+
AVFrame* pop();
21+
22+
[[nodiscard]] size_t size() const;
23+
[[nodiscard]] size_t getFakeFrameUsage() const;
24+
25+
void cleanup();
26+
27+
private:
28+
size_t limit;
29+
std::queue<AVFrame*> queue;
30+
std::queue<AVFrame*> freeQueue;
31+
AVFrame* bufferFrame = nullptr;
32+
std::mutex m_mutex;
33+
size_t fakeFrameUsedStat = 0;
34+
};
1035

1136
class AVFrameHolder : public Singleton<AVFrameHolder> {
1237
public:
1338
void push(AVFrame* frame) {
14-
std::lock_guard<std::mutex> lock(m_mutex);
15-
16-
m_frame = frame;
39+
m_frame_queue.push(frame);
40+
stat ++;
1741
}
1842

19-
void get(const std::function<void(AVFrame*)> fn) {
20-
std::lock_guard<std::mutex> lock(m_mutex);
43+
void get(const std::function<void(AVFrame*)>& fn) {
44+
auto frame = m_frame_queue.pop();
2145

22-
if (m_frame) {
23-
fn(m_frame);
46+
if (frame) {
47+
fn(frame);
48+
stat --;
2449
}
2550
}
2651

2752
void cleanup() {
28-
std::lock_guard<std::mutex> lock(m_mutex);
29-
30-
m_frame = nullptr;
53+
m_frame_queue.cleanup();
54+
stat = 0;
3155
}
3256

57+
[[nodiscard]] int getStat() const { return stat; }
58+
[[nodiscard]] size_t getFakeFrameStat() const { return m_frame_queue.getFakeFrameUsage(); }
59+
[[nodiscard]] size_t getFrameQueueSize() const { return m_frame_queue.size(); }
60+
3361
private:
34-
std::mutex m_mutex;
35-
AVFrame* m_frame = nullptr;
62+
AVFrameQueue m_frame_queue;
63+
int stat = 0;
3664
};

app/src/streaming/ffmpeg/FFmpegVideoDecoder.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
#include "IFFmpegVideoDecoder.hpp"
21
#pragma once
3-
4-
#define m_frames_count 2
2+
#include "IFFmpegVideoDecoder.hpp"
3+
#include "AVFrameHolder.hpp"
54

65
class FFmpegVideoDecoder : public IFFmpegVideoDecoder {
76
public:

app/src/streaming_view.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#endif
1111

1212
#include "streaming_view.hpp"
13+
#include "AVFrameHolder.hpp"
1314
#include "InputManager.hpp"
1415
#include "click_gesture_recognizer.hpp"
1516
#include "helper.hpp"
@@ -331,13 +332,19 @@ void StreamingView::draw(NVGcontext* vg, float x, float y, float width,
331332
statistics += fmt::format("Frames dropped by your network connection: {}\n"
332333
"Average receive time: {:.{}f} | {:.{}f} ms\n"
333334
"Average decoding time: {:.{}f} | {:.{}f} ms\n"
334-
"Average rendering time: {:.{}f} ms\n",
335+
"Average rendering time: {:.{}f} ms\n"
336+
"Frame holder push/get rate: {}\n"
337+
"Fake frames produced: {}\n"
338+
"Frames queue: {}",
335339
stats->video_decode_stats.network_dropped_frames,
336340
stats->video_decode_stats.current_receive_time, 2,
337341
stats->video_decode_stats.session_receive_time, 2,
338342
stats->video_decode_stats.current_decoding_time, 2,
339343
stats->video_decode_stats.session_decoding_time, 2,
340-
stats->video_render_stats.rendering_time, 2);
344+
stats->video_render_stats.rendering_time, 2,
345+
AVFrameHolder::instance().getStat(),
346+
AVFrameHolder::instance().getFakeFrameStat(),
347+
AVFrameHolder::instance().getFrameQueueSize());
341348

342349
nvgFontFaceId(vg, Application::getFont(FONT_REGULAR));
343350
nvgFontSize(vg, 20);

0 commit comments

Comments
 (0)