修改decode recvdata流程

This commit is contained in:
Barry 2018-11-05 22:18:20 +08:00
parent 6ddbf115e9
commit b9764cc68f
10 changed files with 113 additions and 55 deletions

View file

@ -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 \

View file

@ -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()

View file

@ -2,10 +2,10 @@
#define DECODER_H
#include <functional>
#include <QThread>
#include <QTcpSocket>
#include <QPointer>
#include <QMutex>
#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<QTcpSocket> m_deviceSocket = Q_NULLPTR;
QPointer<DeviceSocket> m_deviceSocket;
QMutex m_mutex;
bool m_quit = false;
Frames* m_frames;

View file

@ -1,13 +1,27 @@
#include <QCoreApplication>
#include <QDebug>
#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();
}
}

View file

@ -1,6 +1,7 @@
#ifndef DEVICESOCKET_H
#define DEVICESOCKET_H
#include <QEvent>
#include <QTcpSocket>
#include <QMutex>
#include <QWaitCondition>
@ -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;

View file

@ -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<DeviceSocket*>(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()

View file

@ -2,10 +2,10 @@
#define SERVER_H
#include <QObject>
#include <QTcpSocket>
#include <QTcpServer>
#include <QPointer>
#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<QTcpSocket> m_deviceSocket = Q_NULLPTR;
TcpServer m_serverSocket; // only used if !tunnel_forward
QPointer<DeviceSocket> m_deviceSocket = Q_NULLPTR;
quint16 m_localPort = 0;
bool m_tunnelEnabled = false;
bool m_tunnelForward = false; // use "adb forward" instead of "adb reverse"

19
src/tcpserver.cpp Normal file
View file

@ -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);
}

17
src/tcpserver.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include <QTcpServer>
class TcpServer : public QTcpServer
{
Q_OBJECT
public:
explicit TcpServer(QObject *parent = nullptr);
virtual ~TcpServer();
protected:
virtual void incomingConnection(qintptr handle);
};
#endif // TCPSERVER_H

View file

@ -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;