From c7935bccaa794a4bcb8f067749794f98b6b94bdf Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Sun, 3 Dec 2023 13:42:02 +0100 Subject: [PATCH] Introduce QAVIODevice::setBufferSize() --- examples/qml_video/main.cpp | 11 ++--- examples/qml_video/qml.qrc | 1 + src/QtAVPlayer/QtAVPlayer.pri | 2 +- src/QtAVPlayer/qavdemuxer.cpp | 2 +- src/QtAVPlayer/qaviodevice.cpp | 42 ++++++++++++------- .../{qaviodevice_p.h => qaviodevice.h} | 17 +++----- src/QtAVPlayer/qavplayer.cpp | 11 +++-- src/QtAVPlayer/qavplayer.h | 4 +- .../integration/qavdemuxer/tst_qavdemuxer.cpp | 10 ++--- .../integration/qavplayer/tst_qavplayer.cpp | 32 +++++++------- 10 files changed, 71 insertions(+), 61 deletions(-) rename src/QtAVPlayer/{qaviodevice_p.h => qaviodevice.h} (72%) diff --git a/examples/qml_video/main.cpp b/examples/qml_video/main.cpp index 8a402680..5a8195f6 100644 --- a/examples/qml_video/main.cpp +++ b/examples/qml_video/main.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #include #include @@ -168,13 +169,13 @@ int main(int argc, char *argv[]) } }); - std::unique_ptr qrc; + QSharedPointer qrc; if (file.startsWith(":/")) { - qrc = std::make_unique(file); - if (!qrc->open(QIODevice::ReadOnly)) - qrc.reset(); + QSharedPointer io(new QFile(file)); + if (io->open(QIODevice::ReadOnly)) + qrc.reset(new QAVIODevice(io)); } - p.setSource(file, qrc.get()); + p.setSource(file, qrc); p.setFilter(filter); //p.setSynced(false); diff --git a/examples/qml_video/qml.qrc b/examples/qml_video/qml.qrc index 5f6483ac..f85f45d7 100644 --- a/examples/qml_video/qml.qrc +++ b/examples/qml_video/qml.qrc @@ -1,5 +1,6 @@ main.qml + ../../tests/auto/integration/testdata/20190821_075842.jpg diff --git a/src/QtAVPlayer/QtAVPlayer.pri b/src/QtAVPlayer/QtAVPlayer.pri index eb08cce0..4382be69 100644 --- a/src/QtAVPlayer/QtAVPlayer.pri +++ b/src/QtAVPlayer/QtAVPlayer.pri @@ -29,10 +29,10 @@ PRIVATE_HEADERS += \ $$PWD/qavaudioinputfilter_p.h \ $$PWD/qavvideooutputfilter_p.h \ $$PWD/qavaudiooutputfilter_p.h \ - $$PWD/qaviodevice_p.h \ $$PWD/qavfilters_p.h PUBLIC_HEADERS += \ + $$PWD/qaviodevice.h \ $$PWD/qavaudioformat.h \ $$PWD/qavstreamframe.h \ $$PWD/qavframe.h \ diff --git a/src/QtAVPlayer/qavdemuxer.cpp b/src/QtAVPlayer/qavdemuxer.cpp index 307b7b77..dd41be85 100644 --- a/src/QtAVPlayer/qavdemuxer.cpp +++ b/src/QtAVPlayer/qavdemuxer.cpp @@ -10,7 +10,7 @@ #include "qavaudiocodec_p.h" #include "qavsubtitlecodec_p.h" #include "qavhwdevice_p.h" -#include "qaviodevice_p.h" +#include "qaviodevice.h" #include #if defined(QT_AVPLAYER_VA_X11) && QT_CONFIG(opengl) diff --git a/src/QtAVPlayer/qaviodevice.cpp b/src/QtAVPlayer/qaviodevice.cpp index ad7ee0a4..1888bd56 100644 --- a/src/QtAVPlayer/qaviodevice.cpp +++ b/src/QtAVPlayer/qaviodevice.cpp @@ -5,7 +5,7 @@ * Free Qt Media Player based on FFmpeg. * *********************************************************/ -#include "qaviodevice_p.h" +#include "qaviodevice.h" #include #include @@ -30,13 +30,13 @@ class QAVIODevicePrivate { Q_DECLARE_PUBLIC(QAVIODevice) public: - explicit QAVIODevicePrivate(QAVIODevice *q, QIODevice &device) + explicit QAVIODevicePrivate(QAVIODevice *q, const QSharedPointer &device) : q_ptr(q) , device(device) , buffer(static_cast(av_malloc(buffer_size))) - , ctx(avio_alloc_context(buffer, static_cast(buffer_size), 0, this, &QAVIODevicePrivate::read, nullptr, !device.isSequential() ? &QAVIODevicePrivate::seek : nullptr)) + , ctx(avio_alloc_context(buffer, static_cast(buffer_size), 0, this, &QAVIODevicePrivate::read, nullptr, !device->isSequential() ? &QAVIODevicePrivate::seek : nullptr)) { - if (!device.isSequential()) + if (!device->isSequential()) ctx->seekable = AVIO_SEEKABLE_NORMAL; } @@ -52,7 +52,7 @@ class QAVIODevicePrivate if (readRequest.data == nullptr || readRequest.wroteBytes) return; - readRequest.wroteBytes = !device.atEnd() ? device.read((char *)readRequest.data, readRequest.maxSize) : AVERROR_EOF; + readRequest.wroteBytes = !device->atEnd() ? device->read((char *)readRequest.data, readRequest.maxSize) : AVERROR_EOF; // Unblock the decoder thread when there is available bytes if (readRequest.wroteBytes) { waitCond.wakeAll(); @@ -96,14 +96,14 @@ class QAVIODevicePrivate QMetaObject::invokeMethod(d->q_ptr, [&] { QMutexLocker locker(&d->mutex); if (whence == AVSEEK_SIZE) { - pos = d->device.size() > 0 ? d->device.size() : 0; + pos = d->device->size() > 0 ? d->device->size() : 0; } else { if (whence == SEEK_END) - offset = d->device.size() - offset; + offset = d->device->size() - offset; else if (whence == SEEK_CUR) - offset = d->device.pos() + offset; + offset = d->device->pos() + offset; - pos = d->device.seek(offset) ? d->device.pos() : -1; + pos = d->device->seek(offset) ? d->device->pos() : -1; } d->waitCond.wakeAll(); wake = true; @@ -116,23 +116,23 @@ class QAVIODevicePrivate return pos; } - const size_t buffer_size = 64 * 1024; + size_t buffer_size = 64 * 1024; QAVIODevice *q_ptr = nullptr; - QIODevice &device; + QSharedPointer device; unsigned char *buffer = nullptr; AVIOContext *ctx = nullptr; - QMutex mutex; + mutable QMutex mutex; QWaitCondition waitCond; bool aborted = false; bool wakeRead = false; ReadRequest readRequest; }; -QAVIODevice::QAVIODevice(QIODevice &device, QObject *parent) +QAVIODevice::QAVIODevice(const QSharedPointer &device, QObject *parent) : QObject(parent) , d_ptr(new QAVIODevicePrivate(this, device)) { - connect(&device, &QIODevice::readyRead, this, [this] { + connect(device.get(), &QIODevice::readyRead, this, [this] { Q_D(QAVIODevice); d->readData(); }); @@ -156,4 +156,18 @@ void QAVIODevice::abort(bool aborted) d->waitCond.wakeAll(); } +void QAVIODevice::setBufferSize(size_t size) +{ + Q_D(QAVIODevice); + QMutexLocker locker(&d->mutex); + d->buffer_size = size; +} + +size_t QAVIODevice::bufferSize() const +{ + Q_D(const QAVIODevice); + QMutexLocker locker(&d->mutex); + return d->buffer_size; +} + QT_END_NAMESPACE diff --git a/src/QtAVPlayer/qaviodevice_p.h b/src/QtAVPlayer/qaviodevice.h similarity index 72% rename from src/QtAVPlayer/qaviodevice_p.h rename to src/QtAVPlayer/qaviodevice.h index f57aa7f3..a9abbeca 100644 --- a/src/QtAVPlayer/qaviodevice_p.h +++ b/src/QtAVPlayer/qaviodevice.h @@ -8,19 +8,9 @@ #ifndef QAVFIODEVICE_P_H #define QAVFIODEVICE_P_H -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - #include #include +#include #include QT_BEGIN_NAMESPACE @@ -30,12 +20,15 @@ class QAVIODevicePrivate; class QAVIODevice : public QObject { public: - QAVIODevice(QIODevice &device, QObject *parent = nullptr); + QAVIODevice(const QSharedPointer &device, QObject *parent = nullptr); ~QAVIODevice(); AVIOContext *ctx() const; void abort(bool aborted); + void setBufferSize(size_t size); + size_t bufferSize() const; + protected: std::unique_ptr d_ptr; diff --git a/src/QtAVPlayer/qavplayer.cpp b/src/QtAVPlayer/qavplayer.cpp index 5ca116ad..d25cf391 100644 --- a/src/QtAVPlayer/qavplayer.cpp +++ b/src/QtAVPlayer/qavplayer.cpp @@ -7,7 +7,7 @@ #include "qavplayer.h" #include "qavdemuxer_p.h" -#include "qaviodevice_p.h" +#include "qaviodevice.h" #include "qavvideocodec_p.h" #include "qavaudiocodec_p.h" #include "qavvideoframe.h" @@ -110,7 +110,7 @@ class QAVPlayerPrivate QAVPlayer *q_ptr = nullptr; QString url; - QScopedPointer dev; + QSharedPointer dev; QAVPlayer::MediaStatus mediaStatus = QAVPlayer::NoMedia; QList pendingMediaStatuses; QAVPlayer::State state = QAVPlayer::StoppedState; @@ -502,7 +502,7 @@ void QAVPlayerPrivate::doLoad() { demuxer.abort(false); demuxer.unload(); - int ret = demuxer.load(url, dev.data()); + int ret = demuxer.load(url, dev.get()); if (ret < 0) { setError(QAVPlayer::ResourceError, err_str(ret)); return; @@ -867,7 +867,7 @@ QAVPlayer::~QAVPlayer() d->terminate(); } -void QAVPlayer::setSource(const QString &url, QIODevice *dev) +void QAVPlayer::setSource(const QString &url, const QSharedPointer &dev) { Q_D(QAVPlayer); if (d->url == url) @@ -877,8 +877,7 @@ void QAVPlayer::setSource(const QString &url, QIODevice *dev) d->terminate(); d->url = url; - if (dev) - d->dev.reset(new QAVIODevice(*dev)); + d->dev = dev; emit sourceChanged(url); d->wait(true); d->quit = false; diff --git a/src/QtAVPlayer/qavplayer.h b/src/QtAVPlayer/qavplayer.h index 845537dd..fec9fedb 100644 --- a/src/QtAVPlayer/qavplayer.h +++ b/src/QtAVPlayer/qavplayer.h @@ -18,7 +18,7 @@ QT_BEGIN_NAMESPACE -class QIODevice; +class QAVIODevice; class QAVPlayerPrivate; class QAVPlayer : public QObject { @@ -53,7 +53,7 @@ class QAVPlayer : public QObject QAVPlayer(QObject *parent = nullptr); ~QAVPlayer(); - void setSource(const QString &url, QIODevice *dev = nullptr); + void setSource(const QString &url, const QSharedPointer &dev = {}); QString source() const; QList availableVideoStreams() const; diff --git a/tests/auto/integration/qavdemuxer/tst_qavdemuxer.cpp b/tests/auto/integration/qavdemuxer/tst_qavdemuxer.cpp index a597c250..f41b5e1e 100644 --- a/tests/auto/integration/qavdemuxer/tst_qavdemuxer.cpp +++ b/tests/auto/integration/qavdemuxer/tst_qavdemuxer.cpp @@ -8,7 +8,7 @@ #include "qavdemuxer_p.h" #include "qavaudioframe.h" #include "qavvideoframe.h" -#include "qaviodevice_p.h" +#include "qaviodevice.h" #include "qavvideocodec_p.h" #include "qavaudiocodec_p.h" @@ -226,8 +226,8 @@ void tst_QAVDemuxer::fileIO() { QAVDemuxer d; - QFile file(testData("colors.mp4")); - if (!file.open(QIODevice::ReadOnly)) { + QSharedPointer file(new QFile(testData("colors.mp4"))); + if (!file->open(QIODevice::ReadOnly)) { QFAIL("Could not open"); return; } @@ -285,8 +285,8 @@ void tst_QAVDemuxer::qrcIO() { QAVDemuxer d; - QFile file(":/test.wav"); - if (!file.open(QIODevice::ReadOnly)) { + QSharedPointer file(new QFile(":/test.wav")); + if (!file->open(QIODevice::ReadOnly)) { QFAIL("Could not open"); return; } diff --git a/tests/auto/integration/qavplayer/tst_qavplayer.cpp b/tests/auto/integration/qavplayer/tst_qavplayer.cpp index 438720fa..f0dc187d 100644 --- a/tests/auto/integration/qavplayer/tst_qavplayer.cpp +++ b/tests/auto/integration/qavplayer/tst_qavplayer.cpp @@ -7,7 +7,7 @@ #include "qavplayer.h" #include "qavaudiooutput.h" -#include "qaviodevice_p.h" +#include "qaviodevice.h" #include #include @@ -1263,13 +1263,13 @@ void tst_QAVPlayer::files_io() QAVPlayer p; QFileInfo fileInfo(path); - QFile file(fileInfo.absoluteFilePath()); - if (!file.open(QIODevice::ReadOnly)) { + QSharedPointer file(new QFile(fileInfo.absoluteFilePath())); + if (!file->open(QIODevice::ReadOnly)) { QFAIL("Could not open"); return; } - - p.setSource(path, &file); + QSharedPointer dev(new QAVIODevice(file)); + p.setSource(path, dev); int vf = 0; QAVVideoFrame videoFrame; @@ -2457,21 +2457,22 @@ void tst_QAVPlayer::filesIO() return; } - Buffer buffer; - buffer.m_size = file.size(); - buffer.open(QIODevice::ReadWrite); + QSharedPointer buffer(new Buffer); + buffer->m_size = file.size(); + buffer->open(QIODevice::ReadWrite); QAVPlayer p; QAVVideoFrame frame; int framesCount = 0; QObject::connect(&p, &QAVPlayer::videoFrame, &p, [&](const QAVVideoFrame &f) { frame = f; ++framesCount; }); - p.setSource(fileInfo.fileName(), &buffer); + QSharedPointer dev(new QAVIODevice(buffer)); + p.setSource(fileInfo.fileName(), dev); p.play(); while(!file.atEnd()) { auto bytes = file.read(64 * 1024); - buffer.write(bytes); + buffer->write(bytes); QTest::qWait(50); } @@ -2506,21 +2507,22 @@ void tst_QAVPlayer::filesIOSequential() QFile file(fileInfo.absoluteFilePath()); file.open(QFile::ReadOnly); - BufferSequential buffer; - buffer.m_size = file.size(); - buffer.open(QIODevice::ReadWrite); + QSharedPointer buffer(new BufferSequential); + buffer->m_size = file.size(); + buffer->open(QIODevice::ReadWrite); QAVPlayer p; QAVVideoFrame frame; int framesCount = 0; QObject::connect(&p, &QAVPlayer::videoFrame, &p, [&](const QAVVideoFrame &f) { frame = f; ++framesCount; }); - p.setSource(fileInfo.fileName(), &buffer); + QSharedPointer dev(new QAVIODevice(buffer)); + p.setSource(fileInfo.fileName(), dev); p.play(); while(!file.atEnd()) { auto bytes = file.read(64 * 1024); - buffer.write(bytes); + buffer->write(bytes); QTest::qWait(50); }