From 74b38e9ac57bc8bf37d2d2f7789e2f271e1f41e1 Mon Sep 17 00:00:00 2001 From: Barry <870709864@qq.com> Date: Wed, 6 Apr 2022 09:51:16 +0800 Subject: [PATCH] refactor: stream and decoder&recorder decoupling --- QtScrcpy/device/decoder/decoder.cpp | 21 ++++++---- QtScrcpy/device/decoder/decoder.h | 3 +- QtScrcpy/device/device.cpp | 43 ++++++++++++++++--- QtScrcpy/device/recorder/recorder.cpp | 9 +++- QtScrcpy/device/recorder/recorder.h | 2 +- QtScrcpy/device/stream/stream.cpp | 60 ++------------------------- QtScrcpy/device/stream/stream.h | 7 +--- 7 files changed, 66 insertions(+), 79 deletions(-) diff --git a/QtScrcpy/device/decoder/decoder.cpp b/QtScrcpy/device/decoder/decoder.cpp index c6d727e..5218810 100644 --- a/QtScrcpy/device/decoder/decoder.cpp +++ b/QtScrcpy/device/decoder/decoder.cpp @@ -8,8 +8,16 @@ Decoder::Decoder(VideoBuffer *vb, QObject *parent) : QObject(parent), m_vb(vb) { Decoder::~Decoder() {} -bool Decoder::open(const AVCodec *codec) +bool Decoder::open() { + // codec + AVCodec *codec = Q_NULLPTR; + codec = avcodec_find_decoder(AV_CODEC_ID_H264); + if (!codec) { + qCritical("H.264 decoder not found"); + return false; + } + // codec context m_codecCtx = avcodec_alloc_context3(codec); if (!m_codecCtx) { @@ -26,6 +34,10 @@ bool Decoder::open(const AVCodec *codec) void Decoder::close() { + if (m_vb) { + m_vb->interrupt(); + } + if (!m_codecCtx) { return; } @@ -98,13 +110,6 @@ bool Decoder::push(const AVPacket *packet) return true; } -void Decoder::interrupt() -{ - if (m_vb) { - m_vb->interrupt(); - } -} - void Decoder::pushFrame() { if (!m_vb) { diff --git a/QtScrcpy/device/decoder/decoder.h b/QtScrcpy/device/decoder/decoder.h index 5497a09..cdde67c 100644 --- a/QtScrcpy/device/decoder/decoder.h +++ b/QtScrcpy/device/decoder/decoder.h @@ -15,10 +15,9 @@ public: Decoder(VideoBuffer *vb, QObject *parent = Q_NULLPTR); virtual ~Decoder(); - bool open(const AVCodec *codec); + bool open(); void close(); bool push(const AVPacket *packet); - void interrupt(); signals: void onNewFrame(); diff --git a/QtScrcpy/device/device.cpp b/QtScrcpy/device/device.cpp index 9980a75..664ea5d 100644 --- a/QtScrcpy/device/device.cpp +++ b/QtScrcpy/device/device.cpp @@ -45,13 +45,10 @@ Device::Device(DeviceParams params, QObject *parent) : QObject(parent), m_params return videoSocket->subThreadRecvData(buf, bufSize); }, 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(); @@ -62,12 +59,22 @@ Device::~Device() if (m_server) { m_server->stop(); } - // server must stop before decoder, because decoder block main thread + if (m_stream) { m_stream->stopDecode(); } + // server must stop before decoder, because decoder block main thread + if (m_decoder) { + m_decoder->close(); + } + if (m_recorder) { + if (m_recorder->isRunning()) { + m_recorder->stopRecorder(); + m_recorder->wait(); + } + m_recorder->close(); delete m_recorder; } if (m_vb) { @@ -249,6 +256,18 @@ void Device::initSignals() // init recorder if (m_recorder) { m_recorder->setFrameSize(size); + if (!m_recorder->open()) { + qCritical("Could not open recorder"); + } + + if (!m_recorder->startRecorder()) { + qCritical("Could not start recorder"); + } + } + + // init decoder + if (m_decoder) { + m_decoder->open(); } // init decoder @@ -276,6 +295,20 @@ void Device::initSignals() deleteLater(); qDebug() << "stream thread stop"; }); + connect(m_stream, &Stream::getFrame, this, [this](AVPacket *packet) { + if (m_decoder && !m_decoder->push(packet)) { + qCritical("Could not send packet to decoder"); + } + + if (m_recorder && !m_recorder->push(packet)) { + qCritical("Could not send packet to recorder"); + } + }, Qt::DirectConnection); + connect(m_stream, &Stream::getConfigFrame, this, [this](AVPacket *packet) { + if (m_recorder && !m_recorder->push(packet)) { + qCritical("Could not send config packet to recorder"); + } + }, Qt::DirectConnection); } if (m_decoder && m_vb) { diff --git a/QtScrcpy/device/recorder/recorder.cpp b/QtScrcpy/device/recorder/recorder.cpp index a8130af..41ac095 100644 --- a/QtScrcpy/device/recorder/recorder.cpp +++ b/QtScrcpy/device/recorder/recorder.cpp @@ -51,8 +51,15 @@ void Recorder::setFormat(Recorder::RecorderFormat format) m_format = format; } -bool Recorder::open(const AVCodec *inputCodec) +bool Recorder::open() { + // codec + AVCodec* inputCodec = avcodec_find_decoder(AV_CODEC_ID_H264); + if (!inputCodec) { + qCritical("H.264 decoder not found"); + return false; + } + QString formatName = recorderGetFormatName(m_format); Q_ASSERT(!formatName.isEmpty()); const AVOutputFormat *format = findMuxer(formatName.toUtf8()); diff --git a/QtScrcpy/device/recorder/recorder.h b/QtScrcpy/device/recorder/recorder.h index 1691f38..db1c0b7 100644 --- a/QtScrcpy/device/recorder/recorder.h +++ b/QtScrcpy/device/recorder/recorder.h @@ -28,7 +28,7 @@ public: void setFrameSize(const QSize &declaredFrameSize); void setFormat(Recorder::RecorderFormat format); - bool open(const AVCodec *inputCodec); + bool open(); void close(); bool write(AVPacket *packet); bool startRecorder(); diff --git a/QtScrcpy/device/stream/stream.cpp b/QtScrcpy/device/stream/stream.cpp index 4fe35ff..3328c5e 100644 --- a/QtScrcpy/device/stream/stream.cpp +++ b/QtScrcpy/device/stream/stream.cpp @@ -67,11 +67,6 @@ void Stream::deInit() avformat_network_deinit(); // ignore failure } -void Stream::setDecoder(Decoder *decoder) -{ - m_decoder = decoder; -} - static quint32 bufferRead32be(quint8 *buf) { return static_cast((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]); @@ -84,11 +79,6 @@ static quint64 bufferRead64be(quint8 *buf) return (static_cast(msb) << 32) | lsb; } -void Stream::setRecoder(Recorder *recorder) -{ - m_recorder = recorder; -} - qint32 Stream::recvData(quint8 *buf, qint32 bufSize) { if (!buf || !m_recvData) { @@ -110,9 +100,6 @@ bool Stream::startDecode() void Stream::stopDecode() { - if (m_decoder) { - m_decoder->interrupt(); - } wait(); } @@ -136,23 +123,6 @@ void Stream::run() goto runQuit; } - if (m_decoder && !m_decoder->open(codec)) { - qCritical("Could not open m_decoder"); - goto runQuit; - } - - if (m_recorder) { - if (!m_recorder->open(codec)) { - qCritical("Could not open recorder"); - goto runQuit; - } - - if (!m_recorder->startRecorder()) { - qCritical("Could not start recorder"); - goto runQuit; - } - } - m_parser = av_parser_init(AV_CODEC_ID_H264); if (!m_parser) { qCritical("Could not initialize parser"); @@ -188,16 +158,6 @@ void Stream::run() av_parser_close(m_parser); runQuit: - if (m_recorder) { - if (m_recorder->isRunning()) { - m_recorder->stopRecorder(); - m_recorder->wait(); - } - m_recorder->close(); - } - if (m_decoder) { - m_decoder->close(); - } if (m_codecCtx) { avcodec_free_context(&m_codecCtx); } @@ -305,10 +265,7 @@ bool Stream::pushPacket(AVPacket *packet) bool Stream::processConfigPacket(AVPacket *packet) { - if (m_recorder && !m_recorder->push(packet)) { - qCritical("Could not send config packet to recorder"); - return false; - } + emit getConfigFrame(packet); return true; } @@ -340,18 +297,7 @@ bool Stream::parse(AVPacket *packet) bool Stream::processFrame(AVPacket *packet) { - if (m_decoder && !m_decoder->push(packet)) { - return false; - } - - if (m_recorder) { - packet->dts = packet->pts; - - if (!m_recorder->push(packet)) { - qCritical("Could not send packet to recorder"); - return false; - } - } - + packet->dts = packet->pts; + emit getFrame(packet); return true; } diff --git a/QtScrcpy/device/stream/stream.h b/QtScrcpy/device/stream/stream.h index 839d04f..c58dac4 100644 --- a/QtScrcpy/device/stream/stream.h +++ b/QtScrcpy/device/stream/stream.h @@ -24,13 +24,13 @@ public: static bool init(); static void deInit(); - void setDecoder(Decoder *decoder); - void setRecoder(Recorder *recorder); bool startDecode(); void stopDecode(); signals: void onStreamStop(); + void getFrame(AVPacket* packet); + void getConfigFrame(AVPacket* packet); protected: void run(); @@ -43,9 +43,6 @@ protected: private: std::function m_recvData = nullptr; - // for recorder - Recorder *m_recorder = Q_NULLPTR; - Decoder *m_decoder = Q_NULLPTR; AVCodecContext *m_codecCtx = Q_NULLPTR; AVCodecParserContext *m_parser = Q_NULLPTR;