mirror of
https://github.com/rock88/moonlight-nx
synced 2024-09-20 06:12:00 +00:00
Cleanup;
Add LockThreadDetector, integrate soon...
This commit is contained in:
parent
1be75b0c93
commit
24436ad841
7 changed files with 87 additions and 106 deletions
4
Makefile
4
Makefile
|
@ -44,7 +44,7 @@ APP_AUTHOR := port by rock88
|
|||
APP_VERSION := 1.1.0
|
||||
BUILD := build
|
||||
SOURCES := src src/libgamestream src/switch src/nanogui_resources src/streaming src/streaming/ffmpeg \
|
||||
src/crypto src/streaming/video src/crypto src/streaming/audio src/ui/windows src/ui/buttons src/ui src/helpers src/controls\
|
||||
src/crypto src/streaming/video src/crypto src/streaming/audio src/ui/windows src/ui/buttons src/ui src/utils src/controls\
|
||||
third_party/moonlight-common-c/enet third_party/moonlight-common-c/reedsolomon third_party/moonlight-common-c/src \
|
||||
third_party/nanogui/ext/nanovg/src third_party/nanogui/src
|
||||
DATA := data
|
||||
|
@ -65,7 +65,7 @@ ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
|
|||
M_INCLUDES := \
|
||||
-I$(TOPDIR)/src -I$(TOPDIR)/src/switch -I$(TOPDIR)/src/streaming -I$(TOPDIR)/src/crypto -I$(TOPDIR)/src/crypto/keys \
|
||||
-I$(TOPDIR)/src/streaming/ffmpeg -I$(TOPDIR)/src/streaming/video -I$(TOPDIR)/src/streaming/audio \
|
||||
-I$(TOPDIR)/src/nanogui_resources -I$(TOPDIR)/src/helpers -I$(TOPDIR)/src/controls \
|
||||
-I$(TOPDIR)/src/nanogui_resources -I$(TOPDIR)/src/utils -I$(TOPDIR)/src/controls \
|
||||
-I$(TOPDIR)/src/ui -I$(TOPDIR)/src/ui/buttons -I$(TOPDIR)/src/ui/windows \
|
||||
-I$(TOPDIR)/src/libgamestream \
|
||||
-I$(TOPDIR)/third_party/moonlight-common-c/reedsolomon \
|
||||
|
|
|
@ -106,6 +106,7 @@
|
|||
36A0C0372461DBA30083289C /* AddHostButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36A0C0352461DBA30083289C /* AddHostButton.cpp */; };
|
||||
36A0C03A2461E4C00083289C /* SettingsWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36A0C0382461E4C00083289C /* SettingsWindow.cpp */; };
|
||||
36A0C03D2461F03C0083289C /* Settings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36A0C03B2461F03C0083289C /* Settings.cpp */; };
|
||||
36BD0AFE25E5251300DD1B86 /* LockThreadDetector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36BD0AFC25E5251300DD1B86 /* LockThreadDetector.cpp */; };
|
||||
36BFCCF12479723E00245D40 /* xml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36BFCCEA2479723E00245D40 /* xml.cpp */; };
|
||||
36BFCCF22479723E00245D40 /* client.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36BFCCEC2479723E00245D40 /* client.cpp */; };
|
||||
36BFCCF32479723E00245D40 /* http.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36BFCCF02479723E00245D40 /* http.cpp */; };
|
||||
|
@ -320,6 +321,8 @@
|
|||
36A0C0392461E4C00083289C /* SettingsWindow.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = SettingsWindow.hpp; sourceTree = "<group>"; };
|
||||
36A0C03B2461F03C0083289C /* Settings.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Settings.cpp; sourceTree = "<group>"; };
|
||||
36A0C03C2461F03C0083289C /* Settings.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Settings.hpp; sourceTree = "<group>"; };
|
||||
36BD0AFC25E5251300DD1B86 /* LockThreadDetector.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LockThreadDetector.cpp; sourceTree = "<group>"; };
|
||||
36BD0AFD25E5251300DD1B86 /* LockThreadDetector.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = LockThreadDetector.hpp; sourceTree = "<group>"; };
|
||||
36BFCCEA2479723E00245D40 /* xml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xml.cpp; sourceTree = "<group>"; };
|
||||
36BFCCEB2479723E00245D40 /* client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = client.h; sourceTree = "<group>"; };
|
||||
36BFCCEC2479723E00245D40 /* client.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = client.cpp; sourceTree = "<group>"; };
|
||||
|
@ -432,12 +435,14 @@
|
|||
path = controls;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3620419025D7FDCC00D21EE3 /* helpers */ = {
|
||||
3620419025D7FDCC00D21EE3 /* utils */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3620419125D7FDDB00D21EE3 /* Singleton.hpp */,
|
||||
36BD0AFC25E5251300DD1B86 /* LockThreadDetector.cpp */,
|
||||
36BD0AFD25E5251300DD1B86 /* LockThreadDetector.hpp */,
|
||||
);
|
||||
path = helpers;
|
||||
path = utils;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3652ECC3245B3AFF001FABF3 /* nanogui */ = {
|
||||
|
@ -684,7 +689,7 @@
|
|||
36B406932459F41E005BD903 /* src */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3620419025D7FDCC00D21EE3 /* helpers */,
|
||||
3620419025D7FDCC00D21EE3 /* utils */,
|
||||
36BFCCE92479723E00245D40 /* libgamestream */,
|
||||
36E63789246FFFDC0032F5FB /* crypto */,
|
||||
36DFE0CA2459FA3F00FC51CE /* nanogui_resources */,
|
||||
|
@ -1008,6 +1013,7 @@
|
|||
3652EFE8245B3B00001FABF3 /* opengl.cpp in Sources */,
|
||||
3652EFD7245B3B00001FABF3 /* screen.cpp in Sources */,
|
||||
3652EFE1245B3B00001FABF3 /* progressbar.cpp in Sources */,
|
||||
36BD0AFE25E5251300DD1B86 /* LockThreadDetector.cpp in Sources */,
|
||||
3652EFF5245B3B00001FABF3 /* popupbutton.cpp in Sources */,
|
||||
3652EFF0245B3B00001FABF3 /* colorwheel.cpp in Sources */,
|
||||
3652F068245C292B001FABF3 /* unix.c in Sources */,
|
||||
|
|
|
@ -10,77 +10,9 @@
|
|||
|
||||
#define DECODER_BUFFER_SIZE 92 * 1024 * 2
|
||||
|
||||
#include <switch.h>
|
||||
#include <unistd.h>
|
||||
FFmpegVideoDecoder::FFmpegVideoDecoder() {}
|
||||
|
||||
class ThreadLockWatcher {
|
||||
public:
|
||||
void start() {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
is_alive = true;
|
||||
prev = current = 0;
|
||||
pthread_create(&thread, NULL, entry, this);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
is_alive = false;
|
||||
}
|
||||
|
||||
void enter(int line) {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
last_line = line;
|
||||
prev = current;
|
||||
current++;
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_alive = false;
|
||||
u64 prev = 0;
|
||||
u64 current = 0;
|
||||
int last_line = 0;
|
||||
|
||||
static void* entry(void* context) {
|
||||
while (true) {
|
||||
if (auto watcher = static_cast<ThreadLockWatcher *>(context)) {
|
||||
if (watcher->is_alive) {
|
||||
if (watcher->current != 0) {
|
||||
std::lock_guard<std::mutex> lock(watcher->m_mutex);
|
||||
|
||||
if (watcher->prev > watcher->current) {
|
||||
Logger::error("ThreadLockWatcher", "Thread Lock Detected on a line: %i", watcher->last_line);
|
||||
} else {
|
||||
watcher->prev++;
|
||||
}
|
||||
}
|
||||
usleep(500'000);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::mutex m_mutex;
|
||||
pthread_t thread;
|
||||
};
|
||||
|
||||
static ThreadLockWatcher watcher;
|
||||
#define DBG() watcher.enter(__LINE__);
|
||||
|
||||
FFmpegVideoDecoder::FFmpegVideoDecoder() {
|
||||
//pthread_mutex_init(&m_mutex, NULL);
|
||||
watcher.start();
|
||||
}
|
||||
|
||||
FFmpegVideoDecoder::~FFmpegVideoDecoder() {
|
||||
watcher.stop();
|
||||
//pthread_mutex_destroy(&m_mutex);
|
||||
}
|
||||
FFmpegVideoDecoder::~FFmpegVideoDecoder() {}
|
||||
|
||||
int FFmpegVideoDecoder::setup(int video_format, int width, int height, int redraw_rate, void *context, int dr_flags) {
|
||||
m_stream_fps = redraw_rate;
|
||||
|
@ -200,26 +132,22 @@ void FFmpegVideoDecoder::cleanup() {
|
|||
}
|
||||
|
||||
int FFmpegVideoDecoder::submit_decode_unit(PDECODE_UNIT decode_unit) {
|
||||
DBG();
|
||||
if (decode_unit->fullLength < DECODER_BUFFER_SIZE) {
|
||||
PLENTRY entry = decode_unit->bufferList;
|
||||
DBG();
|
||||
|
||||
if (!m_last_frame) {
|
||||
m_video_decode_stats.measurement_start_timestamp = LiGetMillis();
|
||||
m_last_frame = decode_unit->frameNumber;
|
||||
DBG();
|
||||
}
|
||||
else {
|
||||
// Any frame number greater than m_LastFrameNumber + 1 represents a dropped frame
|
||||
m_video_decode_stats.network_dropped_frames += decode_unit->frameNumber - (m_last_frame + 1);
|
||||
m_video_decode_stats.total_frames += decode_unit->frameNumber - (m_last_frame + 1);
|
||||
m_last_frame = decode_unit->frameNumber;
|
||||
DBG();
|
||||
}
|
||||
|
||||
m_video_decode_stats.received_frames++;
|
||||
m_video_decode_stats.total_frames++;
|
||||
DBG();
|
||||
|
||||
int length = 0;
|
||||
while (entry != NULL) {
|
||||
|
@ -227,14 +155,11 @@ int FFmpegVideoDecoder::submit_decode_unit(PDECODE_UNIT decode_unit) {
|
|||
Logger::error("FFmpeg", "Big buffer to decode... !");
|
||||
}
|
||||
|
||||
DBG();
|
||||
memcpy(m_ffmpeg_buffer + length, entry->data, entry->length);
|
||||
length += entry->length;
|
||||
entry = entry->next;
|
||||
DBG();
|
||||
}
|
||||
|
||||
DBG();
|
||||
m_video_decode_stats.total_reassembly_time += LiGetMillis() - decode_unit->receiveTimeMs;
|
||||
|
||||
m_frames_in++;
|
||||
|
@ -245,24 +170,17 @@ int FFmpegVideoDecoder::submit_decode_unit(PDECODE_UNIT decode_unit) {
|
|||
Logger::error("FFmpeg", "Big buffer to decode...");
|
||||
}
|
||||
|
||||
DBG();
|
||||
if (decode(m_ffmpeg_buffer, length) == 0) {
|
||||
m_frames_out++;
|
||||
DBG();
|
||||
m_video_decode_stats.total_decode_time += LiGetMillis() - before_decode;
|
||||
|
||||
// Also count the frame-to-frame delay if the decoder is delaying frames
|
||||
// until a subsequent frame is submitted.
|
||||
m_video_decode_stats.total_decode_time += (m_frames_in - m_frames_out) * (1000 / m_stream_fps);
|
||||
m_video_decode_stats.decoded_frames++;
|
||||
DBG();
|
||||
//if (pthread_mutex_lock(&m_mutex) == 0) {
|
||||
m_frame = get_frame(true);
|
||||
AVFrameHolder::instance().push(m_frame);
|
||||
DBG();//
|
||||
// Push event!!
|
||||
//pthread_mutex_unlock(&m_mutex);
|
||||
//}
|
||||
|
||||
m_frame = get_frame(true);
|
||||
AVFrameHolder::instance().push(m_frame);
|
||||
}
|
||||
} else {
|
||||
Logger::error("FFmpeg", "Big buffer to decode... 2");
|
||||
|
@ -277,36 +195,28 @@ int FFmpegVideoDecoder::capabilities() const {
|
|||
int FFmpegVideoDecoder::decode(char* indata, int inlen) {
|
||||
m_packet.data = (uint8_t *)indata;
|
||||
m_packet.size = inlen;
|
||||
DBG();
|
||||
|
||||
int err = avcodec_send_packet(m_decoder_context, &m_packet);
|
||||
DBG();
|
||||
|
||||
if (err != 0) {
|
||||
DBG();
|
||||
char error[512];
|
||||
av_strerror(err, error, sizeof(error));
|
||||
Logger::error("FFmpeg", "Decode failed - %s", error);
|
||||
DBG();
|
||||
}
|
||||
DBG();
|
||||
return err != 0 ? err : 0;
|
||||
}
|
||||
|
||||
AVFrame* FFmpegVideoDecoder::get_frame(bool native_frame) {
|
||||
DBG();
|
||||
int err = avcodec_receive_frame(m_decoder_context, m_frames[m_next_frame]);
|
||||
DBG();
|
||||
|
||||
if (err == 0) {
|
||||
DBG();
|
||||
m_current_frame = m_next_frame;
|
||||
m_next_frame = (m_current_frame + 1) % m_frames_count;
|
||||
DBG();
|
||||
if (/*ffmpeg_decoder == SOFTWARE ||*/ native_frame)
|
||||
return m_frames[m_current_frame];
|
||||
} else if (err != AVERROR(EAGAIN)) {
|
||||
DBG();
|
||||
char error[512];
|
||||
av_strerror(err, error, sizeof(error));
|
||||
DBG();
|
||||
Logger::error("FFmpeg", "Receive failed - %d/%s", err, error);
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "IFFmpegVideoDecoder.hpp"
|
||||
#include <pthread.h>
|
||||
#pragma once
|
||||
|
||||
class FFmpegVideoDecoder: public IFFmpegVideoDecoder {
|
||||
|
@ -34,5 +33,4 @@ private:
|
|||
|
||||
char* m_ffmpeg_buffer = nullptr;
|
||||
AVFrame* m_frame = nullptr;
|
||||
pthread_mutex_t m_mutex;
|
||||
};
|
||||
|
|
42
src/utils/LockThreadDetector.cpp
Normal file
42
src/utils/LockThreadDetector.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
#include "LockThreadDetector.hpp"
|
||||
#include "Logger.hpp"
|
||||
|
||||
void* LockThreadDetector::entry(void* context) {
|
||||
while (true) {
|
||||
if (auto detector = static_cast<LockThreadDetector *>(context)) {
|
||||
if (detector->m_is_running) {
|
||||
if (detector->m_current != 0) {
|
||||
std::lock_guard<std::mutex> lock(detector->m_mutex);
|
||||
|
||||
if (detector->m_prev > detector->m_current) {
|
||||
Logger::error("LockThreadDetector", "Thread Lock Detected on a line: %i", detector->m_last_line);
|
||||
} else {
|
||||
detector->m_prev++;
|
||||
}
|
||||
}
|
||||
usleep(500'000);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LockThreadDetector::LockThreadDetector(std::string file_name) {
|
||||
m_file_name = file_name;
|
||||
}
|
||||
|
||||
void LockThreadDetector::start() {
|
||||
|
||||
}
|
||||
|
||||
void LockThreadDetector::stop() {
|
||||
|
||||
}
|
||||
|
||||
void LockThreadDetector::enter(int line) {
|
||||
|
||||
}
|
25
src/utils/LockThreadDetector.hpp
Normal file
25
src/utils/LockThreadDetector.hpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include <stdio.h>
|
||||
#include <mutex>
|
||||
#include <switch.h>
|
||||
#pragma once
|
||||
|
||||
class LockThreadDetector {
|
||||
LockThreadDetector(std::string file_name);
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
void enter(int line);
|
||||
|
||||
private:
|
||||
static void* entry(void* context);
|
||||
|
||||
std::string m_file_name;
|
||||
bool m_is_running = false;
|
||||
u64 m_prev = 0;
|
||||
u64 m_current = 0;
|
||||
int m_last_line = 0;
|
||||
|
||||
std::mutex m_mutex;
|
||||
pthread_t m_thread;
|
||||
};
|
Loading…
Reference in a new issue