diff --git a/src/QtScrcpy.pro b/src/QtScrcpy.pro index 4f92b6f..b574be9 100644 --- a/src/QtScrcpy.pro +++ b/src/QtScrcpy.pro @@ -36,7 +36,8 @@ SOURCES += \ fpscounter.cpp \ qyuvopenglwidget.cpp \ videoform.cpp \ - devicesocket.cpp + devicesocket.cpp \ + tcpserver.cpp HEADERS += \ dialog.h \ @@ -48,7 +49,8 @@ HEADERS += \ fpscounter.h \ qyuvopenglwidget.h \ videoform.h \ - devicesocket.h + devicesocket.h \ + tcpserver.h FORMS += \ dialog.ui \ diff --git a/src/decoder.cpp b/src/decoder.cpp index 25ee450..aa98d94 100644 --- a/src/decoder.cpp +++ b/src/decoder.cpp @@ -45,7 +45,7 @@ static qint32 readPacket(void *opaque, quint8 *buf, qint32 bufSize) { return 0; } -void Decoder::setDeviceSocket(QTcpSocket* deviceSocket) +void Decoder::setDeviceSocket(DeviceSocket* deviceSocket) { m_deviceSocket = deviceSocket; } @@ -56,16 +56,7 @@ qint32 Decoder::recvData(quint8* buf, qint32 bufSize) return 0; } if (m_deviceSocket) { - while (!m_quit && m_deviceSocket->bytesAvailable() <= 0) { - if (!m_deviceSocket->waitForReadyRead(300) - && QTcpSocket::SocketTimeoutError != m_deviceSocket->error()) { - qDebug() << "waitForReadyRead error " << m_deviceSocket->error(); - break; - } - } - qint64 readSize = qMin(m_deviceSocket->bytesAvailable(), (qint64)bufSize); - //qDebug() << "ready recv data " << readSize; - return m_deviceSocket->read((char*)buf, readSize); + return m_deviceSocket->recvData(buf, bufSize); } return 0; } @@ -239,12 +230,7 @@ runQuit: avcodec_free_context(&codecCtx); } - emit onDecodeStop(); - - if (m_deviceSocket) { - m_deviceSocket->disconnectFromHost(); - delete m_deviceSocket; - } + emit onDecodeStop(); } void Decoder::pushFrame() diff --git a/src/decoder.h b/src/decoder.h index 36d3a52..ffab273 100644 --- a/src/decoder.h +++ b/src/decoder.h @@ -2,10 +2,10 @@ #define DECODER_H #include #include -#include #include #include +#include "devicesocket.h" extern "C" { #include "libavcodec/avcodec.h" @@ -26,7 +26,7 @@ public: static void deInit(); void setFrames(Frames* frames); - void setDeviceSocket(QTcpSocket* deviceSocket); + void setDeviceSocket(DeviceSocket* deviceSocket); qint32 recvData(quint8* buf, qint32 bufSize); bool startDecode(); void stopDecode(); @@ -40,7 +40,7 @@ protected: void pushFrame(); private: - QPointer m_deviceSocket = Q_NULLPTR; + QPointer m_deviceSocket; QMutex m_mutex; bool m_quit = false; Frames* m_frames; diff --git a/src/devicesocket.cpp b/src/devicesocket.cpp index 5fc85df..82372b3 100644 --- a/src/devicesocket.cpp +++ b/src/devicesocket.cpp @@ -1,13 +1,27 @@ +#include +#include + #include "devicesocket.h" +static const int GetDataEvent = QEvent::registerEventType(QEvent::User+1); +class DeviceSocketEvent : public QEvent +{ +public: + DeviceSocketEvent() : QEvent(QEvent::Type(GetDataEvent)){} +}; + DeviceSocket::DeviceSocket(QObject *parent) : QTcpSocket(parent) { connect(this, &DeviceSocket::readyRead, this, &DeviceSocket::onReadyRead); + connect(this, &DeviceSocket::aboutToClose, this, &DeviceSocket::quitNotify); + connect(this, &DeviceSocket::disconnected, this, &DeviceSocket::quitNotify); + + installEventFilter(this); } DeviceSocket::~DeviceSocket() { - + quitNotify(); } qint32 DeviceSocket::recvData(quint8 *buf, qint32 bufSize) @@ -16,13 +30,30 @@ qint32 DeviceSocket::recvData(quint8 *buf, qint32 bufSize) m_buffer = buf; m_bufferSize = bufSize; + m_dataSize = 0; + // post event + DeviceSocketEvent* getDataEvent = new DeviceSocketEvent(); + QCoreApplication::postEvent(this, getDataEvent); + + // wait while (!m_recvData) { m_recvDataCond.wait(&m_mutex); } + + m_recvData = false; return m_dataSize; } +bool DeviceSocket::eventFilter(QObject *watched, QEvent *event) +{ + if (event->type() == GetDataEvent) { + onReadyRead(); + return true; + } + return false; +} + void DeviceSocket::onReadyRead() { QMutexLocker locker(&m_mutex); @@ -37,3 +68,15 @@ void DeviceSocket::onReadyRead() m_recvDataCond.wakeOne(); } } + +void DeviceSocket::quitNotify() +{ + QMutexLocker locker(&m_mutex); + if (m_buffer) { + m_buffer = Q_NULLPTR; + m_bufferSize = 0; + m_recvData = true; + m_dataSize = 0; + m_recvDataCond.wakeOne(); + } +} diff --git a/src/devicesocket.h b/src/devicesocket.h index d698a78..9101302 100644 --- a/src/devicesocket.h +++ b/src/devicesocket.h @@ -1,6 +1,7 @@ #ifndef DEVICESOCKET_H #define DEVICESOCKET_H +#include #include #include #include @@ -14,10 +15,12 @@ public: qint32 recvData(quint8* buf, qint32 bufSize); -signals: +protected: + bool eventFilter(QObject *watched, QEvent *event); protected slots: void onReadyRead(); + void quitNotify(); private: QMutex m_mutex; diff --git a/src/server.cpp b/src/server.cpp index 7453390..bd3ee7f 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -17,9 +17,8 @@ Server::Server(QObject *parent) : QObject(parent) connect(&m_workProcess, &AdbProcess::adbProcessResult, this, &Server::onWorkProcessResult); connect(&m_serverProcess, &AdbProcess::adbProcessResult, this, &Server::onWorkProcessResult); - connect(&m_serverSocket, &QTcpServer::newConnection, this, [this](){ - m_deviceSocket = m_serverSocket.nextPendingConnection(); - m_deviceSocket->setParent(Q_NULLPTR); + connect(&m_serverSocket, &QTcpServer::newConnection, this, [this](){ + m_deviceSocket = dynamic_cast(m_serverSocket.nextPendingConnection()); QString deviceName; QSize deviceSize; @@ -186,7 +185,7 @@ bool Server::connectTo() QSize deviceSize; bool success = false; - m_deviceSocket = new QTcpSocket(); + m_deviceSocket = new DeviceSocket(); // wait for devices server start m_deviceSocket->connectToHost(QHostAddress::LocalHost, m_localPort); @@ -235,23 +234,17 @@ void Server::timerEvent(QTimerEvent *event) } } -QTcpSocket* Server::getDeviceSocketByThread(QThread* thread) -{ - if (!m_deviceSocket || QThread::currentThread() != m_deviceSocket->thread()) { - return Q_NULLPTR; - } - - if (thread) { - m_deviceSocket->moveToThread(thread); - } - QTcpSocket* devicesSocket = m_deviceSocket; - m_deviceSocket = Q_NULLPTR; - - return devicesSocket; +DeviceSocket* Server::getDeviceSocket() +{ + return m_deviceSocket; } void Server::stop() { + if (m_deviceSocket) { + m_deviceSocket->close(); + m_deviceSocket->deleteLater(); + } // ignore failure m_serverProcess.kill(); if (m_tunnelEnabled) { @@ -267,11 +260,7 @@ void Server::stop() removeServer(); m_serverCopiedToDevice = false; } - m_serverSocket.close(); - if (m_deviceSocket) { - m_deviceSocket->close(); - m_deviceSocket->deleteLater(); - } + m_serverSocket.close(); } bool Server::startServerByStep() diff --git a/src/server.h b/src/server.h index 1e62b13..9324538 100644 --- a/src/server.h +++ b/src/server.h @@ -2,10 +2,10 @@ #define SERVER_H #include -#include -#include #include +#include "tcpServer.h" +#include "devicesocket.h" #include "adbprocess.h" class Server : public QObject @@ -27,9 +27,7 @@ public: bool start(const QString& serial, quint16 localPort, quint16 maxSize, quint32 bitRate, const QString& crop); bool connectTo(); - // you can call this if you will use device socket in sub thread - // must call this in main thread - QTcpSocket* getDeviceSocketByThread(QThread* thread); + DeviceSocket* getDeviceSocket(); void stop(); @@ -63,8 +61,8 @@ private: AdbProcess m_workProcess; QString m_serial = ""; AdbProcess m_serverProcess; - QTcpServer m_serverSocket; // only used if !tunnel_forward - QPointer m_deviceSocket = Q_NULLPTR; + TcpServer m_serverSocket; // only used if !tunnel_forward + QPointer m_deviceSocket = Q_NULLPTR; quint16 m_localPort = 0; bool m_tunnelEnabled = false; bool m_tunnelForward = false; // use "adb forward" instead of "adb reverse" diff --git a/src/tcpserver.cpp b/src/tcpserver.cpp new file mode 100644 index 0000000..fdc9a64 --- /dev/null +++ b/src/tcpserver.cpp @@ -0,0 +1,19 @@ +#include "tcpserver.h" +#include "devicesocket.h" + +TcpServer::TcpServer(QObject *parent) : QTcpServer(parent) +{ + +} + +TcpServer::~TcpServer() +{ + +} + +void TcpServer::incomingConnection(qintptr handle) +{ + DeviceSocket *socket = new DeviceSocket(); + socket->setSocketDescriptor(handle); + addPendingConnection(socket); +} diff --git a/src/tcpserver.h b/src/tcpserver.h new file mode 100644 index 0000000..7156814 --- /dev/null +++ b/src/tcpserver.h @@ -0,0 +1,17 @@ +#ifndef TCPSERVER_H +#define TCPSERVER_H + +#include + +class TcpServer : public QTcpServer +{ + Q_OBJECT +public: + explicit TcpServer(QObject *parent = nullptr); + virtual ~TcpServer(); + +protected: + virtual void incomingConnection(qintptr handle); +}; + +#endif // TCPSERVER_H diff --git a/src/videoform.cpp b/src/videoform.cpp index 73760b1..2034d0d 100644 --- a/src/videoform.cpp +++ b/src/videoform.cpp @@ -32,7 +32,7 @@ VideoForm::VideoForm(QWidget *parent) : } // init decode - m_decoder.setDeviceSocket(m_server->getDeviceSocketByThread(&m_decoder)); + m_decoder.setDeviceSocket(m_server->getDeviceSocket()); m_decoder.startDecode(); } }); @@ -58,12 +58,13 @@ VideoForm::VideoForm(QWidget *parent) : },Qt::QueuedConnection); m_server->start("P7C0218510000537", 27183, 1080, 8000000, ""); + //m_server->start("P7C0218510000537", 27183, 0, 8000000, ""); } VideoForm::~VideoForm() { - m_decoder.stopDecode(); m_server->stop(); + m_decoder.stopDecode(); delete m_server; m_frames.deInit(); delete ui;