From c96e3ed9dd49b0fdfe727fb0d762bc126ee65b08 Mon Sep 17 00:00:00 2001 From: rankun Date: Thu, 16 Jan 2020 17:08:56 +0800 Subject: [PATCH] feat: add config --- QtScrcpy/QtScrcpy.pro | 8 +- QtScrcpy/device/recorder/recorder.cpp | 105 ++++++++------------------ QtScrcpy/device/recorder/recorder.h | 25 ++---- QtScrcpy/device/server/server.cpp | 3 +- QtScrcpy/dialog.cpp | 6 +- QtScrcpy/main.cpp | 4 + QtScrcpy/util/config.cpp | 80 ++++++++++++++++++++ QtScrcpy/util/config.h | 27 +++++++ QtScrcpy/util/util.pri | 6 +- config/config.ini | 4 + publish_for_win.bat | 2 + 11 files changed, 170 insertions(+), 100 deletions(-) create mode 100644 QtScrcpy/util/config.cpp create mode 100644 QtScrcpy/util/config.h create mode 100644 config/config.ini diff --git a/QtScrcpy/QtScrcpy.pro b/QtScrcpy/QtScrcpy.pro index 8ac2b36..1bd3c2d 100644 --- a/QtScrcpy/QtScrcpy.pro +++ b/QtScrcpy/QtScrcpy.pro @@ -58,8 +58,8 @@ INCLUDEPATH += \ # 统一版本号入口,只修改这一个地方即可 VERSION_MAJOR = 1 -VERSION_MINOR = 12 -VERSION_PATCH = 1 +VERSION_MINOR = 1 +VERSION_PATCH = 0 # qmake变量的方式定义版本号 VERSION = $${VERSION_MAJOR}.$${VERSION_MINOR}.$${VERSION_PATCH} @@ -152,6 +152,10 @@ macos { APP_FFMPEG.path = Contents/MacOS QMAKE_BUNDLE_DATA += APP_FFMPEG + APP_CONFIG.files = $$files($$PWD/../config/config.ini) + APP_CONFIG.path = Contents/MacOS + QMAKE_BUNDLE_DATA += APP_CONFIG + # mac application icon ICON = $$PWD/res/QtScrcpy.icns QMAKE_INFO_PLIST = $$PWD/res/Info_mac.plist diff --git a/QtScrcpy/device/recorder/recorder.cpp b/QtScrcpy/device/recorder/recorder.cpp index b418810..5e16317 100644 --- a/QtScrcpy/device/recorder/recorder.cpp +++ b/QtScrcpy/device/recorder/recorder.cpp @@ -12,85 +12,38 @@ Recorder::Recorder(const QString& fileName, QObject* parent) , m_fileName(fileName) , m_format(guessRecordFormat(fileName)) { - queueInit(&m_queue); } Recorder::~Recorder() { - } -Recorder::RecordPacket* Recorder::packetNew(const AVPacket *packet) { - RecordPacket* rec = new RecordPacket; +AVPacket* Recorder::packetNew(const AVPacket *packet) { + AVPacket* rec = new AVPacket; if (!rec) { return Q_NULLPTR; } // av_packet_ref() does not initialize all fields in old FFmpeg versions - av_init_packet(&rec->packet); + av_init_packet(rec); - if (av_packet_ref(&rec->packet, packet)) { + if (av_packet_ref(rec, packet)) { delete rec; return Q_NULLPTR; } - rec->next = Q_NULLPTR; return rec; } -void Recorder::packetDelete(Recorder::RecordPacket *rec) { - av_packet_unref(&rec->packet); - delete rec; +void Recorder::packetDelete(AVPacket* packet) { + av_packet_unref(packet); + delete packet; } -void Recorder::queueInit(Recorder::RecorderQueue *queue) { - queue->first = Q_NULLPTR; - // queue->last is undefined if queue->first == NULL -} - -bool Recorder::queueIsEmpty(Recorder::RecorderQueue *queue) { - return !queue->first; -} - -bool Recorder::queuePush(Recorder::RecorderQueue *queue, const AVPacket *packet) { - RecordPacket *rec = packetNew(packet); - if (!rec) { - qCritical("Could not allocate record packet"); - return false; +void Recorder::queueClear() +{ + while (!m_queue.isEmpty()) { + packetDelete(m_queue.dequeue()); } - rec->next = Q_NULLPTR; - - if (queueIsEmpty(queue)) { - queue->first = queue->last = rec; - } else { - // chain rec after the (current) last packet - queue->last->next = rec; - // the last packet is now rec - queue->last = rec; - } - return true; -} - -Recorder::RecordPacket* Recorder::queueTake(Recorder::RecorderQueue *queue) { - assert(!queueIsEmpty(queue)); - - RecordPacket *rec = queue->first; - assert(rec); - - queue->first = rec->next; - // no need to update queue->last if the queue is left empty: - // queue->last is undefined if queue->first == NULL - - return rec; -} - -void Recorder::queueClear(Recorder::RecorderQueue *queue) { - RecordPacket *rec = queue->first; - while (rec) { - RecordPacket *current = rec; - rec = rec->next; - packetDelete(current); - } - queue->first = Q_NULLPTR; } void Recorder::setFrameSize(const QSize &declaredFrameSize) @@ -289,21 +242,21 @@ Recorder::RecorderFormat Recorder::guessRecordFormat(const QString &fileName) void Recorder::run() { for (;;) { - RecordPacket *rec = Q_NULLPTR; + AVPacket *rec = Q_NULLPTR; { QMutexLocker locker(&m_mutex); - while (!m_stopped && queueIsEmpty(&m_queue)) { + while (!m_stopped && m_queue.isEmpty()) { m_recvDataCond.wait(&m_mutex); } // if stopped is set, continue to process the remaining events (to // finish the recording) before actually stopping - if (m_stopped && queueIsEmpty(&m_queue)) { - RecordPacket* last = m_previous; + if (m_stopped && m_queue.isEmpty()) { + AVPacket* last = m_previous; if (last) { // assign an arbitrary duration to the last packet - last->packet.duration = 100000; - bool ok = write(&last->packet); + last->duration = 100000; + bool ok = write(last); if (!ok) { // failing to write the last frame is not very serious, no // future frame may depend on it, so the resulting file @@ -315,11 +268,11 @@ void Recorder::run() { break; } - rec = queueTake(&m_queue); + rec = m_queue.dequeue(); } // recorder->previous is only written from this thread, no need to lock - RecordPacket* previous = m_previous; + AVPacket* previous = m_previous; m_previous = rec; if (!previous) { @@ -328,21 +281,20 @@ void Recorder::run() { } // config packets have no PTS, we must ignore them - if (rec->packet.pts != AV_NOPTS_VALUE - && previous->packet.pts != AV_NOPTS_VALUE) { + if (rec->pts != AV_NOPTS_VALUE + && previous->pts != AV_NOPTS_VALUE) { // we now know the duration of the previous packet - previous->packet.duration = rec->packet.pts - previous->packet.pts; + previous->duration = rec->pts - previous->pts; } - bool ok = write(&previous->packet); + bool ok = write(previous); packetDelete(previous); if (!ok) { qCritical("Could not record packet"); - QMutexLocker locker(&m_mutex); m_failed = true; // discard pending packets - queueClear(&m_queue); + queueClear(); break; } } @@ -370,7 +322,10 @@ bool Recorder::push(const AVPacket *packet) { return false; } - bool ok = queuePush(&m_queue, packet); - m_recvDataCond.wakeOne(); - return ok; + AVPacket* rec = packetNew(packet); + if (rec) { + m_queue.enqueue(rec); + m_recvDataCond.wakeOne(); + } + return rec != Q_NULLPTR; } diff --git a/QtScrcpy/device/recorder/recorder.h b/QtScrcpy/device/recorder/recorder.h index da9695c..cdbe72a 100644 --- a/QtScrcpy/device/recorder/recorder.h +++ b/QtScrcpy/device/recorder/recorder.h @@ -5,6 +5,7 @@ #include #include #include +#include extern "C" { @@ -41,23 +42,9 @@ private: RecorderFormat guessRecordFormat(const QString& fileName); private: - struct RecordPacket { - AVPacket packet; - RecordPacket *next; - }; - - struct RecorderQueue { - RecordPacket *first = Q_NULLPTR; - RecordPacket *last = Q_NULLPTR; // undefined if first is NULL - }; - - Recorder::RecordPacket* packetNew(const AVPacket *packet); - void packetDelete(Recorder::RecordPacket *rec); - void queueInit(Recorder::RecorderQueue *queue); - bool queueIsEmpty(Recorder::RecorderQueue *queue); - bool queuePush(Recorder::RecorderQueue *queue, const AVPacket *packet); - Recorder::RecordPacket* queueTake(Recorder::RecorderQueue *queue); - void queueClear(Recorder::RecorderQueue *queue); + AVPacket* packetNew(const AVPacket *packet); + void packetDelete(AVPacket* packet); + void queueClear(); protected: void run(); @@ -72,12 +59,12 @@ private: QWaitCondition m_recvDataCond; bool m_stopped = false; // set on recorder_stop() by the stream reader bool m_failed = false; // set on packet write failure - RecorderQueue m_queue; + QQueue m_queue; // we can write a packet only once we received the next one so that we can // set its duration (next_pts - current_pts) // "previous" is only accessed from the recorder thread, so it does not // need to be protected by the mutex - RecordPacket* m_previous = Q_NULLPTR; + AVPacket* m_previous = Q_NULLPTR; }; #endif // RECORDER_H diff --git a/QtScrcpy/device/server/server.cpp b/QtScrcpy/device/server/server.cpp index f60da81..4f04f7f 100644 --- a/QtScrcpy/device/server/server.cpp +++ b/QtScrcpy/device/server/server.cpp @@ -6,6 +6,7 @@ #include #include "server.h" +#include "config.h" #define DEVICE_SERVER_PATH "/data/local/tmp/scrcpy-server.jar" #define DEVICE_NAME_FIELD_LENGTH 64 @@ -129,7 +130,7 @@ bool Server::execute() args << "app_process"; args << "/"; // unused; args << "com.genymobile.scrcpy.Server"; - args << QCoreApplication::applicationVersion(); + args << Config::getInstance().getServerVersion(); args << QString::number(m_params.maxSize); args << QString::number(m_params.bitRate); args << QString::number(m_params.maxFps); diff --git a/QtScrcpy/dialog.cpp b/QtScrcpy/dialog.cpp index 1b09354..baf9dbb 100644 --- a/QtScrcpy/dialog.cpp +++ b/QtScrcpy/dialog.cpp @@ -9,6 +9,7 @@ #include "device.h" #include "videoform.h" #include "keymap.h" +#include "config.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), @@ -63,7 +64,7 @@ Dialog::Dialog(QWidget *parent) : } Dialog::~Dialog() -{ +{ m_deviceManage.disconnectAllDevice(); delete ui; } @@ -92,6 +93,8 @@ void Dialog::initUI() // game only windows ui->gameCheck->setEnabled(false); #endif + + ui->recordPathEdt->setText(Config::getInstance().getRecordPath()); } void Dialog::execAdbCmd() @@ -287,6 +290,7 @@ void Dialog::on_selectRecordPathBtn_clicked() void Dialog::on_recordPathEdt_textChanged(const QString &arg1) { + Config::getInstance().setRecordPath(arg1); ui->recordPathEdt->setToolTip(arg1.trimmed()); ui->notDisplayCheck->setCheckable(!arg1.trimmed().isEmpty()); } diff --git a/QtScrcpy/main.cpp b/QtScrcpy/main.cpp index e0182a9..b4bdb29 100644 --- a/QtScrcpy/main.cpp +++ b/QtScrcpy/main.cpp @@ -8,6 +8,7 @@ #include "dialog.h" #include "stream.h" #include "mousetap/mousetap.h" +#include "config.h" Dialog* g_mainDlg = Q_NULLPTR; @@ -44,11 +45,13 @@ int main(int argc, char *argv[]) qputenv("QTSCRCPY_ADB_PATH", "../../../../third_party/adb/win/adb.exe"); qputenv("QTSCRCPY_SERVER_PATH", "../../../../third_party/scrcpy-server"); qputenv("QTSCRCPY_KEYMAP_PATH", "../../../../keymap"); + qputenv("QTSCRCPY_CONFIG_PATH", "../../../../config/config.ini"); #endif #ifdef Q_OS_LINUX qputenv("QTSCRCPY_ADB_PATH", "../../../third_party/adb/linux/adb"); qputenv("QTSCRCPY_SERVER_PATH", "../../../third_party/scrcpy-server"); + qputenv("QTSCRCPY_CONFIG_PATH", "../../../config/config.ini"); #endif //加载样式表 @@ -62,6 +65,7 @@ int main(int argc, char *argv[]) } g_mainDlg = new Dialog; + g_mainDlg->setWindowTitle(Config::getInstance().getTitle()); g_mainDlg->show(); qInfo(QString("QtScrcpy %1 ").arg(QCoreApplication::applicationVersion()).toUtf8()); diff --git a/QtScrcpy/util/config.cpp b/QtScrcpy/util/config.cpp new file mode 100644 index 0000000..0c57eb0 --- /dev/null +++ b/QtScrcpy/util/config.cpp @@ -0,0 +1,80 @@ +#include +#include +#include + +#include "config.h" + +#define GROUP_COMMON "common" + +#define COMMON_TITLE_KEY "WindowTitle" +#define COMMON_TITLE_DEF QCoreApplication::applicationName() + +#define COMMON_RECORD_KEY "RecordPath" +#define COMMON_RECORD_DEF "" + +#define COMMON_SERVER_VERSION_KEY "ServerVersion" +#define COMMON_SERVER_VERSION_DEF "1.12.1" + + +QString Config::s_configPath = ""; + +Config::Config(QObject *parent) : QObject(parent) +{ + m_settings = new QSettings(getConfigPath(), QSettings::IniFormat); + m_settings->setIniCodec("UTF-8"); +} + +Config &Config::getInstance() +{ + static Config config; + return config; +} + +const QString& Config::getConfigPath() +{ + if (s_configPath.isEmpty()) { + s_configPath = QString::fromLocal8Bit(qgetenv("QTSCRCPY_CONFIG_PATH")); + QFileInfo fileInfo(s_configPath); + if (s_configPath.isEmpty() || !fileInfo.isFile()) { + s_configPath = QCoreApplication::applicationDirPath() + "/config/config.ini"; + } + } + return s_configPath; +} + +QString Config::getRecordPath() +{ + QString record; + m_settings->beginGroup(GROUP_COMMON); + record = m_settings->value(COMMON_RECORD_KEY, COMMON_RECORD_DEF).toString(); + m_settings->endGroup(); + return record; +} + +void Config::setRecordPath(const QString &path) +{ + m_settings->beginGroup(GROUP_COMMON); + m_settings->setValue(COMMON_RECORD_KEY, path); + m_settings->endGroup(); +} + +QString Config::getServerVersion() +{ + QString server; + m_settings->beginGroup(GROUP_COMMON); + server = m_settings->value(COMMON_SERVER_VERSION_KEY, COMMON_SERVER_VERSION_DEF).toString(); + m_settings->endGroup(); + return server; +} + +QString Config::getTitle() +{ + QString title; + m_settings->beginGroup(GROUP_COMMON); + title = m_settings->value(COMMON_TITLE_KEY, COMMON_TITLE_DEF).toString(); + m_settings->endGroup(); + return title; +} + + + diff --git a/QtScrcpy/util/config.h b/QtScrcpy/util/config.h new file mode 100644 index 0000000..a7c1016 --- /dev/null +++ b/QtScrcpy/util/config.h @@ -0,0 +1,27 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#include +#include + +class QSettings; +class Config : public QObject +{ + Q_OBJECT +public: + static Config& getInstance(); + QString getTitle(); + QString getRecordPath(); + void setRecordPath(const QString& path); + QString getServerVersion(); + +private: + explicit Config(QObject *parent = nullptr); + const QString& getConfigPath(); + +private: + static QString s_configPath; + QPointer m_settings; +}; + +#endif // CONFIG_H diff --git a/QtScrcpy/util/util.pri b/QtScrcpy/util/util.pri index 720d7e6..3c8c77b 100644 --- a/QtScrcpy/util/util.pri +++ b/QtScrcpy/util/util.pri @@ -2,7 +2,9 @@ include ($$PWD/mousetap/mousetap.pri) HEADERS += \ $$PWD/compat.h \ - $$PWD/bufferutil.h + $$PWD/bufferutil.h \ + $$PWD/config.h SOURCES += \ - $$PWD/bufferutil.cpp + $$PWD/bufferutil.cpp \ + $$PWD/config.cpp diff --git a/config/config.ini b/config/config.ini new file mode 100644 index 0000000..f36d228 --- /dev/null +++ b/config/config.ini @@ -0,0 +1,4 @@ +[common] +WindowTitle=abc +RecordPath=C:/Users/bytedance/Desktop +ServerVersion=1.12.1 diff --git a/publish_for_win.bat b/publish_for_win.bat index 470508d..8a503ac 100644 --- a/publish_for_win.bat +++ b/publish_for_win.bat @@ -21,6 +21,7 @@ if /i "%1"=="x64" ( set adb_path=%script_path%third_party\adb\win\*.* set jar_path=%script_path%third_party\scrcpy-server.jar set keymap_path=%script_path%keymap +set config_path=%script_path%config if /i %cpu_mode% == x86 ( set publish_path=%script_path%QtScrcpy-win32\ @@ -42,6 +43,7 @@ xcopy %release_path% %publish_path% /E /Y xcopy %adb_path% %publish_path% /Y xcopy %jar_path% %publish_path% /Y xcopy %keymap_path% %publish_path%keymap\ /E /Y +xcopy %config_path% %publish_path%config\ /E /Y :: qt windeployqt %publish_path%\QtScrcpy.exe