Skip to content

Commit c9cc500

Browse files
committed
Move frame buffer size from constant into config
1 parent 4dc88ba commit c9cc500

File tree

7 files changed

+59
-22
lines changed

7 files changed

+59
-22
lines changed

app/src/streaming/AVFrameHolder.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#include "AVFrameHolder.hpp"
99

10-
AVFrameQueue::AVFrameQueue(size_t limit): limit(limit) {}
10+
AVFrameQueue::AVFrameQueue() {}
1111

1212
AVFrameQueue::~AVFrameQueue() {
1313
for (; !queue.empty(); queue.pop()) {
@@ -25,8 +25,10 @@ void AVFrameQueue::push(AVFrame* item) {
2525
std::lock_guard<std::mutex> lock(m_mutex);
2626
queue.push(item);
2727

28-
if (queue.size() > limit)
28+
if (queue.size() > limit) {
2929
queue.pop();
30+
framesDroppedStat ++;
31+
}
3032
}
3133

3234
AVFrame* AVFrameQueue::pop() {
@@ -51,9 +53,14 @@ size_t AVFrameQueue::getFakeFrameUsage() const {
5153
return fakeFrameUsedStat;
5254
}
5355

56+
size_t AVFrameQueue::getFramesDropStat() const {
57+
return framesDroppedStat;
58+
}
59+
5460
void AVFrameQueue::cleanup() {
5561
std::lock_guard<std::mutex> lock(m_mutex);
5662
fakeFrameUsedStat = 0;
63+
framesDroppedStat = 0;
5764
bufferFrame = nullptr;
5865
queue = {};
5966
}

app/src/streaming/AVFrameHolder.hpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,35 @@
44
#include <mutex>
55
#include <functional>
66
#include <queue>
7+
#include "Settings.hpp"
78

89
extern "C" {
910
#include <libavcodec/avcodec.h>
1011
}
1112

12-
#define m_frames_count 4
13-
1413
class AVFrameQueue {
1514
public:
16-
explicit AVFrameQueue(size_t limit = m_frames_count - 1);
15+
explicit AVFrameQueue();
1716
~AVFrameQueue();
1817

1918
void push(AVFrame* item);
2019
AVFrame* pop();
2120

2221
[[nodiscard]] size_t size() const;
2322
[[nodiscard]] size_t getFakeFrameUsage() const;
23+
[[nodiscard]] size_t getFramesDropStat() const;
2424

2525
void cleanup();
2626

2727
private:
28+
friend class AVFrameHolder;
2829
size_t limit;
2930
std::queue<AVFrame*> queue;
3031
std::queue<AVFrame*> freeQueue;
3132
AVFrame* bufferFrame = nullptr;
3233
std::mutex m_mutex;
3334
size_t fakeFrameUsedStat = 0;
35+
size_t framesDroppedStat = 0;
3436
};
3537

3638
class AVFrameHolder : public Singleton<AVFrameHolder> {
@@ -49,13 +51,18 @@ class AVFrameHolder : public Singleton<AVFrameHolder> {
4951
}
5052
}
5153

54+
void prepare() {
55+
m_frame_queue.limit = Settings::instance().frames_queue_size();
56+
}
57+
5258
void cleanup() {
5359
m_frame_queue.cleanup();
5460
stat = 0;
5561
}
5662

5763
[[nodiscard]] int getStat() const { return stat; }
5864
[[nodiscard]] size_t getFakeFrameStat() const { return m_frame_queue.getFakeFrameUsage(); }
65+
[[nodiscard]] size_t getFrameDropStat() const { return m_frame_queue.getFramesDropStat(); }
5966
[[nodiscard]] size_t getFrameQueueSize() const { return m_frame_queue.size(); }
6067

6168
private:

app/src/streaming/ffmpeg/FFmpegVideoDecoder.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -146,41 +146,48 @@ int FFmpegVideoDecoder::setup(int video_format, int width, int height,
146146
return err;
147147
}
148148

149+
AVFrameHolder::instance().prepare();
150+
151+
// One extra frame for decoding processing
152+
m_frames_size = Settings::instance().frames_queue_size() + 1;
153+
m_frames = new AVFrame*[m_frames_size];
154+
149155
tmp_frame = av_frame_alloc();
150-
for (auto & m_frame : m_frames) {
151-
m_frame = av_frame_alloc();
152-
if (m_frame == nullptr) {
156+
for (int i = 0; i < m_frames_size; i++) {
157+
auto& frame = m_frames[i];
158+
frame = av_frame_alloc();
159+
if (frame == nullptr) {
153160
brls::Logger::error("FFmpeg: Couldn't allocate frame");
154161
return -1;
155162
}
156163

157164
#if defined(PLATFORM_SWITCH) && defined(BOREALIS_USE_DEKO3D)
158-
m_frames[i]->format = AV_PIX_FMT_NVTEGRA;
165+
frame->format = AV_PIX_FMT_NVTEGRA;
159166
#elif defined(PLATFORM_ANDROID)
160-
m_frames[i]->format = AV_PIX_FMT_MEDIACODEC;
167+
frame->format = AV_PIX_FMT_MEDIACODEC;
161168
#else
162169
if (video_format & VIDEO_FORMAT_MASK_10BIT)
163-
m_frame->format = AV_PIX_FMT_P010;
170+
frame->format = AV_PIX_FMT_P010;
164171
else
165-
m_frame->format = AV_PIX_FMT_NV12;
172+
frame->format = AV_PIX_FMT_NV12;
166173
#endif
167-
m_frame->width = width;
168-
m_frame->height = height;
174+
frame->width = width;
175+
frame->height = height;
169176

170177
// Need to align Switch frame to 256, need to de reviewed
171178
#if defined(PLATFORM_SWITCH) && !defined(BOREALIS_USE_DEKO3D)
172-
int err = av_frame_get_buffer(m_frame, 256);
179+
int err = av_frame_get_buffer(frame, 256);
173180
if (err < 0) {
174181
char errs[64];
175182
brls::Logger::error("FFmpeg: Couldn't allocate frame buffer: {}", av_make_error_string(errs, 64, err));
176183
return -1;
177184
}
178185

179186
for (int j = 0; j < 2; j++) {
180-
uintptr_t ptr = (uintptr_t)m_frame->data[j];
187+
uintptr_t ptr = (uintptr_t)frame->data[j];
181188
uintptr_t dst = (((ptr)+(256)-1)&~((256)-1));
182189
uintptr_t gap = dst - ptr;
183-
m_frame->data[j] += gap;
190+
frame->data[j] += gap;
184191
}
185192
#endif
186193
}
@@ -235,7 +242,7 @@ void FFmpegVideoDecoder::cleanup() {
235242
}
236243

237244
// if (m_frames) {
238-
for (int i = 0; i < m_frames_count; i++) {
245+
for (int i = 0; i < m_frames_size; i++) {
239246
// if (m_extra_frames[i])
240247
av_frame_free(&m_frames[i]);
241248
}
@@ -254,6 +261,7 @@ void FFmpegVideoDecoder::cleanup() {
254261
}
255262

256263
AVFrameHolder::instance().cleanup();
264+
delete[] m_frames;
257265

258266
brls::Logger::info("FFmpeg: Cleanup done!");
259267
}
@@ -445,7 +453,7 @@ AVFrame* FFmpegVideoDecoder::get_frame(bool native_frame) {
445453

446454
if (err == 0) {
447455
m_current_frame = m_next_frame;
448-
m_next_frame = (m_current_frame + 1) % m_frames_count;
456+
m_next_frame = (m_current_frame + 1) % m_frames_size;
449457
if (/*ffmpeg_decoder == SOFTWARE ||*/ native_frame)
450458
return resultFrame;
451459
} else {

app/src/streaming/ffmpeg/FFmpegVideoDecoder.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ class FFmpegVideoDecoder : public IFFmpegVideoDecoder {
2323
const AVCodec* m_decoder = nullptr;
2424
AVCodecContext* m_decoder_context = nullptr;
2525
AVFrame *tmp_frame = nullptr;
26-
// AVFrame* m_extra_frames[m_frames_count];
27-
AVFrame* m_frames[m_frames_count];
26+
AVFrame** m_frames;
27+
int m_frames_size;
2828

2929
int m_stream_fps = 0;
3030
int m_frames_in = 0;

app/src/streaming_view.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ void StreamingView::draw(NVGcontext* vg, float x, float y, float width,
334334
"Average decoding time: {:.{}f} | {:.{}f} ms\n"
335335
"Average rendering time: {:.{}f} ms\n"
336336
"Frame holder push/get rate: {}\n"
337-
"Fake frames produced: {}\n"
337+
"Frames queue reuses | drops: {} | {}\n"
338338
"Frames queue: {}",
339339
stats->video_decode_stats.network_dropped_frames,
340340
stats->video_decode_stats.current_receive_time, 2,
@@ -344,6 +344,7 @@ void StreamingView::draw(NVGcontext* vg, float x, float y, float width,
344344
stats->video_render_stats.rendering_time, 2,
345345
AVFrameHolder::instance().getStat(),
346346
AVFrameHolder::instance().getFakeFrameStat(),
347+
AVFrameHolder::instance().getFrameDropStat(),
347348
AVFrameHolder::instance().getFrameQueueSize());
348349

349350
nvgFontFaceId(vg, Application::getFont(FONT_REGULAR));

app/src/utils/Settings.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,15 @@ void Settings::load() {
266266
}
267267
}
268268

269+
if (json_t* frames_queue_size = json_object_get(settings, "frames_queue_size")) {
270+
if (json_typeof(frames_queue_size) == JSON_INTEGER) {
271+
m_frames_queue_size = (int)json_integer_value(frames_queue_size);
272+
273+
// SANITY CHECK, APP WILL CRASH OTHERWISE
274+
if (m_frames_queue_size < 1) m_frames_queue_size = 1;
275+
}
276+
}
277+
269278
if (json_t* hw_decoding = json_object_get(settings, "use_hw_decoding")) {
270279
m_use_hw_decoding = json_typeof(hw_decoding) == JSON_TRUE;
271280
}
@@ -488,6 +497,7 @@ void Settings::save() {
488497
json_object_set_new(settings, "audio_backend", json_integer(m_audio_backend));
489498
json_object_set_new(settings, "bitrate", json_integer(m_bitrate));
490499
json_object_set_new(settings, "decoder_threads", json_integer(m_decoder_threads));
500+
json_object_set_new(settings, "frames_queue_size", json_integer(m_frames_queue_size));
491501
json_object_set_new(settings, "enable_hdr", m_enable_hdr ? json_true() : json_false());
492502
json_object_set_new(settings, "click_by_tap", m_click_by_tap ? json_true() : json_false());
493503
json_object_set_new(settings, "use_hw_decoding", m_use_hw_decoding ? json_true() : json_false());

app/src/utils/Settings.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ class Settings : public Singleton<Settings> {
9797
void set_decoder_threads(int decoder_threads) { m_decoder_threads = decoder_threads; }
9898
[[nodiscard]] int decoder_threads() const { return m_decoder_threads; }
9999

100+
void set_frames_queue_size(int frames_queue_size) { m_frames_queue_size = frames_queue_size; }
101+
[[nodiscard]] int frames_queue_size() const { return m_frames_queue_size; }
102+
100103
void set_sops(bool sops) { m_sops = sops; }
101104
[[nodiscard]] bool sops() const { return m_sops; }
102105

@@ -190,6 +193,7 @@ class Settings : public Singleton<Settings> {
190193
bool m_enable_hdr = false;
191194
bool m_click_by_tap = false;
192195
int m_decoder_threads = 4;
196+
int m_frames_queue_size = 3;
193197
bool m_sops = true;
194198
bool m_play_audio = false;
195199
bool m_write_log = false;

0 commit comments

Comments
 (0)