mirror of
https://github.com/barry-ran/QtScrcpy.git
synced 2025-04-20 19:44:59 +00:00
refactor: stream and decoder&recorder decoupling
This commit is contained in:
parent
dbbe5297b0
commit
0b39bbc719
7 changed files with 66 additions and 79 deletions
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<quint32>((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]);
|
||||
|
@ -84,11 +79,6 @@ static quint64 bufferRead64be(quint8 *buf)
|
|||
return (static_cast<quint64>(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;
|
||||
}
|
||||
|
|
|
@ -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<qint32(quint8*, qint32)> 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;
|
||||
|
|
Loading…
Add table
Reference in a new issue