[vlc-commits] [Git][videolan/vlc][master] 3 commits: qt: vlcaccess image provider
Steve Lhomme (@robUx4)
gitlab at videolan.org
Wed Apr 3 17:34:50 UTC 2024
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
d8d598e8 by Pierre Lamot at 2024-04-03T16:46:06+00:00
qt: vlcaccess image provider
artwork may reference a network resource, so far we were using QNetwork to read
these resources, but it has some drawbacks
* The protocol for the artwork may not be handled by QNetwork
* The access to the artwork may require credentials that will likely be the same
as the one required to access the media
* QNetwork may not be present as this is not a requirement for building VLC
Image may require to be loaded using VLC access using special URI image://vlcaccess/?uri=......
- - - - -
d7204227 by Pierre Lamot at 2024-04-03T16:46:06+00:00
qt: refactor RoundImage to use VLC access image provider
- - - - -
925f1338 by Pierre Lamot at 2024-04-03T16:46:06+00:00
qml: use vlcaccess image provider to display artwork
RoundImage will automatically use the vlcaccess image provide, so only Image
usecase needs to be updated
- - - - -
9 changed files:
- modules/gui/qt/Makefile.am
- modules/gui/qt/maininterface/mainui.cpp
- modules/gui/qt/network/qml/NetworkCustomCover.qml
- modules/gui/qt/player/qml/Player.qml
- modules/gui/qt/player/qml/controlbarcontrols/ArtworkInfoWidget.qml
- modules/gui/qt/playlist/qml/PlaylistDelegate.qml
- + modules/gui/qt/util/vlcaccess_image_provider.cpp
- + modules/gui/qt/util/vlcaccess_image_provider.hpp
- modules/gui/qt/widgets/native/roundimage.cpp
Changes:
=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -298,6 +298,7 @@ libqt_plugin_la_SOURCES = \
util/base_model.hpp util/base_model_p.hpp util/base_model.cpp \
util/color_scheme_model.cpp util/color_scheme_model.hpp \
util/color_svg_image_provider.cpp util/color_svg_image_provider.hpp \
+ util/vlcaccess_image_provider.cpp util/vlcaccess_image_provider.hpp \
util/covergenerator.cpp \
util/covergenerator.hpp \
util/imageluminanceextractor.cpp util/imageluminanceextractor.hpp \
@@ -464,6 +465,7 @@ nodist_libqt_plugin_la_SOURCES = \
util/base_model.moc.cpp \
util/color_scheme_model.moc.cpp \
util/color_svg_image_provider.moc.cpp \
+ util/vlcaccess_image_provider.moc.cpp \
util/imageluminanceextractor.moc.cpp \
util/csdbuttonmodel.moc.cpp \
util/keyhelper.moc.cpp \
=====================================
modules/gui/qt/maininterface/mainui.cpp
=====================================
@@ -41,6 +41,7 @@
#include "util/flickable_scroll_handler.hpp"
#include "util/color_svg_image_provider.hpp"
#include "util/effects_image_provider.hpp"
+#include "util/vlcaccess_image_provider.hpp"
#include "util/csdbuttonmodel.hpp"
#include "util/vlctick.hpp"
#include "util/list_selection_model.hpp"
@@ -144,6 +145,7 @@ MainUI::MainUI(qt_intf_t *p_intf, MainCtx *mainCtx, QWindow* interfaceWindow, Q
SingletonRegisterHelper<SystemPalette>::setInstance( new SystemPalette(this) );
SingletonRegisterHelper<QmlKeyHelper>::setInstance( new QmlKeyHelper(this) );
SingletonRegisterHelper<SVGColorImage>::setInstance( new SVGColorImage(this) );
+ SingletonRegisterHelper<VLCAccessImage>::setInstance( new VLCAccessImage(this) );
if (m_mainCtx->hasMediaLibrary())
{
@@ -174,6 +176,7 @@ bool MainUI::setup(QQmlEngine* engine)
SingletonRegisterHelper<EffectsImageProvider>::setInstance(new EffectsImageProvider(engine));
engine->addImageProvider(QStringLiteral("svgcolor"), new SVGColorImageImageProvider());
+ engine->addImageProvider(QStringLiteral("vlcaccess"), new VLCAccessImageProvider());
m_component = new QQmlComponent(engine, QStringLiteral("qrc:/main/MainInterface.qml"), QQmlComponent::PreferSynchronous, engine);
if (m_component->isLoading())
@@ -239,6 +242,7 @@ void MainUI::registerQMLTypes()
qmlRegisterSingletonType<QmlKeyHelper>(uri, versionMajor, versionMinor, "KeyHelper", SingletonRegisterHelper<QmlKeyHelper>::callback);
qmlRegisterSingletonType<EffectsImageProvider>(uri, versionMajor, versionMinor, "Effects", SingletonRegisterHelper<EffectsImageProvider>::callback);
qmlRegisterSingletonType<SVGColorImage>(uri, versionMajor, versionMinor, "SVGColorImage", SingletonRegisterHelper<SVGColorImage>::callback);
+ qmlRegisterSingletonType<VLCAccessImage>(uri, versionMajor, versionMinor, "VLCAccessImage", SingletonRegisterHelper<VLCAccessImage>::callback);
qmlRegisterSingletonType<PlaylistController>(uri, versionMajor, versionMinor, "MainPlaylistController", SingletonRegisterHelper<PlaylistController>::callback);
qmlRegisterType<DelayEstimator>( uri, versionMajor, versionMinor, "DelayEstimator" );
=====================================
modules/gui/qt/network/qml/NetworkCustomCover.qml
=====================================
@@ -108,7 +108,7 @@ Item {
source: {
if (!!networkModel && !!networkModel.artwork && networkModel.artwork.length > 0)
- return networkModel.artwork
+ return VLCAccessImage.uri(networkModel.artwork)
return ""
}
=====================================
modules/gui/qt/player/qml/Player.qml
=====================================
@@ -407,7 +407,7 @@ FocusScope {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
- source: rootPlayer.coverSource
+ source: VLCAccessImage.uri(rootPlayer.coverSource)
fillMode: Image.PreserveAspectFit
mipmap: true
cache: false
=====================================
modules/gui/qt/player/qml/controlbarcontrols/ArtworkInfoWidget.qml
=====================================
@@ -102,7 +102,7 @@ AbstractButton {
source: {
if (!paintOnly && Player.artwork && Player.artwork.toString())
- return Player.artwork
+ return VLCAccessImage.uri(Player.artwork)
else
return VLCStyle.noArtAlbumCover
}
=====================================
modules/gui/qt/playlist/qml/PlaylistDelegate.qml
=====================================
@@ -163,7 +163,7 @@ T.ItemDelegate {
anchors.fill: parent
fillMode: Image.PreserveAspectFit
- source: (model.artwork && model.artwork.toString()) ? model.artwork : VLCStyle.noArtAlbumCover
+ source: (model.artwork && model.artwork.toString()) ? VLCAccessImage.uri(model.artwork) : VLCStyle.noArtAlbumCover
visible: !statusIcon.visible
asynchronous: true
=====================================
modules/gui/qt/util/vlcaccess_image_provider.cpp
=====================================
@@ -0,0 +1,273 @@
+/*****************************************************************************
+ * Copyright (C) 2024 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_access.h>
+#include <vlc_stream.h>
+
+#include "vlcaccess_image_provider.hpp"
+
+#include "util/asynctask.hpp"
+#include "qt.hpp"
+
+#include <QImageReader>
+#include <QFile>
+#include <QQmlFile>
+#include <QUrlQuery>
+
+#define PATH_KEY "uri"
+
+namespace {
+
+class ImageReader : public AsyncTask<QImage>
+{
+public:
+ /**
+ * @brief ImageReader
+ * @param device i/o source to read from
+ *
+ * @param requestedSize only taken as hint, the Image is resized with PreserveAspectCrop
+ *
+ * @param radius
+ */
+ ImageReader(std::unique_ptr<QIODevice> device, QSize requestedSize, VLCAccessImageProvider::ImagePostProcessCb postProcessCb)
+ : device(std::move(device))
+ , requestedSize {requestedSize}
+ , postProcessCb {postProcessCb}
+ {
+ }
+
+ QString errorString() const {
+ return errorStr;
+ }
+
+ QImage execute() override
+ {
+ QImageReader reader;
+ reader.setDevice(device.get());
+ const QSize sourceSize = reader.size();
+
+ if (requestedSize.isValid())
+ reader.setScaledSize(sourceSize.scaled(requestedSize, Qt::KeepAspectRatioByExpanding));
+
+ auto img = reader.read();
+
+ if (img.isNull()) {
+ errorStr = reader.errorString();
+ }
+
+ if (!img.isNull() && postProcessCb)
+ img = postProcessCb(img, requestedSize);
+
+ return img;
+ }
+
+private:
+ std::unique_ptr<QIODevice> device;
+ QSize requestedSize;
+ QString errorStr;
+ VLCAccessImageProvider::ImagePostProcessCb postProcessCb;
+};
+
+
+class VLCAccessImageResponse : public QQuickImageResponse
+{
+public:
+ VLCAccessImageResponse(const QUrl& url, const QSize &requestedSize, VLCAccessImageProvider::ImagePostProcessCb postProcessCb = nullptr)
+ : imagePostProcessCb(postProcessCb)
+ {
+
+ std::unique_ptr<QIODevice> device;
+ if (url.scheme().compare(QStringLiteral("qrc"), Qt::CaseInsensitive) == 0)
+ {
+ QString qrcPath = QQmlFile::urlToLocalFileOrQrc(url);
+ device = std::make_unique<QFile>(qrcPath);
+ }
+ else
+ {
+ QUrl fileUrl = url;
+ if (fileUrl.scheme().isEmpty())
+ fileUrl.setScheme("file");
+ device = std::make_unique<VLCIODevice>(fileUrl.toString(QUrl::FullyEncoded));
+ }
+ reader.reset(new ImageReader(std::move(device), requestedSize, postProcessCb));
+
+ connect(reader.get(), &ImageReader::result, this, &VLCAccessImageResponse::handleImageRead);
+
+ reader->start(*QThreadPool::globalInstance());
+ }
+
+ QQuickTextureFactory *textureFactory() const override
+ {
+ return result.isNull() ? nullptr : QQuickTextureFactory::textureFactoryForImage(result);
+ }
+
+ QString errorString() const override
+ {
+ return errorStr;
+ }
+
+private:
+ void handleImageRead()
+ {
+ result = reader->takeResult();
+ errorStr = reader->errorString();
+ reader.reset();
+
+ emit finished();
+ }
+
+ VLCAccessImageProvider::ImagePostProcessCb imagePostProcessCb;
+ QImage result;
+ TaskHandle<ImageReader> reader;
+ QString errorStr;
+};
+
+} // anonymous namespace
+
+//// VLCAccessImageProvider
+
+VLCAccessImageProvider::VLCAccessImageProvider(VLCAccessImageProvider::ImagePostProcessCb cb)
+ : QQuickAsyncImageProvider()
+ , postProcessCb(cb)
+{
+}
+
+QQuickImageResponse* VLCAccessImageProvider::requestImageResponse(const QString& id, const QSize& requestedSize)
+{
+ QUrl url {id};
+ QUrlQuery query {url};
+ if (!query.hasQueryItem(PATH_KEY))
+ return nullptr;
+
+ QString vlcurl = query.queryItemValue(PATH_KEY, QUrl::FullyEncoded);
+ return new VLCAccessImageResponse(QUrl::fromEncoded(vlcurl.toUtf8()), requestedSize, postProcessCb);
+}
+
+QString VLCAccessImageProvider::wrapUri(QString path)
+{
+ QUrlQuery query;
+ query.addQueryItem(PATH_KEY, path);
+ return QStringLiteral("image://vlcaccess/?") + query.toString(QUrl::FullyEncoded);
+}
+
+//// VLCImageAccess
+
+VLCAccessImage::VLCAccessImage(QObject* parent)
+ : QObject(parent)
+{}
+
+QString VLCAccessImage::uri(QString path)
+{
+ return VLCAccessImageProvider::wrapUri(path);
+}
+
+//// VLCIODevice
+
+VLCIODevice::VLCIODevice(const QString& filename, QObject* parent)
+ : QIODevice(parent)
+ , m_filename(filename)
+{
+}
+
+VLCIODevice::~VLCIODevice()
+{
+ close();
+}
+
+bool VLCIODevice::open(OpenMode mode)
+{
+ //we only support reading
+ if (mode & QIODevice::OpenModeFlag::WriteOnly)
+ return false;
+
+ m_stream = vlc_access_NewMRL(nullptr, qtu(m_filename));
+ if (m_stream == nullptr)
+ return false;
+
+ return QIODevice::open(mode);
+}
+
+bool VLCIODevice::isSequential() const
+{
+ assert(m_stream);
+ //some access (like http) will perform really poorly with the way
+ //Qt uses the QIODevice (lots of seeks)
+ //return !vlc_stream_CanSeek(m_stream);
+ return true;
+}
+
+void VLCIODevice::close()
+{
+ if (!m_stream)
+ return;
+ vlc_stream_Delete(m_stream);
+ m_stream = nullptr;
+}
+
+qint64 VLCIODevice::pos() const
+{
+ assert(m_stream);
+ return vlc_stream_Tell(m_stream);
+}
+
+qint64 VLCIODevice::size() const
+{
+ assert(m_stream);
+ uint64_t streamSize;
+ bool ret = vlc_stream_GetSize(m_stream, &streamSize);
+ if (!ret)
+ return -1;
+ return static_cast<qint64>(streamSize);
+}
+
+bool VLCIODevice::seek(qint64 pos)
+{
+ assert(m_stream);
+ QIODevice::seek(pos);
+ if (pos < 0)
+ return false;
+ return vlc_stream_Seek(m_stream, pos) == VLC_SUCCESS;
+}
+
+bool VLCIODevice::atEnd() const
+{
+ assert(m_stream);
+ return vlc_stream_Eof(m_stream);
+}
+
+bool VLCIODevice::reset()
+{
+ assert(m_stream);
+ return vlc_stream_Seek(m_stream, 0) == VLC_SUCCESS;
+}
+
+qint64 VLCIODevice::readData(char* data, qint64 maxlen)
+{
+ assert(m_stream);
+ return vlc_stream_Read(m_stream, data, maxlen);
+}
+
+qint64 VLCIODevice::writeData(const char*, qint64)
+{
+ assert(m_stream);
+ return -1;
+}
=====================================
modules/gui/qt/util/vlcaccess_image_provider.hpp
=====================================
@@ -0,0 +1,102 @@
+/*****************************************************************************
+ * Copyright (C) 2024 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifndef VLCACCESSIMAGEPROVIDER_HPP
+#define VLCACCESSIMAGEPROVIDER_HPP
+
+#include <QObject>
+#include <QQuickAsyncImageProvider>
+#include <QString>
+#include <QIODevice>
+
+typedef struct stream_t stream_t;
+
+/**
+ * VLCIODevice is a QIODevice based on vlc_access
+ */
+class VLCIODevice : public QIODevice
+{
+public:
+ VLCIODevice(const QString &filename, QObject *parent = nullptr);
+
+ virtual ~VLCIODevice();
+
+public:
+ bool open(QIODevice::OpenMode mode) override;
+
+ bool isSequential() const override;
+
+ void close() override;
+
+ qint64 pos() const override;
+
+ qint64 size() const override;
+
+ bool seek(qint64 pos) override;
+
+ bool atEnd() const override;
+
+ bool reset() override;
+
+protected:
+ qint64 readData(char *data, qint64 maxlen) override;
+
+ qint64 writeData(const char*, qint64) override;
+
+private:
+ QString m_filename;
+ stream_t* m_stream = nullptr;
+};
+
+class VLCAccessImageProvider: public QQuickAsyncImageProvider
+{
+public:
+ typedef std::function<QImage (QImage&, const QSize &)> ImagePostProcessCb;
+
+ VLCAccessImageProvider(ImagePostProcessCb cb = nullptr);
+
+ QQuickImageResponse* requestImageResponse(const QString &id, const QSize &requestedSize) override;
+
+ static QString wrapUri(QString path);
+
+private:
+ ImagePostProcessCb postProcessCb;
+};
+
+class VLCAccessImage : public QObject {
+ Q_OBJECT
+public:
+ VLCAccessImage(QObject* parent = nullptr);
+
+ /**
+ * @brief adapt @path to open it using
+ * @param path to the artwork
+ *
+ * sample usage:
+ *
+ * @code{qml}
+ * Image {
+ * src: VLCImageAccess.uri("file:///path/to/assert.svg")
+ * }
+ * @code
+ *
+ */
+ Q_INVOKABLE QString uri(QString path);
+
+};
+
+#endif // VLCACCESSIMAGEPROVIDER_HPP
=====================================
modules/gui/qt/widgets/native/roundimage.cpp
=====================================
@@ -24,12 +24,16 @@
# include "config.h"
#endif
+#include <vlc_access.h>
+#include <vlc_stream.h>
+
#include "qt.hpp"
#include "roundimage.hpp"
#include "roundimage_p.hpp"
#include "util/asynctask.hpp"
#include "util/qsgroundedrectangularimagenode.hpp"
+#include "util/vlcaccess_image_provider.hpp"
#include <qhashfunctions.h>
@@ -42,15 +46,10 @@
#include <QQuickWindow>
#include <QGuiApplication>
#include <QSGImageNode>
+#include <QIODevice>
#include <QtQml>
#include <QQmlFile>
-#ifdef QT_NETWORK_LIB
-#include <QNetworkAccessManager>
-#include <QNetworkReply>
-#include <QNetworkRequest>
-#endif
-
bool operator ==(const ImageCacheKey &lhs, const ImageCacheKey &rhs)
{
@@ -101,172 +100,6 @@ namespace
return target;
}
- class ImageReader : public AsyncTask<QImage>
- {
- public:
- /**
- * @brief ImageReader
- * @param device i/o source to read from, ImageReader doesn't take owner ship of the device
- * parent must make sure availability of device through out the lifetime of this instance
- *
- * @param requestedSize only taken as hint, the Image is resized with PreserveAspectCrop
- *
- * @param radius
- */
- ImageReader(QIODevice *device, QSize requestedSize, const qreal radius)
- : device {device}
- , requestedSize {requestedSize}
- , radius {radius}
- {
- }
-
- QString errorString() const { return errorStr; }
-
- QImage execute() override
- {
- QImageReader reader;
- reader.setDevice(device);
- const QSize sourceSize = reader.size();
-
- if (requestedSize.isValid())
- reader.setScaledSize(sourceSize.scaled(requestedSize, Qt::KeepAspectRatioByExpanding));
-
- auto img = reader.read();
- errorStr = reader.errorString();
-
- if (!errorStr.isEmpty())
- img = prepareImage(requestedSize.isValid() ? requestedSize : img.size(), radius, img);
-
- return img;
- }
-
- private:
- QIODevice *device;
- QSize requestedSize;
- qreal radius;
- QString errorStr;
- };
-
- class LocalImageResponse : public QQuickImageResponse
- {
- public:
- LocalImageResponse(const QString &fileName, const QSize &requestedSize, const qreal radius)
- {
- auto file = new QFile(fileName);
- reader.reset(new ImageReader(file, requestedSize, radius));
- file->setParent(reader.get());
-
- connect(reader.get(), &ImageReader::result, this, &LocalImageResponse::handleImageRead);
-
- reader->start(*QThreadPool::globalInstance());
- }
-
- QQuickTextureFactory *textureFactory() const override
- {
- return result.isNull() ? nullptr : QQuickTextureFactory::textureFactoryForImage(result);
- }
-
- QString errorString() const override
- {
- return errorStr;
- }
-
- private:
- void handleImageRead()
- {
- result = reader->takeResult();
- errorStr = reader->errorString();
- reader.reset();
-
- emit finished();
- }
-
- QImage result;
- TaskHandle<ImageReader> reader;
- QString errorStr;
- };
-
-#ifdef QT_NETWORK_LIB
- class NetworkImageResponse : public QQuickImageResponse
- {
- public:
- /**
- * @brief NetworkImageResponse
- * @param reply - Network reply to read from, NetworkImageResponse takes ownership of this object
- * @param requestedSize - passed to ImageReader class
- * @param radius - passed to ImageReader class
- */
- NetworkImageResponse(QNetworkReply *reply, QSize requestedSize, const qreal radius)
- : reply {reply}
- , requestedSize {requestedSize}
- , radius {radius}
- {
- reply->setParent(this);
-
- QObject::connect(reply, &QNetworkReply::finished
- , this, &NetworkImageResponse::handleNetworkReplyFinished);
- }
-
- QQuickTextureFactory *textureFactory() const override
- {
- return result.isNull() ? nullptr : QQuickTextureFactory::textureFactoryForImage(result);
- }
-
- QString errorString() const override
- {
- return error;
- }
-
- void cancel() override
- {
- if (reply->isRunning())
- reply->abort();
-
- reader.reset();
- }
-
- private:
- void handleNetworkReplyFinished()
- {
- if (reply->error() != QNetworkReply::NoError)
- {
- error = reply->errorString();
- emit finished();
-
- releaseNetworkReply();
- return;
- }
-
- reader.reset(new ImageReader(reply, requestedSize, radius));
- QObject::connect(reader.get(), &ImageReader::result, this, [this]()
- {
- result = reader->takeResult();
- error = reader->errorString();
- reader.reset();
-
- releaseNetworkReply();
-
- emit finished();
- });
-
- reader->start(*QThreadPool::globalInstance());
- }
-
- void releaseNetworkReply()
- {
- reply->deleteLater();
- reply = nullptr;
- }
-
- QNetworkReply *reply;
- QSize requestedSize;
- qreal radius;
- TaskHandle<ImageReader> reader;
- QImage result;
- QString error;
- };
-#endif
-
// adapts a given QQuickImageResponse to produce a image with radius
class ImageResponseRadiusAdaptor : public QQuickImageResponse
{
@@ -429,7 +262,7 @@ void RoundImageRequest::handleImageResponseFinished()
QQuickImageResponse* RoundImageRequest::getAsyncImageResponse(const QUrl &url, const QSize &requestedSize, const qreal radius, QQmlEngine *engine)
{
- if (url.scheme() == QStringLiteral("image"))
+ if (url.scheme() == QStringLiteral("image") && url.host() != "vlcaccess")
{
auto provider = engine->imageProvider(url.host());
if (!provider)
@@ -447,21 +280,13 @@ QQuickImageResponse* RoundImageRequest::getAsyncImageResponse(const QUrl &url, c
return nullptr;
}
- else if (QQmlFile::isLocalFile(url))
- {
- return new LocalImageResponse(QQmlFile::urlToLocalFileOrQrc(url), requestedSize, radius);
- }
-#ifdef QT_NETWORK_LIB
- else
- {
- QNetworkRequest request(url);
- request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
- auto reply = engine->networkAccessManager()->get(request);
- return new NetworkImageResponse(reply, requestedSize, radius);
- }
-#else
- return nullptr;
-#endif
+
+ VLCAccessImageProvider vlcAccessImageProvider([radius](QImage& img, const QSize &requestedSize) -> QImage {
+ return prepareImage(requestedSize, radius, img);
+ });
+ QString wrappedUri = VLCAccessImageProvider::wrapUri(url.toString(QUrl::FullyEncoded));
+
+ return vlcAccessImageProvider.requestImageResponse(wrappedUri, requestedSize);
}
// RoundImage
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/f7498f6b19a43af10883fb5bc35d88a16f9b3bf2...925f13389b7089053198ceaaef037df9ab935270
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/f7498f6b19a43af10883fb5bc35d88a16f9b3bf2...925f13389b7089053198ceaaef037df9ab935270
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list