You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
6.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <QTimer>
#include <QMessageBox>
#include "device.h"
#include "recorder.h"
#include "server.h"
#include "videobuffer.h"
#include "decoder.h"
#include "filehandler.h"
#include "stream.h"
#include "videoform.h"
#include "controller.h"
#include "config.h"
Device::Device(DeviceParams params, QObject *parent)
: QObject(parent)
, m_params(params)
{
if (!params.display && m_params.recordFileName.trimmed().isEmpty()) {
qCritical("not display must be recorded");
deleteLater();
return;
}
if (params.display) {
m_vb = new VideoBuffer();
m_vb->init();
m_decoder = new Decoder(m_vb, this);
m_fileHandler = new FileHandler(this);
m_controller = new Controller(params.gameScript, this);
m_videoForm = new VideoForm(Config::getInstance().getSkin());
m_videoForm->setSerial(m_params.serial);
if (m_controller) {
m_videoForm->setController(m_controller);
}
if (m_fileHandler) {
m_videoForm->setFileHandler(m_fileHandler);
}
m_videoForm->show();
}
m_stream = new Stream(this);
if (m_decoder) {
m_stream->setDecoder(m_decoder);
}
m_server = new Server(this);
if (!m_params.recordFileName.trimmed().isEmpty()) {
m_recorder = new Recorder(m_params.recordFileName);
m_stream->setRecoder(m_recorder);
}
initSignals();
startServer();
}
Device::~Device()
{
if (m_server) {
m_server->stop();
}
// server must stop before decoder, because decoder block main thread
if (m_stream) {
m_stream->stopDecode();
}
if (m_recorder) {
delete m_recorder;
}
if (m_vb) {
m_vb->deInit();
delete m_vb;
}
if (m_videoForm) {
delete m_videoForm;
}
emit deviceDisconnect(m_params.serial);
}
VideoForm *Device::getVideoForm()
{
return m_videoForm;
}
Controller *Device::getController()
{
return m_controller;
}
Server *Device::getServer()
{
return m_server;
}
void Device::updateScript(QString script)
{
if(m_controller){
m_controller->updateScript(script);
}
}
void Device::initSignals()
{
if (m_controller && m_videoForm) {
connect(m_controller, &Controller::grabCursor, m_videoForm, &VideoForm::onGrabCursor);
}
if (m_videoForm) {
connect(m_videoForm, &VideoForm::destroyed, this, [this](QObject *obj){
Q_UNUSED(obj)
deleteLater();
});
}
if (m_fileHandler) {
connect(m_fileHandler, &FileHandler::fileHandlerResult, this, [this](FileHandler::FILE_HANDLER_RESULT processResult, bool isApk){
QString tips = "";
if (isApk) {
tips = tr("install apk");
} else {
tips = tr("file transfer");
}
if (FileHandler::FAR_IS_RUNNING == processResult && m_videoForm) {
QMessageBox::warning(m_videoForm, "QtScrcpy", tr("wait current %1 to complete").arg(tips), QMessageBox::Ok);
}
if (FileHandler::FAR_SUCCESS_EXEC == processResult && m_videoForm) {
QMessageBox::information(m_videoForm, "QtScrcpy", tr("%1 complete, save in %2").arg(tips).arg(Config::getInstance().getPushFilePath()), QMessageBox::Ok);
}
if (FileHandler::FAR_ERROR_EXEC == processResult && m_videoForm) {
QMessageBox::information(m_videoForm, "QtScrcpy", tr("%1 failed").arg(tips), QMessageBox::Ok);
}
});
}
if (m_server) {
connect(m_server, &Server::serverStartResult, this, [this](bool success){
if (success) {
m_server->connectTo();
} else {
deleteLater();
}
});
connect(m_server, &Server::connectToResult, this, [this](bool success, const QString &deviceName, const QSize &size){
if (success) {
float diff = m_startTimeCount.elapsed() / 1000.0f;
qInfo(QString("server start finish in %1s").arg(diff).toStdString().c_str());
// update ui
if (m_videoForm) {
m_videoForm->setWindowTitle(deviceName);
m_videoForm->updateScreenRatio(size);
m_videoForm->updateShowSize(size);
}
// init recorder
if (m_recorder) {
m_recorder->setFrameSize(size);
}
// init decoder
m_stream->setVideoSocket(m_server->getVideoSocket());
m_stream->startDecode();
// init controller
if (m_controller) {
m_controller->setControlSocket(m_server->getControlSocket());
}
// 显示界面时才自动息屏m_params.display
if (m_params.closeScreen && m_params.display && m_controller) {
m_controller->setScreenPowerMode(ControlMsg::SPM_OFF);
}
}
});
connect(m_server, &Server::onServerStop, this, [this](){
deleteLater();
qDebug() << "server process stop";
});
}
if (m_stream) {
connect(m_stream, &Stream::onStreamStop, this, [this](){
deleteLater();
qDebug() << "stream thread stop";
});
}
if (m_decoder && m_vb) {
// must be Qt::QueuedConnection, ui update must be main thread
connect(m_decoder, &Decoder::onNewFrame, this, [this](){
m_vb->lock();
const AVFrame *frame = m_vb->consumeRenderedFrame();
if (m_videoForm) {
m_videoForm->updateRender(frame);
}
m_vb->unLock();
},Qt::QueuedConnection);
}
}
void Device::startServer()
{
// fix: macos cant recv finished signel, timer is ok
QTimer::singleShot(0, this, [this](){
m_startTimeCount.start();
// max size support 480p 720p 1080p 设备原生分辨率
// support wireless connect, example:
//m_server->start("192.168.0.174:5555", 27183, m_maxSize, m_bitRate, "");
// only one devices, serial can be null
// mark: crop input format: "width:height:x:y" or - for no crop, for example: "100:200:0:0"
Server::ServerParams params;
params.serial = m_params.serial;
params.localPort = m_params.localPort;
params.maxSize = m_params.maxSize;
params.bitRate = m_params.bitRate;
params.maxFps = m_params.maxFps;
params.crop = "-";
params.control = true;
params.useReverse = m_params.useReverse;
m_server->start(params);
});
}