diff options
Diffstat (limited to 'src/plugins')
11 files changed, 155 insertions, 26 deletions
diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp index f3ad84836..a0f809376 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -53,7 +53,6 @@ #include <qdebug.h> #include <qvideoframe.h> #include <private/qmemoryvideobuffer_p.h> -#include <private/qvideoframe_p.h> #include <QtCore/private/qjnihelpers_p.h> QT_BEGIN_NAMESPACE @@ -749,7 +748,7 @@ void QAndroidCameraSession::processPreviewImage(int id, const QVideoFrame &frame transform.scale(-1, 1); transform.rotate(rotation); - emit imageCaptured(id, qt_imageFromVideoFrame(frame).transformed(transform)); + emit imageCaptured(id, frame.image().transformed(transform)); } void QAndroidCameraSession::onNewPreviewFrame(const QVideoFrame &frame) diff --git a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp index ef86af896..66eafc765 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp +++ b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp @@ -176,12 +176,12 @@ void QAndroidMetaDataReaderControl::extractMetadata(QAndroidMetaDataReaderContro if (!string.isNull()) { metadata.insert(isVideo ? QMediaMetaData::LeadPerformer : QMediaMetaData::ContributingArtist, - string.split('/', QString::SkipEmptyParts)); + string.split('/', Qt::SkipEmptyParts)); } string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Author); if (!string.isNull()) - metadata.insert(QMediaMetaData::Author, string.split('/', QString::SkipEmptyParts)); + metadata.insert(QMediaMetaData::Author, string.split('/', Qt::SkipEmptyParts)); string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Bitrate); if (!string.isNull()) { @@ -196,7 +196,7 @@ void QAndroidMetaDataReaderControl::extractMetadata(QAndroidMetaDataReaderContro string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Composer); if (!string.isNull()) - metadata.insert(QMediaMetaData::Composer, string.split('/', QString::SkipEmptyParts)); + metadata.insert(QMediaMetaData::Composer, string.split('/', Qt::SkipEmptyParts)); string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Date); if (!string.isNull()) @@ -231,7 +231,7 @@ void QAndroidMetaDataReaderControl::extractMetadata(QAndroidMetaDataReaderContro string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Writer); if (!string.isNull()) - metadata.insert(QMediaMetaData::Writer, string.split('/', QString::SkipEmptyParts)); + metadata.insert(QMediaMetaData::Writer, string.split('/', Qt::SkipEmptyParts)); string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Year); if (!string.isNull()) diff --git a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp index f899481f0..de8422b86 100644 --- a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp +++ b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp @@ -271,7 +271,7 @@ void AndroidMediaPlayer::setAudioRole(QAudio::Role role) void AndroidMediaPlayer::setCustomAudioRole(const QString &role) { - QStringList roles = role.split(",", QString::SkipEmptyParts); + QStringList roles = role.split(",", Qt::SkipEmptyParts); int type = 0; // CONTENT_TYPE_UNKNOWN int usage = 0; // USAGE_UNKNOWN diff --git a/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm b/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm index dbaf3ed41..55a20b1bd 100644 --- a/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm +++ b/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm @@ -48,7 +48,6 @@ #include <QtCore/qbuffer.h> #include <QtConcurrent/qtconcurrentrun.h> #include <QtGui/qimagereader.h> -#include <private/qvideoframe_p.h> QT_USE_NAMESPACE @@ -214,7 +213,7 @@ void AVFImageCaptureControl::makeCapturePreview(CaptureRequest request, QTransform transform; transform.rotate(rotation); - Q_EMIT imageCaptured(request.captureId, qt_imageFromVideoFrame(frame).transformed(transform)); + Q_EMIT imageCaptured(request.captureId, frame.image().transformed(transform)); request.previewReady->release(); } diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h index 7a268a3d9..db29e88aa 100644 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h +++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h @@ -67,7 +67,7 @@ public: QMediaPlayer::MediaStatus mediaStatus() const; QMediaContent media() const; - const QIODevice *mediaStream() const; + QIODevice *mediaStream() const; void setMedia(const QMediaContent &content, QIODevice *stream); qint64 position() const; @@ -110,6 +110,9 @@ public Q_SLOTS: void processDurationChange(qint64 duration); + void streamReady(); + void streamDestroyed(); + Q_SIGNALS: void positionChanged(qint64 position); void durationChanged(qint64 duration); @@ -128,6 +131,7 @@ private: void setAudioAvailable(bool available); void setVideoAvailable(bool available); void setSeekable(bool seekable); + void resetStream(QIODevice *stream = nullptr); AVFMediaPlayerService *m_service; AVFVideoOutput *m_videoOutput; diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm index ba902a53c..424f30008 100644 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm +++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm @@ -42,6 +42,7 @@ #include "avfvideooutput.h" #include <qpointer.h> +#include <QFileInfo> #import <AVFoundation/AVFoundation.h> @@ -66,7 +67,7 @@ static void *AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext = &AVFMedi static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMediaPlayerSessionObserverCurrentItemObservationContext; static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext = &AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext; -@interface AVFMediaPlayerSessionObserver : NSObject +@interface AVFMediaPlayerSessionObserver : NSObject<AVAssetResourceLoaderDelegate> @property (readonly, getter=player) AVPlayer* m_player; @property (readonly, getter=playerItem) AVPlayerItem* m_playerItem; @@ -74,7 +75,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext @property (readonly, getter=session) AVFMediaPlayerSession* m_session; - (AVFMediaPlayerSessionObserver *) initWithMediaPlayerSession:(AVFMediaPlayerSession *)session; -- (void) setURL:(NSURL *)url; +- (void) setURL:(NSURL *)url mimeType:(NSString *)mimeType; - (void) unloadMedia; - (void) prepareToPlayAsset:(AVURLAsset *)asset withKeys:(NSArray *)requestedKeys; - (void) assetFailedToPrepareForPlayback:(NSError *)error; @@ -84,6 +85,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext change:(NSDictionary *)change context:(void *)context; - (void) detatchSession; - (void) dealloc; +- (BOOL) resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest; @end @implementation AVFMediaPlayerSessionObserver @@ -95,6 +97,8 @@ static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext AVPlayerLayer *m_playerLayer; NSURL *m_URL; BOOL m_bufferIsLikelyToKeepUp; + NSData *m_data; + NSString *m_mimeType; } @synthesize m_player, m_playerItem, m_playerLayer, m_session; @@ -109,8 +113,11 @@ static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext return self; } -- (void) setURL:(NSURL *)url +- (void) setURL:(NSURL *)url mimeType:(NSString *)mimeType { + [m_mimeType release]; + m_mimeType = [mimeType retain]; + if (m_URL != url) { [m_URL release]; @@ -122,6 +129,8 @@ static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext // use __block to avoid maintaining strong references on variables captured by the // following block callback __block AVURLAsset *asset = [[AVURLAsset URLAssetWithURL:m_URL options:nil] retain]; + [asset.resourceLoader setDelegate:self queue:dispatch_get_main_queue()]; + __block NSArray *requestedKeys = [[NSArray arrayWithObjects:AVF_TRACKS_KEY, AVF_PLAYABLE_KEY, nil] retain]; __block AVFMediaPlayerSessionObserver *blockSelf = self; @@ -403,9 +412,48 @@ static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext [m_URL release]; } + [m_mimeType release]; [super dealloc]; } +- (BOOL) resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest +{ + Q_UNUSED(resourceLoader); + + if (![loadingRequest.request.URL.scheme isEqualToString:@"iodevice"]) + return NO; + + QIODevice *device = m_session->mediaStream(); + if (!device) + return NO; + + device->seek(loadingRequest.dataRequest.requestedOffset); + if (loadingRequest.contentInformationRequest) { + loadingRequest.contentInformationRequest.contentType = m_mimeType; + loadingRequest.contentInformationRequest.contentLength = device->size(); + loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES; + } + + if (loadingRequest.dataRequest) { + NSInteger requestedLength = loadingRequest.dataRequest.requestedLength; + int maxBytes = qMin(32 * 1064, int(requestedLength)); + char buffer[maxBytes]; + NSInteger submitted = 0; + while (submitted < requestedLength) { + qint64 len = device->read(buffer, maxBytes); + if (len < 1) + break; + + [loadingRequest.dataRequest respondWithData:[NSData dataWithBytes:buffer length:len]]; + submitted += len; + } + + // Finish loading even if not all bytes submitted. + [loadingRequest finishLoading]; + } + + return YES; +} @end AVFMediaPlayerSession::AVFMediaPlayerSession(AVFMediaPlayerService *service, QObject *parent) @@ -483,11 +531,23 @@ QMediaContent AVFMediaPlayerSession::media() const return m_resources; } -const QIODevice *AVFMediaPlayerSession::mediaStream() const +QIODevice *AVFMediaPlayerSession::mediaStream() const { return m_mediaStream; } +static void setURL(void *observer, const QString &url, const QString &mimeType = QString()) +{ + NSString *urlString = [NSString stringWithUTF8String:url.toUtf8().constData()]; + NSURL *nsurl = [NSURL URLWithString:urlString]; + [static_cast<AVFMediaPlayerSessionObserver*>(observer) setURL:nsurl mimeType:[NSString stringWithUTF8String:mimeType.toLatin1().constData()]]; +} + +static void setStreamURL(void *observer, const QString &url) +{ + setURL(observer, QLatin1String("iodevice://") + url, QFileInfo(url).suffix()); +} + void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *stream) { #ifdef QT_DEBUG_AVF @@ -497,7 +557,7 @@ void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *st [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) unloadMedia]; m_resources = content; - m_mediaStream = stream; + resetStream(stream); setAudioAvailable(false); setVideoAvailable(false); @@ -508,7 +568,7 @@ void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *st const QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatus; const QMediaPlayer::State oldState = m_state; - if (content.isNull() || content.request().url().isEmpty()) { + if (!m_mediaStream && (content.isNull() || content.request().url().isEmpty())) { m_mediaStatus = QMediaPlayer::NoMedia; if (m_mediaStatus != oldMediaStatus) Q_EMIT mediaStatusChanged(m_mediaStatus); @@ -524,11 +584,16 @@ void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *st if (m_mediaStatus != oldMediaStatus) Q_EMIT mediaStatusChanged(m_mediaStatus); - //Load AVURLAsset - //initialize asset using content's URL - NSString *urlString = [NSString stringWithUTF8String:content.request().url().toEncoded().constData()]; - NSURL *url = [NSURL URLWithString:urlString]; - [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) setURL:url]; + if (m_mediaStream) { + // If there is a data, try to load it, + // otherwise wait for readyRead. + if (m_mediaStream->size()) + setStreamURL(m_observer, m_resources.request().url().toString()); + } else { + //Load AVURLAsset + //initialize asset using content's URL + setURL(m_observer, m_resources.request().url().toString()); + } m_state = QMediaPlayer::StoppedState; if (m_state != oldState) @@ -969,3 +1034,28 @@ void AVFMediaPlayerSession::processMediaLoadError() Q_EMIT error(QMediaPlayer::FormatError, tr("Failed to load media")); } + +void AVFMediaPlayerSession::streamReady() +{ + setStreamURL(m_observer, m_resources.request().url().toString()); +} + +void AVFMediaPlayerSession::streamDestroyed() +{ + resetStream(nullptr); +} + +void AVFMediaPlayerSession::resetStream(QIODevice *stream) +{ + if (m_mediaStream) { + disconnect(m_mediaStream, &QIODevice::readyRead, this, &AVFMediaPlayerSession::streamReady); + disconnect(m_mediaStream, &QIODevice::destroyed, this, &AVFMediaPlayerSession::streamDestroyed); + } + + m_mediaStream = stream; + + if (m_mediaStream) { + connect(m_mediaStream, &QIODevice::readyRead, this, &AVFMediaPlayerSession::streamReady); + connect(m_mediaStream, &QIODevice::destroyed, this, &AVFMediaPlayerSession::streamDestroyed); + } +} diff --git a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm index e06ddc4b0..63bdee4f5 100644 --- a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm +++ b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm @@ -177,7 +177,11 @@ void AVFVideoRendererControl::setSurface(QAbstractVideoSurface *surface) #endif //Check for needed formats to render as OpenGL Texture - m_enableOpenGL = m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).contains(QVideoFrame::Format_BGR32); + auto handleGlEnabled = [this] { + m_enableOpenGL = m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).contains(QVideoFrame::Format_BGR32); + }; + handleGlEnabled(); + connect(m_surface, &QAbstractVideoSurface::supportedFormatsChanged, this, handleGlEnabled); //If we already have a layer, but changed surfaces start rendering again if (m_playerLayer && !m_displayLink->isActive()) { diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp index a0c120816..cee3e9c56 100644 --- a/src/plugins/directshow/camera/dscamerasession.cpp +++ b/src/plugins/directshow/camera/dscamerasession.cpp @@ -44,7 +44,6 @@ #include <QtMultimedia/qvideosurfaceformat.h> #include <QtMultimedia/qcameraimagecapture.h> #include <private/qmemoryvideobuffer_p.h> -#include <private/qvideoframe_p.h> #include "dscamerasession.h" #include "dsvideorenderer.h" @@ -637,7 +636,7 @@ void DSCameraSession::presentFrame() if (m_capturedFrame.isValid()) { - captureImage = qt_imageFromVideoFrame(m_capturedFrame); + captureImage = m_capturedFrame.image(); const bool needsVerticalMirroring = m_previewSurfaceFormat.scanLineDirection() != QVideoSurfaceFormat::TopToBottom; captureImage = captureImage.mirrored(m_needsHorizontalMirroring, needsVerticalMirroring); // also causes a deep copy of the data diff --git a/src/plugins/gstreamer/camerabin/camerabinzoom.cpp b/src/plugins/gstreamer/camerabin/camerabinzoom.cpp index bb3659493..401e13207 100644 --- a/src/plugins/gstreamer/camerabin/camerabinzoom.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinzoom.cpp @@ -51,7 +51,9 @@ CameraBinZoom::CameraBinZoom(CameraBinSession *session) , m_requestedOpticalZoom(1.0) , m_requestedDigitalZoom(1.0) { - + GstElement *camerabin = m_session->cameraBin(); + g_signal_connect(G_OBJECT(camerabin), "notify::zoom", G_CALLBACK(updateZoom), this); + g_signal_connect(G_OBJECT(camerabin), "notify::max-zoom", G_CALLBACK(updateMaxZoom), this); } CameraBinZoom::~CameraBinZoom() @@ -114,4 +116,32 @@ void CameraBinZoom::zoomTo(qreal optical, qreal digital) emit currentDigitalZoomChanged(digital); } +void CameraBinZoom::updateZoom(GObject *o, GParamSpec *p, gpointer d) +{ + Q_UNUSED(p); + + gfloat zoomFactor = 1.0; + g_object_get(o, ZOOM_PROPERTY, &zoomFactor, NULL); + + CameraBinZoom *zoom = reinterpret_cast<CameraBinZoom *>(d); + + QMetaObject::invokeMethod(zoom, "currentDigitalZoomChanged", + Qt::QueuedConnection, + Q_ARG(qreal, zoomFactor)); +} + +void CameraBinZoom::updateMaxZoom(GObject *o, GParamSpec *p, gpointer d) +{ + Q_UNUSED(p); + + gfloat zoomFactor = 1.0; + g_object_get(o, MAX_ZOOM_PROPERTY, &zoomFactor, NULL); + + CameraBinZoom *zoom = reinterpret_cast<CameraBinZoom *>(d); + + QMetaObject::invokeMethod(zoom, "maximumDigitalZoomChanged", + Qt::QueuedConnection, + Q_ARG(qreal, zoomFactor)); +} + QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinzoom.h b/src/plugins/gstreamer/camerabin/camerabinzoom.h index 8ad4764b2..858ada2da 100644 --- a/src/plugins/gstreamer/camerabin/camerabinzoom.h +++ b/src/plugins/gstreamer/camerabin/camerabinzoom.h @@ -41,6 +41,7 @@ #define CAMERABINZOOMCONTROL_H #include <qcamerazoomcontrol.h> +#include <gst/gst.h> QT_BEGIN_NAMESPACE @@ -64,6 +65,9 @@ public: void zoomTo(qreal optical, qreal digital) override; private: + static void updateZoom(GObject *o, GParamSpec *p, gpointer d); + static void updateMaxZoom(GObject *o, GParamSpec *p, gpointer d); + CameraBinSession *m_session; qreal m_requestedOpticalZoom; qreal m_requestedDigitalZoom; diff --git a/src/plugins/m3u/qm3uhandler.cpp b/src/plugins/m3u/qm3uhandler.cpp index 017c32d92..5e05994ef 100644 --- a/src/plugins/m3u/qm3uhandler.cpp +++ b/src/plugins/m3u/qm3uhandler.cpp @@ -163,7 +163,7 @@ public: virtual bool writeItem(const QMediaContent& item) { - *m_textStream << item.request().url().toString() << endl; + *m_textStream << item.request().url().toString() << Qt::endl; return true; } |