From efecb01edfe446d8f0cf7138dd818d5e282f69fd Mon Sep 17 00:00:00 2001 From: Barry <870709864@qq.com> Date: Mon, 5 Nov 2018 00:10:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/QtScrcpy.pro | 9 ++-- src/decoder.cpp | 4 +- src/decoder.h | 3 +- src/dialog.cpp | 89 ++++++---------------------------------- src/dialog.h | 11 ++--- src/dialog.ui | 4 +- src/fpscounter.cpp | 2 +- src/main.cpp | 16 +++++--- src/qyuvopenglwidget.cpp | 37 +++++++++-------- src/qyuvopenglwidget.h | 1 + src/videoform.cpp | 87 +++++++++++++++++++++++++++++++++++++++ src/videoform.h | 32 +++++++++++++++ src/videoform.ui | 47 +++++++++++++++++++++ 13 files changed, 228 insertions(+), 114 deletions(-) create mode 100644 src/videoform.cpp create mode 100644 src/videoform.h create mode 100644 src/videoform.ui diff --git a/src/QtScrcpy.pro b/src/QtScrcpy.pro index f9cc0e9..0a8e23c 100644 --- a/src/QtScrcpy.pro +++ b/src/QtScrcpy.pro @@ -34,7 +34,8 @@ SOURCES += \ convert.cpp \ frames.cpp \ fpscounter.cpp \ - qyuvopenglwidget.cpp + qyuvopenglwidget.cpp \ + videoform.cpp HEADERS += \ dialog.h \ @@ -44,10 +45,12 @@ HEADERS += \ convert.h \ frames.h \ fpscounter.h \ - qyuvopenglwidget.h + qyuvopenglwidget.h \ + videoform.h FORMS += \ - dialog.ui + dialog.ui \ + videoform.ui INCLUDEPATH += \ $$PWD/ffmpeg/include diff --git a/src/decoder.cpp b/src/decoder.cpp index 68adda6..25ee450 100644 --- a/src/decoder.cpp +++ b/src/decoder.cpp @@ -239,6 +239,8 @@ runQuit: avcodec_free_context(&codecCtx); } + emit onDecodeStop(); + if (m_deviceSocket) { m_deviceSocket->disconnectFromHost(); delete m_deviceSocket; @@ -252,5 +254,5 @@ void Decoder::pushFrame() // the previous newFrame will consume this frame return; } - emit newFrame(); + emit onNewFrame(); } diff --git a/src/decoder.h b/src/decoder.h index 572b346..36d3a52 100644 --- a/src/decoder.h +++ b/src/decoder.h @@ -32,7 +32,8 @@ public: void stopDecode(); signals: - void newFrame(); + void onNewFrame(); + void onDecodeStop(); protected: void run(); diff --git a/src/dialog.cpp b/src/dialog.cpp index 43e30b1..30f57d8 100644 --- a/src/dialog.cpp +++ b/src/dialog.cpp @@ -4,87 +4,19 @@ #include "dialog.h" #include "ui_dialog.h" #include "adbprocess.h" -#include "qyuvopenglwidget.h" - -void saveAVFrame_YUV_ToTempFile(const AVFrame *pFrame) -{ - int t_frameWidth = pFrame->width; - int t_frameHeight = pFrame->height; - int t_yPerRowBytes = pFrame->linesize[0]; - int t_uPerRowBytes = pFrame->linesize[1]; - int t_vPerRowBytes = pFrame->linesize[2]; - qDebug()<<"robin:saveAVFrame_YUV_ToTempFile info:"<data[0],t_frameWidth * t_frameHeight); - //t_file.write((char *)pFrame->data[1],(t_frameWidth/2) * t_frameHeight / 2); - //t_file.write((char *)pFrame->data[2],(t_frameWidth/2) * t_frameHeight / 2); - - for(int i = 0;i< t_frameHeight ;i++) - { - t_file.write((char*)(pFrame->data[0]+i*t_yPerRowBytes),t_frameWidth); - } - - for(int i = 0;i< t_frameHeight/2 ;i++) - { - t_file.write((char*)(pFrame->data[1]+i*t_uPerRowBytes),t_frameWidth/2); - } - - for(int i = 0;i< t_frameHeight/2 ;i++) - { - t_file.write((char*)(pFrame->data[2]+i*t_vPerRowBytes),t_frameWidth/2); - } - - t_file.flush(); - -} Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); - setWindowFlags(windowFlags() - | Qt::WindowMaximizeButtonHint - | Qt::WindowMinimizeButtonHint); - - w = new QYUVOpenGLWidget(this); - ui->verticalLayout->addWidget(w); - - Decoder::init(); - - frames.init(); - decoder.setFrames(&frames); - - server = new Server(); - connect(server, &Server::serverStartResult, this, [this](bool success){ - if (success) { - server->connectTo(); - } - }); - - connect(server, &Server::connectToResult, this, [this](bool success){ - if (success) { - decoder.setDeviceSocket(server->getDeviceSocketByThread(&decoder)); - decoder.startDecode(); - } - }); - - // must be Qt::QueuedConnection, ui update must be main thread - QObject::connect(&decoder, &Decoder::newFrame, this, [this](){ - frames.lock(); - const AVFrame *frame = frames.consumeRenderedFrame(); - //saveAVFrame_YUV_ToTempFile(frame); - w->setFrameSize(QSize(frame->width, frame->height)); - w->updateTextures(frame->data[0], frame->data[1], frame->data[2], frame->linesize[0], frame->linesize[1], frame->linesize[2]); - frames.unLock(); - },Qt::QueuedConnection); + setAttribute(Qt::WA_DeleteOnClose); + //setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint); } Dialog::~Dialog() -{ - Decoder::deInit(); - frames.deInit(); +{ + on_stopServerBtn_clicked(); delete ui; } @@ -99,12 +31,15 @@ void Dialog::on_adbProcess_clicked() void Dialog::on_startServerBtn_clicked() { - server->start("P7C0218510000537", 27183, 0, 8000000, ""); - //server->start("P7CDU17C23010875", 27183, 0, 8000000, ""); + if (!m_videoForm) { + m_videoForm = new VideoForm(); + } + m_videoForm->show(); } void Dialog::on_stopServerBtn_clicked() -{ - decoder.stopDecode(); - server->stop(); +{ + if (m_videoForm) { + m_videoForm->close(); + } } diff --git a/src/dialog.h b/src/dialog.h index 17fbf41..d61f600 100644 --- a/src/dialog.h +++ b/src/dialog.h @@ -2,10 +2,9 @@ #define DIALOG_H #include +#include -#include "server.h" -#include "decoder.h" -#include "frames.h" +#include "videoform.h" namespace Ui { class Dialog; @@ -29,10 +28,8 @@ private slots: private: Ui::Dialog *ui; - Server* server; - Decoder decoder; - Frames frames; - QYUVOpenGLWidget* w; + + QPointer m_videoForm; }; #endif // DIALOG_H diff --git a/src/dialog.ui b/src/dialog.ui index 1c02c34..e992565 100644 --- a/src/dialog.ui +++ b/src/dialog.ui @@ -6,8 +6,8 @@ 0 0 - 1100 - 712 + 354 + 81 diff --git a/src/fpscounter.cpp b/src/fpscounter.cpp index 43deed2..2cf0781 100644 --- a/src/fpscounter.cpp +++ b/src/fpscounter.cpp @@ -46,7 +46,7 @@ void FpsCounter::timerEvent(QTimerEvent *event) m_curRendered = m_rendered; m_curSkipped = m_skipped; resetCounter(); - qInfo("FPS:%d Discard:%d", m_curRendered, m_skipped); + //qInfo("FPS:%d Discard:%d", m_curRendered, m_skipped); } } diff --git a/src/main.cpp b/src/main.cpp index ad9a0dd..bec5615 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,24 +1,28 @@ -#include "dialog.h" - #include #include #include #include +#include "dialog.h" +#include "decoder.h" + int main(int argc, char *argv[]) { //QApplication::setAttribute(Qt::AA_UseDesktopOpenGL); //QApplication::setAttribute(Qt::AA_UseOpenGLES); //QApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); + Decoder::init(); QApplication a(argc, argv); qputenv("QTSCRCPY_ADB_PATH", "G:\\mygitcode\\QtScrcpy\\src\\adb.exe"); qputenv("QTSCRCPY_SERVER_PATH", "G:\\mygitcode\\QtScrcpy\\src\\scrcpy-server.jar"); - Dialog w; - //w.move(50, 930); - w.show(); + Dialog* w = new Dialog; + w->show(); - return a.exec(); + int ret = a.exec(); + + Decoder::deInit(); + return ret; } diff --git a/src/qyuvopenglwidget.cpp b/src/qyuvopenglwidget.cpp index cc81cf0..d620fe4 100644 --- a/src/qyuvopenglwidget.cpp +++ b/src/qyuvopenglwidget.cpp @@ -90,15 +90,19 @@ void QYUVOpenGLWidget::setFrameSize(const QSize &frameSize) if (m_frameSize != frameSize) { m_frameSize = frameSize; m_needUpdate = true; + // inittexture immediately + repaint(); } } void QYUVOpenGLWidget::updateTextures(quint8 *dataY, quint8 *dataU, quint8 *dataV, quint32 linesizeY, quint32 linesizeU, quint32 linesizeV) { - updateTexture(m_texture[0], 0, dataY, linesizeY); - updateTexture(m_texture[1], 1, dataU, linesizeU); - updateTexture(m_texture[2], 2, dataV, linesizeV); - update(); + if (m_textureInited) { + updateTexture(m_texture[0], 0, dataY, linesizeY); + updateTexture(m_texture[1], 1, dataU, linesizeU); + updateTexture(m_texture[2], 2, dataV, linesizeV); + update(); + } } void QYUVOpenGLWidget::initializeGL() @@ -114,36 +118,35 @@ void QYUVOpenGLWidget::initializeGL() // 设置背景清理色为黑色 glClearColor(0.0,0.0,0.0,0.0); // 清理颜色背景 - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); } void QYUVOpenGLWidget::paintGL() { if (m_needUpdate) { - //TODO 需要deInitTextures吗 deInitTextures(); initTextures(); m_needUpdate = false; } - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_texture[0]); + if (m_textureInited) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_texture[0]); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, m_texture[1]); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, m_texture[1]); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, m_texture[2]); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, m_texture[2]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - // 没有画面则显示黑屏 - //glClear(GL_COLOR_BUFFER_BIT); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } } void QYUVOpenGLWidget::resizeGL(int width, int height) { glViewport(0, 0, width, height); + repaint(); } void QYUVOpenGLWidget::initShader() @@ -208,12 +211,14 @@ void QYUVOpenGLWidget::initTextures() glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_frameSize.width()/2, m_frameSize.height()/2, 0, GL_RED, GL_UNSIGNED_BYTE, NULL); + m_textureInited = true; } void QYUVOpenGLWidget::deInitTextures() { glDeleteTextures(3, m_texture); memset(m_texture, 0, 3); + m_textureInited = false; } void QYUVOpenGLWidget::updateTexture(GLuint texture, quint32 textureType, quint8 *pixels, quint32 stride) diff --git a/src/qyuvopenglwidget.h b/src/qyuvopenglwidget.h index deeebee..c67d120 100644 --- a/src/qyuvopenglwidget.h +++ b/src/qyuvopenglwidget.h @@ -33,6 +33,7 @@ private: // 视频帧尺寸 QSize m_frameSize = {-1, -1}; bool m_needUpdate = false; + bool m_textureInited = false; // 顶点缓冲对象(Vertex Buffer Objects, VBO):默认即为VertexBuffer(GL_ARRAY_BUFFER)类型 QOpenGLBuffer m_vbo; diff --git a/src/videoform.cpp b/src/videoform.cpp new file mode 100644 index 0000000..7f0849a --- /dev/null +++ b/src/videoform.cpp @@ -0,0 +1,87 @@ +#include + +#include "videoform.h" +#include "ui_videoform.h" + +VideoForm::VideoForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::videoForm) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + m_server = new Server(); + m_frames.init(); + m_decoder.setFrames(&m_frames); + + connect(m_server, &Server::serverStartResult, this, [this](bool success){ + if (success) { + m_server->connectTo(); + } + }); + + connect(m_server, &Server::connectToResult, this, [this](bool success, const QString &deviceName, const QSize &size){ + if (success) { + setWindowTitle(deviceName); + + updateShowSize(size); + // 双屏有问题,位置有问题 + QDesktopWidget* desktop = QApplication::desktop(); + if (desktop) { + QSize screenSize = desktop->size(); + if (!screenSize.isEmpty()) { + move((screenSize.width() - width())/2, (screenSize.height() - height())/2); + } + } + + m_decoder.setDeviceSocket(m_server->getDeviceSocketByThread(&m_decoder)); + m_decoder.startDecode(); + } + }); + + connect(m_server, &Server::onServerStop, this, [this](){ + close(); + qDebug() << "server process stop"; + }); + + connect(&m_decoder, &Decoder::onDecodeStop, this, [this](){ + close(); + qDebug() << "decoder thread stop"; + }); + + // must be Qt::QueuedConnection, ui update must be main thread + QObject::connect(&m_decoder, &Decoder::onNewFrame, this, [this](){ + m_frames.lock(); + const AVFrame *frame = m_frames.consumeRenderedFrame(); + updateShowSize(QSize(frame->width, frame->height)); + ui->videoWidget->setFrameSize(QSize(frame->width, frame->height)); + ui->videoWidget->updateTextures(frame->data[0], frame->data[1], frame->data[2], frame->linesize[0], frame->linesize[1], frame->linesize[2]); + m_frames.unLock(); + },Qt::QueuedConnection); + + m_server->start("P7C0218510000537", 27183, 1080, 8000000, ""); +} + +VideoForm::~VideoForm() +{ + m_decoder.stopDecode(); + m_server->stop(); + delete m_server; + m_frames.deInit(); + delete ui; +} + +void VideoForm::updateShowSize(const QSize &newSize) +{ + QSize showSize = newSize; + QDesktopWidget* desktop = QApplication::desktop(); + if (desktop) { + QSize screenSize = desktop->size(); + showSize.setWidth(qMin(newSize.width(), screenSize.width())); + showSize.setHeight(qMin(newSize.height(), screenSize.height() - 100)); + } + + if (showSize != size()) { + resize(showSize); + } +} diff --git a/src/videoform.h b/src/videoform.h new file mode 100644 index 0000000..02a3ed3 --- /dev/null +++ b/src/videoform.h @@ -0,0 +1,32 @@ +#ifndef VIDEOFORM_H +#define VIDEOFORM_H + +#include + +#include "server.h" +#include "decoder.h" +#include "frames.h" + +namespace Ui { +class videoForm; +} + +class VideoForm : public QWidget +{ + Q_OBJECT + +public: + explicit VideoForm(QWidget *parent = 0); + ~VideoForm(); + +private: + void updateShowSize(const QSize &newSize); + +private: + Ui::videoForm *ui; + Server* m_server = Q_NULLPTR; + Decoder m_decoder; + Frames m_frames; +}; + +#endif // VIDEOFORM_H diff --git a/src/videoform.ui b/src/videoform.ui new file mode 100644 index 0000000..cce5644 --- /dev/null +++ b/src/videoform.ui @@ -0,0 +1,47 @@ + + + videoForm + + + + 0 + 0 + 454 + 908 + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + QYUVOpenGLWidget + QWidget +
qyuvopenglwidget.h
+ 1 +
+
+ + +