diff options
Diffstat (limited to 'src/plugins')
360 files changed, 0 insertions, 65750 deletions
diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index bdefc1bb3..73bcbf963 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -3,21 +3,3 @@ if(TARGET Qt::Quick) add_subdirectory(videonode) endif() -if(ANDROID) - add_subdirectory(android) -endif() -if(QNX OR WIN32 OR (APPLE AND NOT WATCHOS) OR (UNIX AND NOT ANDROID AND NOT APPLE AND NOT QT_FEATURE_gstreamer)) - add_subdirectory(audiocapture) -endif() -if(QNX AND QT_FEATURE_mmrenderer) - add_subdirectory(qnx) -endif() -if(QT_FEATURE_wmf AND WIN32) - add_subdirectory(wmf) -endif() -if(QT_FEATURE_gstreamer) - add_subdirectory(gstreamer) -endif() -if(APPLE AND QT_FEATURE_avfoundation AND NOT WATCHOS) - add_subdirectory(avfoundation) -endif() diff --git a/src/plugins/android/CMakeLists.txt b/src/plugins/android/CMakeLists.txt deleted file mode 100644 index 2fefad369..000000000 --- a/src/plugins/android/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Generated from android.pro. - -add_subdirectory(src) -if(ANDROID) - add_subdirectory(jar) -endif() diff --git a/src/plugins/android/android.pro b/src/plugins/android/android.pro deleted file mode 100644 index 37d11c86b..000000000 --- a/src/plugins/android/android.pro +++ /dev/null @@ -1,4 +0,0 @@ -TEMPLATE = subdirs - -SUBDIRS += src -android: SUBDIRS += jar diff --git a/src/plugins/android/jar/AndroidManifest.xml b/src/plugins/android/jar/AndroidManifest.xml deleted file mode 100644 index 17019fb34..000000000 --- a/src/plugins/android/jar/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="org.qtproject.qt.android.multimedia" - android:versionCode="1" - android:versionName="1.0" > - <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> -</manifest> diff --git a/src/plugins/android/jar/CMakeLists.txt b/src/plugins/android/jar/CMakeLists.txt deleted file mode 100644 index 796bf43a1..000000000 --- a/src/plugins/android/jar/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -# Generated from jar.pro. - -set(java_sources - src/org/qtproject/qt/android/multimedia/QtAndroidMediaPlayer.java - src/org/qtproject/qt/android/multimedia/QtCameraListener.java - src/org/qtproject/qt/android/multimedia/QtMediaRecorderListener.java - src/org/qtproject/qt/android/multimedia/QtMultimediaUtils.java - src/org/qtproject/qt/android/multimedia/QtSurfaceHolderCallback.java - src/org/qtproject/qt/android/multimedia/QtSurfaceTextureHolder.java - src/org/qtproject/qt/android/multimedia/QtSurfaceTextureListener.java -) - -qt_internal_add_jar(QtAndroidMultimedia - INCLUDE_JARS ${QT_ANDROID_JAR} - SOURCES ${java_sources} - OUTPUT_DIR "${QT_BUILD_DIR}/jar" -) - -install_jar(QtAndroidMultimedia - DESTINATION jar - COMPONENT Devel -) - diff --git a/src/plugins/android/jar/jar.pro b/src/plugins/android/jar/jar.pro deleted file mode 100644 index 0ef830f32..000000000 --- a/src/plugins/android/jar/jar.pro +++ /dev/null @@ -1,21 +0,0 @@ -TARGET = Qt$${QT_MAJOR_VERSION}AndroidMultimedia - -load(qt_build_paths) -CONFIG += java -DESTDIR = $$MODULE_BASE_OUTDIR/jar - -JAVACLASSPATH += $$PWD/src - -JAVASOURCES += $$PWD/src/org/qtproject/qt/android/multimedia/QtAndroidMediaPlayer.java \ - $$PWD/src/org/qtproject/qt/android/multimedia/QtCameraListener.java \ - $$PWD/src/org/qtproject/qt/android/multimedia/QtSurfaceTextureListener.java \ - $$PWD/src/org/qtproject/qt/android/multimedia/QtSurfaceTextureHolder.java \ - $$PWD/src/org/qtproject/qt/android/multimedia/QtMultimediaUtils.java \ - $$PWD/src/org/qtproject/qt/android/multimedia/QtMediaRecorderListener.java \ - $$PWD/src/org/qtproject/qt/android/multimedia/QtSurfaceHolderCallback.java - -# install -target.path = $$[QT_INSTALL_PREFIX]/jar -INSTALLS += target - -OTHER_FILES += $$JAVASOURCES diff --git a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtAndroidMediaPlayer.java b/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtAndroidMediaPlayer.java deleted file mode 100644 index aa706179c..000000000 --- a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtAndroidMediaPlayer.java +++ /dev/null @@ -1,590 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtMultimedia of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -package org.qtproject.qt.android.multimedia; - -import java.io.IOException; -import java.lang.String; -import java.util.HashMap; -import java.io.FileInputStream; - -// API is level is < 9 unless marked otherwise. -import android.content.Context; -import android.media.MediaPlayer; -import android.media.AudioAttributes; -import android.net.Uri; -import android.util.Log; -import java.io.FileDescriptor; -import android.content.res.AssetFileDescriptor; -import android.content.res.AssetManager; -import android.view.SurfaceHolder; - -public class QtAndroidMediaPlayer -{ - // Native callback functions for MediaPlayer - native public void onErrorNative(int what, int extra, long id); - native public void onBufferingUpdateNative(int percent, long id); - native public void onProgressUpdateNative(int progress, long id); - native public void onDurationChangedNative(int duration, long id); - native public void onInfoNative(int what, int extra, long id); - native public void onVideoSizeChangedNative(int width, int height, long id); - native public void onStateChangedNative(int state, long id); - - private MediaPlayer mMediaPlayer = null; - private AudioAttributes mAudioAttributes = null; - private HashMap<String, String> mHeaders = null; - private Uri mUri = null; - private final long mID; - private final Context mContext; - private boolean mMuted = false; - private int mVolume = 100; - private static final String TAG = "Qt MediaPlayer"; - private SurfaceHolder mSurfaceHolder = null; - - private class State { - final static int Uninitialized = 0x1 /* End */; - final static int Idle = 0x2; - final static int Preparing = 0x4; - final static int Prepared = 0x8; - final static int Initialized = 0x10; - final static int Started = 0x20; - final static int Stopped = 0x40; - final static int Paused = 0x80; - final static int PlaybackCompleted = 0x100; - final static int Error = 0x200; - } - - private volatile int mState = State.Uninitialized; - - /** - * MediaPlayer OnErrorListener - */ - private class MediaPlayerErrorListener - implements MediaPlayer.OnErrorListener - { - @Override - public boolean onError(final MediaPlayer mp, - final int what, - final int extra) - { - setState(State.Error); - onErrorNative(what, extra, mID); - return true; - } - - } - - /** - * MediaPlayer OnBufferingListener - */ - private class MediaPlayerBufferingListener - implements MediaPlayer.OnBufferingUpdateListener - { - private int mBufferPercent = -1; - @Override - public void onBufferingUpdate(final android.media.MediaPlayer mp, - final int percent) - { - // Avoid updates when percent is unchanged. - // E.g., we keep getting updates when percent == 100 - if (mBufferPercent == percent) - return; - - onBufferingUpdateNative((mBufferPercent = percent), mID); - } - - } - - /** - * MediaPlayer OnCompletionListener - */ - private class MediaPlayerCompletionListener - implements MediaPlayer.OnCompletionListener - { - @Override - public void onCompletion(final MediaPlayer mp) - { - setState(State.PlaybackCompleted); - } - - } - - /** - * MediaPlayer OnInfoListener - */ - private class MediaPlayerInfoListener - implements MediaPlayer.OnInfoListener - { - @Override - public boolean onInfo(final MediaPlayer mp, - final int what, - final int extra) - { - onInfoNative(what, extra, mID); - return true; - } - - } - - /** - * MediaPlayer OnPreparedListener - */ - private class MediaPlayerPreparedListener - implements MediaPlayer.OnPreparedListener - { - - @Override - public void onPrepared(final MediaPlayer mp) - { - setState(State.Prepared); - onDurationChangedNative(getDuration(), mID); - } - - } - - /** - * MediaPlayer OnSeekCompleteListener - */ - private class MediaPlayerSeekCompleteListener - implements MediaPlayer.OnSeekCompleteListener - { - - @Override - public void onSeekComplete(final MediaPlayer mp) - { - onProgressUpdateNative(getCurrentPosition(), mID); - } - - } - - /** - * MediaPlayer OnVideoSizeChangedListener - */ - private class MediaPlayerVideoSizeChangedListener - implements MediaPlayer.OnVideoSizeChangedListener - { - - @Override - public void onVideoSizeChanged(final MediaPlayer mp, - final int width, - final int height) - { - onVideoSizeChangedNative(width, height, mID); - } - - } - - public QtAndroidMediaPlayer(final Context context, final long id) - { - mID = id; - mContext = context; - } - - public MediaPlayer getMediaPlayerHandle() - { - return mMediaPlayer; - } - - private void setState(int state) - { - if (mState == state) - return; - - mState = state; - - onStateChangedNative(mState, mID); - } - - - private void init() - { - if (mMediaPlayer == null) { - mMediaPlayer = new MediaPlayer(); - setState(State.Idle); - // Make sure the new media player has the volume that was set on the QMediaPlayer - setVolumeHelper(mMuted ? 0 : mVolume); - setAudioAttributes(mMediaPlayer, mAudioAttributes); - } - } - - public void start() - { - if ((mState & (State.Prepared - | State.Started - | State.Paused - | State.PlaybackCompleted)) == 0) { - return; - } - - try { - mMediaPlayer.start(); - setState(State.Started); - } catch (final IllegalStateException e) { - Log.d(TAG, "" + e.getMessage()); - } - } - - - public void pause() - { - if ((mState & (State.Started | State.Paused | State.PlaybackCompleted)) == 0) - return; - - try { - mMediaPlayer.pause(); - setState(State.Paused); - } catch (final IllegalStateException e) { - Log.d(TAG, "" + e.getMessage()); - } - } - - - public void stop() - { - if ((mState & (State.Prepared - | State.Started - | State.Stopped - | State.Paused - | State.PlaybackCompleted)) == 0) { - return; - } - - try { - mMediaPlayer.stop(); - setState(State.Stopped); - } catch (final IllegalStateException e) { - Log.d(TAG, "" + e.getMessage()); - } - } - - - public void seekTo(final int msec) - { - if ((mState & (State.Prepared - | State.Started - | State.Paused - | State.PlaybackCompleted)) == 0) { - return; - } - - try { - mMediaPlayer.seekTo(msec); - } catch (final IllegalStateException e) { - Log.d(TAG, "" + e.getMessage()); - } - } - - - public boolean isPlaying() - { - boolean playing = false; - if ((mState & (State.Idle - | State.Initialized - | State.Prepared - | State.Started - | State.Paused - | State.Stopped - | State.PlaybackCompleted)) == 0) { - return playing; - } - - try { - playing = mMediaPlayer.isPlaying(); - } catch (final IllegalStateException e) { - Log.d(TAG, "" + e.getMessage()); - } - - return playing; - } - - public void prepareAsync() - { - if ((mState & (State.Initialized | State.Stopped)) == 0) - return; - - try { - mMediaPlayer.prepareAsync(); - setState(State.Preparing); - } catch (final IllegalStateException e) { - Log.d(TAG, "" + e.getMessage()); - } - } - - public void initHeaders() - { - mHeaders = new HashMap<String, String>(); - } - - public void setHeader(final String header, final String value) - { - mHeaders.put(header, value); - } - - public void setDataSource(final String path) - { - if ((mState & State.Uninitialized) != 0) - init(); - - if ((mState & State.Idle) == 0) - return; - - mMediaPlayer.setOnBufferingUpdateListener(new MediaPlayerBufferingListener()); - mMediaPlayer.setOnCompletionListener(new MediaPlayerCompletionListener()); - mMediaPlayer.setOnInfoListener(new MediaPlayerInfoListener()); - mMediaPlayer.setOnSeekCompleteListener(new MediaPlayerSeekCompleteListener()); - mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayerVideoSizeChangedListener()); - mMediaPlayer.setOnErrorListener(new MediaPlayerErrorListener()); - mMediaPlayer.setOnPreparedListener(new MediaPlayerPreparedListener()); - - if (mSurfaceHolder != null) - mMediaPlayer.setDisplay(mSurfaceHolder); - - AssetFileDescriptor afd = null; - FileInputStream fis = null; - try { - mUri = Uri.parse(path); - final boolean inAssets = (mUri.getScheme().compareTo("assets") == 0); - if (inAssets) { - final String asset = mUri.getPath().substring(1 /* Remove first '/' */); - final AssetManager am = mContext.getAssets(); - afd = am.openFd(asset); - final long offset = afd.getStartOffset(); - final long length = afd.getLength(); - FileDescriptor fd = afd.getFileDescriptor(); - mMediaPlayer.setDataSource(fd, offset, length); - } else if (mUri.getScheme().compareTo("file") == 0) { - fis = new FileInputStream(mUri.getPath()); - FileDescriptor fd = fis.getFD(); - mMediaPlayer.setDataSource(fd); - } else { - if (mHeaders.isEmpty()) - mMediaPlayer.setDataSource(path); - else - mMediaPlayer.setDataSource(mContext, mUri, mHeaders); - } - setState(State.Initialized); - } catch (final IOException e) { - Log.d(TAG, "" + e.getMessage()); - } catch (final IllegalArgumentException e) { - Log.d(TAG, "" + e.getMessage()); - } catch (final SecurityException e) { - Log.d(TAG, "" + e.getMessage()); - } catch (final IllegalStateException e) { - Log.d(TAG, "" + e.getMessage()); - } catch (final NullPointerException e) { - Log.d(TAG, "" + e.getMessage()); - } finally { - try { - if (afd != null) - afd.close(); - if (fis != null) - fis.close(); - } catch (final IOException ioe) { /* Ignore... */ } - - if ((mState & State.Initialized) == 0) { - setState(State.Error); - onErrorNative(MediaPlayer.MEDIA_ERROR_UNKNOWN, - -1004 /*MEDIA_ERROR_IO*/, - mID); - return; - } - } - } - - - public int getCurrentPosition() - { - int currentPosition = 0; - if ((mState & (State.Idle - | State.Initialized - | State.Prepared - | State.Started - | State.Paused - | State.Stopped - | State.PlaybackCompleted)) == 0) { - return currentPosition; - } - - try { - currentPosition = mMediaPlayer.getCurrentPosition(); - } catch (final IllegalStateException e) { - Log.d(TAG, "" + e.getMessage()); - } - - return currentPosition; - } - - - public int getDuration() - { - int duration = 0; - if ((mState & (State.Prepared - | State.Started - | State.Paused - | State.Stopped - | State.PlaybackCompleted)) == 0) { - return duration; - } - - try { - duration = mMediaPlayer.getDuration(); - } catch (final IllegalStateException e) { - Log.d(TAG, "" + e.getMessage()); - } - - return duration; - } - - public void setVolume(int volume) - { - if (volume < 0) - volume = 0; - - if (volume > 100) - volume = 100; - - mVolume = volume; - - if (!mMuted) - setVolumeHelper(mVolume); - } - - private void setVolumeHelper(int volume) - { - if ((mState & (State.Idle - | State.Initialized - | State.Stopped - | State.Prepared - | State.Started - | State.Paused - | State.PlaybackCompleted)) == 0) { - return; - } - - try { - float newVolume = (float)volume / 100; - mMediaPlayer.setVolume(newVolume, newVolume); - } catch (final IllegalStateException e) { - Log.d(TAG, "" + e.getMessage()); - } - } - - public SurfaceHolder display() - { - return mSurfaceHolder; - } - - public void setDisplay(SurfaceHolder sh) - { - mSurfaceHolder = sh; - - if ((mState & State.Uninitialized) != 0) - return; - - mMediaPlayer.setDisplay(mSurfaceHolder); - } - - - public int getVolume() - { - return mVolume; - } - - public void mute(final boolean mute) - { - mMuted = mute; - setVolumeHelper(mute ? 0 : mVolume); - } - - public boolean isMuted() - { - return mMuted; - } - - - public void reset() - { - if ((mState & (State.Idle - | State.Initialized - | State.Prepared - | State.Started - | State.Paused - | State.Stopped - | State.PlaybackCompleted - | State.Error)) == 0) { - return; - } - - mMediaPlayer.reset(); - setState(State.Idle); - } - - public void release() - { - if (mMediaPlayer != null) { - mMediaPlayer.reset(); - mMediaPlayer.release(); - mMediaPlayer = null; - } - - setState(State.Uninitialized); - } - - public void setAudioAttributes(int type, int usage) - { - mAudioAttributes = new AudioAttributes.Builder() - .setUsage(usage) - .setContentType(type) - .build(); - - setAudioAttributes(mMediaPlayer, mAudioAttributes); - } - - static private void setAudioAttributes(MediaPlayer player, AudioAttributes attr) - { - if (player == null || attr == null) - return; - - try { - player.setAudioAttributes(attr); - } catch (final IllegalArgumentException e) { - Log.d(TAG, "" + e.getMessage()); - } - } -} diff --git a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtCameraListener.java b/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtCameraListener.java deleted file mode 100644 index ff26d90c3..000000000 --- a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtCameraListener.java +++ /dev/null @@ -1,216 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtMultimedia of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -package org.qtproject.qt.android.multimedia; - -import android.hardware.Camera; -import android.graphics.ImageFormat; -import android.graphics.SurfaceTexture; -import android.util.Log; -import java.lang.Math; - -public class QtCameraListener implements Camera.ShutterCallback, - Camera.PictureCallback, - Camera.AutoFocusCallback, - Camera.PreviewCallback -{ - private static final String TAG = "Qt Camera"; - - private static final int BUFFER_POOL_SIZE = 2; - - private int m_cameraId = -1; - - private boolean m_notifyNewFrames = false; - private boolean m_notifyWhenFrameAvailable = false; - private byte[][] m_previewBuffers = null; - private byte[] m_lastPreviewBuffer = null; - private Camera.Size m_previewSize = null; - private int m_previewFormat = ImageFormat.NV21; // Default preview format on all devices - private int m_previewBytesPerLine = -1; - - private QtCameraListener(int id) - { - m_cameraId = id; - } - - public void notifyNewFrames(boolean notify) - { - m_notifyNewFrames = notify; - } - - public void notifyWhenFrameAvailable(boolean notify) - { - m_notifyWhenFrameAvailable = notify; - } - - public byte[] lastPreviewBuffer() - { - return m_lastPreviewBuffer; - } - - public int previewWidth() - { - if (m_previewSize == null) - return -1; - - return m_previewSize.width; - } - - public int previewHeight() - { - if (m_previewSize == null) - return -1; - - return m_previewSize.height; - } - - public int previewFormat() - { - return m_previewFormat; - } - - public int previewBytesPerLine() - { - return m_previewBytesPerLine; - } - - public void clearPreviewCallback(Camera camera) - { - camera.setPreviewCallbackWithBuffer(null); - } - - public void setupPreviewCallback(Camera camera) - { - // Clear previous callback (also clears added buffers) - clearPreviewCallback(camera); - m_lastPreviewBuffer = null; - - final Camera.Parameters params = camera.getParameters(); - m_previewSize = params.getPreviewSize(); - m_previewFormat = params.getPreviewFormat(); - - int bufferSizeNeeded = 0; - if (m_previewFormat == ImageFormat.YV12) { - // For YV12, bytes per line must be a multiple of 16 - final int yStride = (int) Math.ceil(m_previewSize.width / 16.0) * 16; - final int uvStride = (int) Math.ceil((yStride / 2) / 16.0) * 16; - final int ySize = yStride * m_previewSize.height; - final int uvSize = uvStride * m_previewSize.height / 2; - bufferSizeNeeded = ySize + uvSize * 2; - - m_previewBytesPerLine = yStride; - - } else { - double bytesPerPixel = ImageFormat.getBitsPerPixel(m_previewFormat) / 8.0; - bufferSizeNeeded = (int) Math.ceil(bytesPerPixel * m_previewSize.width * m_previewSize.height); - - // bytes per line are calculated only for the first plane - switch (m_previewFormat) { - case ImageFormat.NV21: - m_previewBytesPerLine = m_previewSize.width; // 1 byte per sample and tightly packed - break; - case ImageFormat.RGB_565: - case ImageFormat.YUY2: - m_previewBytesPerLine = m_previewSize.width * 2; // 2 bytes per pixel - break; - default: - m_previewBytesPerLine = -1; - break; - } - } - - // We could keep the same buffers when they are already bigger than the required size - // but the Android doc says the size must match, so in doubt just replace them. - if (m_previewBuffers == null || m_previewBuffers[0].length != bufferSizeNeeded) - m_previewBuffers = new byte[BUFFER_POOL_SIZE][bufferSizeNeeded]; - - // Add callback and queue all buffers - camera.setPreviewCallbackWithBuffer(this); - for (byte[] buffer : m_previewBuffers) - camera.addCallbackBuffer(buffer); - } - - @Override - public void onPreviewFrame(byte[] data, Camera camera) - { - // Re-enqueue the last buffer - if (m_lastPreviewBuffer != null) - camera.addCallbackBuffer(m_lastPreviewBuffer); - - m_lastPreviewBuffer = data; - - if (data != null) { - if (m_notifyWhenFrameAvailable) { - m_notifyWhenFrameAvailable = false; - notifyFrameAvailable(m_cameraId); - } - if (m_notifyNewFrames) { - notifyNewPreviewFrame(m_cameraId, data, - m_previewSize.width, m_previewSize.height, - m_previewFormat, - m_previewBytesPerLine); - } - } - } - - @Override - public void onShutter() - { - notifyPictureExposed(m_cameraId); - } - - @Override - public void onPictureTaken(byte[] data, Camera camera) - { - notifyPictureCaptured(m_cameraId, data); - } - - @Override - public void onAutoFocus(boolean success, Camera camera) - { - notifyAutoFocusComplete(m_cameraId, success); - } - - private static native void notifyAutoFocusComplete(int id, boolean success); - private static native void notifyPictureExposed(int id); - private static native void notifyPictureCaptured(int id, byte[] data); - private static native void notifyNewPreviewFrame(int id, byte[] data, int width, int height, - int pixelFormat, int bytesPerLine); - private static native void notifyFrameAvailable(int id); -} diff --git a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtMediaRecorderListener.java b/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtMediaRecorderListener.java deleted file mode 100644 index bf1763dee..000000000 --- a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtMediaRecorderListener.java +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtMultimedia of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -package org.qtproject.qt.android.multimedia; - -import android.media.MediaRecorder; - -public class QtMediaRecorderListener implements MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener -{ - private long m_id = -1; - - public QtMediaRecorderListener(long id) - { - m_id = id; - } - - @Override - public void onError(MediaRecorder mr, int what, int extra) - { - notifyError(m_id, what, extra); - } - - @Override - public void onInfo(MediaRecorder mr, int what, int extra) - { - notifyInfo(m_id, what, extra); - } - - private static native void notifyError(long id, int what, int extra); - private static native void notifyInfo(long id, int what, int extra); -} diff --git a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtMultimediaUtils.java b/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtMultimediaUtils.java deleted file mode 100644 index 28d56e0dd..000000000 --- a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtMultimediaUtils.java +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtMultimedia of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -package org.qtproject.qt.android.multimedia; - -import android.app.Activity; -import android.content.Context; -import android.view.OrientationEventListener; -import android.os.Environment; -import android.media.MediaScannerConnection; -import java.lang.String; -import java.io.File; - -public class QtMultimediaUtils -{ - static private class OrientationListener extends OrientationEventListener - { - static public int deviceOrientation = 0; - - public OrientationListener(Context context) - { - super(context); - } - - @Override - public void onOrientationChanged(int orientation) - { - if (orientation == ORIENTATION_UNKNOWN) - return; - - deviceOrientation = orientation; - } - } - - static private Context m_context = null; - static private OrientationListener m_orientationListener = null; - - static public void setActivity(Activity qtMainActivity, Object qtActivityDelegate) - { - } - - static public void setContext(Context context) - { - m_context = context; - m_orientationListener = new OrientationListener(context); - } - - public QtMultimediaUtils() - { - } - - static void enableOrientationListener(boolean enable) - { - if (enable) - m_orientationListener.enable(); - else - m_orientationListener.disable(); - } - - static int getDeviceOrientation() - { - return m_orientationListener.deviceOrientation; - } - - static String getDefaultMediaDirectory(int type) - { - String dirType = new String(); - switch (type) { - case 0: - dirType = Environment.DIRECTORY_MUSIC; - break; - case 1: - dirType = Environment.DIRECTORY_MOVIES; - break; - case 2: - dirType = Environment.DIRECTORY_DCIM; - break; - default: - break; - } - - File path = new File(""); - if (type == 3) { - // There is no API for knowing the standard location for sounds - // such as voice recording. Though, it's typically in the 'Sounds' - // directory at the root of the external storage - path = new File(Environment.getExternalStorageDirectory().getAbsolutePath() - + File.separator + "Sounds"); - } else { - path = Environment.getExternalStoragePublicDirectory(dirType); - } - - path.mkdirs(); // make sure the directory exists - - return path.getAbsolutePath(); - } - - static void registerMediaFile(String file) - { - MediaScannerConnection.scanFile(m_context, new String[] { file }, null, null); - } -} diff --git a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtSurfaceHolderCallback.java b/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtSurfaceHolderCallback.java deleted file mode 100644 index 62000716b..000000000 --- a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtSurfaceHolderCallback.java +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtMultimedia of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -package org.qtproject.qt.android.multimedia; - -import android.view.SurfaceHolder; - -public class QtSurfaceHolderCallback implements SurfaceHolder.Callback -{ - private long m_id = -1; - - public QtSurfaceHolderCallback(long id) - { - m_id = id; - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) - { - } - - @Override - public void surfaceCreated(SurfaceHolder holder) - { - notifySurfaceCreated(m_id); - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) - { - notifySurfaceDestroyed(m_id); - } - - - private static native void notifySurfaceCreated(long id); - private static native void notifySurfaceDestroyed(long id); -} diff --git a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtSurfaceTextureHolder.java b/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtSurfaceTextureHolder.java deleted file mode 100644 index ea7a41505..000000000 --- a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtSurfaceTextureHolder.java +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the (whatever) of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -package org.qtproject.qt.android.multimedia; - -import android.view.SurfaceHolder; -import android.view.Surface; -import android.graphics.Rect; -import android.graphics.Canvas; - -public class QtSurfaceTextureHolder implements SurfaceHolder -{ - private Surface surfaceTexture; - - public QtSurfaceTextureHolder(Surface surface) - { - surfaceTexture = surface; - } - - @Override - public void addCallback(SurfaceHolder.Callback callback) - { - } - - @Override - public Surface getSurface() - { - return surfaceTexture; - } - - @Override - public Rect getSurfaceFrame() - { - return new Rect(); - } - - @Override - public boolean isCreating() - { - return false; - } - - @Override - public Canvas lockCanvas(Rect dirty) - { - return new Canvas(); - } - - @Override - public Canvas lockCanvas() - { - return new Canvas(); - } - - @Override - public void removeCallback(SurfaceHolder.Callback callback) - { - } - - @Override - public void setFixedSize(int width, int height) - { - } - - @Override - public void setFormat(int format) - { - } - - @Override - public void setKeepScreenOn(boolean screenOn) - { - } - - @Override - public void setSizeFromLayout() - { - } - - @Override - public void setType(int type) - { - } - - @Override - public void unlockCanvasAndPost(Canvas canvas) - { - } -} diff --git a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtSurfaceTextureListener.java b/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtSurfaceTextureListener.java deleted file mode 100644 index 4d929c6ad..000000000 --- a/src/plugins/android/jar/src/org/qtproject/qt/android/multimedia/QtSurfaceTextureListener.java +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtMultimedia of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -package org.qtproject.qt.android.multimedia; - -import android.graphics.SurfaceTexture; - -public class QtSurfaceTextureListener implements SurfaceTexture.OnFrameAvailableListener -{ - private final long m_id; - - public QtSurfaceTextureListener(long id) - { - m_id = id; - } - - @Override - public void onFrameAvailable(SurfaceTexture surfaceTexture) - { - notifyFrameAvailable(m_id); - } - - private static native void notifyFrameAvailable(long id); -} diff --git a/src/plugins/android/src/CMakeLists.txt b/src/plugins/android/src/CMakeLists.txt deleted file mode 100644 index 938bd7ae2..000000000 --- a/src/plugins/android/src/CMakeLists.txt +++ /dev/null @@ -1,58 +0,0 @@ -# Generated from src.pro. - -##################################################################### -## QAndroidMediaServicePlugin Plugin: -##################################################################### - -qt_internal_add_plugin(QAndroidMediaServicePlugin - OUTPUT_NAME qtmedia_android - TYPE mediaservice - SOURCES - common/qandroidglobal.h - common/qandroidmultimediautils.cpp common/qandroidmultimediautils.h - common/qandroidvideooutput.cpp common/qandroidvideooutput.h - mediacapture/qandroidaudioencodersettingscontrol.cpp mediacapture/qandroidaudioencodersettingscontrol.h - mediacapture/qandroidaudioinputselectorcontrol.cpp mediacapture/qandroidaudioinputselectorcontrol.h - mediacapture/qandroidcameracontrol.cpp mediacapture/qandroidcameracontrol.h - mediacapture/qandroidcameraexposurecontrol.cpp mediacapture/qandroidcameraexposurecontrol.h - mediacapture/qandroidcamerafocuscontrol.cpp mediacapture/qandroidcamerafocuscontrol.h - mediacapture/qandroidcameraimagecapturecontrol.cpp mediacapture/qandroidcameraimagecapturecontrol.h - mediacapture/qandroidcameraimageprocessingcontrol.cpp mediacapture/qandroidcameraimageprocessingcontrol.h - mediacapture/qandroidcamerasession.cpp mediacapture/qandroidcamerasession.h - mediacapture/qandroidcameravideorenderercontrol.cpp mediacapture/qandroidcameravideorenderercontrol.h - mediacapture/qandroidcaptureservice.cpp mediacapture/qandroidcaptureservice.h - mediacapture/qandroidcapturesession.cpp mediacapture/qandroidcapturesession.h - mediacapture/qandroidimageencodercontrol.cpp mediacapture/qandroidimageencodercontrol.h - mediacapture/qandroidmediacontainercontrol.cpp mediacapture/qandroidmediacontainercontrol.h - mediacapture/qandroidmediarecordercontrol.cpp mediacapture/qandroidmediarecordercontrol.h - mediacapture/qandroidmediavideoprobecontrol.cpp mediacapture/qandroidmediavideoprobecontrol.h - mediacapture/qandroidvideodeviceselectorcontrol.cpp mediacapture/qandroidvideodeviceselectorcontrol.h - mediacapture/qandroidvideoencodersettingscontrol.cpp mediacapture/qandroidvideoencodersettingscontrol.h - mediaplayer/qandroidmediaplayercontrol.cpp mediaplayer/qandroidmediaplayercontrol.h - mediaplayer/qandroidmediaplayervideorenderercontrol.cpp mediaplayer/qandroidmediaplayervideorenderercontrol.h - mediaplayer/qandroidmediaservice.cpp mediaplayer/qandroidmediaservice.h - mediaplayer/qandroidmetadatareadercontrol.cpp mediaplayer/qandroidmetadatareadercontrol.h - qandroidmediaserviceplugin.cpp qandroidmediaserviceplugin.h - wrappers/jni/androidcamera.cpp wrappers/jni/androidcamera.h - wrappers/jni/androidmediametadataretriever.cpp wrappers/jni/androidmediametadataretriever.h - wrappers/jni/androidmediaplayer.cpp wrappers/jni/androidmediaplayer.h - wrappers/jni/androidmediarecorder.cpp wrappers/jni/androidmediarecorder.h - wrappers/jni/androidmultimediautils.cpp wrappers/jni/androidmultimediautils.h - wrappers/jni/androidsurfacetexture.cpp wrappers/jni/androidsurfacetexture.h - wrappers/jni/androidsurfaceview.cpp wrappers/jni/androidsurfaceview.h - INCLUDE_DIRECTORIES - common - mediacapture - mediaplayer - wrappers/jni - PUBLIC_LIBRARIES - Qt::Core - Qt::CorePrivate - Qt::Gui - Qt::MultimediaPrivate - Qt::Network - Qt::OpenGL -) - -#### Keys ignored in scope 1:.:.:src.pro:<TRUE>: -# OTHER_FILES = "android_mediaservice.json" diff --git a/src/plugins/android/src/android_mediaservice.json b/src/plugins/android/src/android_mediaservice.json deleted file mode 100644 index df4bccb2b..000000000 --- a/src/plugins/android/src/android_mediaservice.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["androidmultimedia"], - "Services": ["org.qt-project.qt.camera", "org.qt-project.qt.mediaplayer", "org.qt-project.qt.audiosource"] -} diff --git a/src/plugins/android/src/common/common.pri b/src/plugins/android/src/common/common.pri deleted file mode 100644 index 1b02b99ea..000000000 --- a/src/plugins/android/src/common/common.pri +++ /dev/null @@ -1,10 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/qandroidglobal.h \ - $$PWD/qandroidvideooutput.h \ - $$PWD/qandroidmultimediautils.h - -SOURCES += \ - $$PWD/qandroidvideooutput.cpp \ - $$PWD/qandroidmultimediautils.cpp diff --git a/src/plugins/android/src/common/qandroidglobal.h b/src/plugins/android/src/common/qandroidglobal.h deleted file mode 100644 index e7342be97..000000000 --- a/src/plugins/android/src/common/qandroidglobal.h +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDGLOBAL_H -#define QANDROIDGLOBAL_H - -#include <QtCore/qglobal.h> -#include <QtCore/qloggingcategory.h> - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qtAndroidMediaPlugin) - -QT_END_NAMESPACE - -#endif // QANDROIDGLOBAL_H diff --git a/src/plugins/android/src/common/qandroidmultimediautils.cpp b/src/plugins/android/src/common/qandroidmultimediautils.cpp deleted file mode 100644 index 1f03d5d29..000000000 --- a/src/plugins/android/src/common/qandroidmultimediautils.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidmultimediautils.h" -#include "qandroidglobal.h" - -#include <qlist.h> -#include <QtCore/private/qjni_p.h> -#include <QtCore/private/qjnihelpers_p.h> - -QT_BEGIN_NAMESPACE - -int qt_findClosestValue(const QList<int> &list, int value) -{ - if (list.size() < 2) - return 0; - - int begin = 0; - int end = list.size() - 1; - int pivot = begin + (end - begin) / 2; - int v = list.at(pivot); - - while (end - begin > 1) { - if (value == v) - return pivot; - - if (value > v) - begin = pivot; - else - end = pivot; - - pivot = begin + (end - begin) / 2; - v = list.at(pivot); - } - - return value - v >= list.at(pivot + 1) - value ? pivot + 1 : pivot; -} - -bool qt_sizeLessThan(const QSize &s1, const QSize &s2) -{ - return s1.width() * s1.height() < s2.width() * s2.height(); -} - -QVideoFrame::PixelFormat qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat f) -{ - switch (f) { - case AndroidCamera::NV21: - return QVideoFrame::Format_NV21; - case AndroidCamera::YV12: - return QVideoFrame::Format_YV12; - case AndroidCamera::RGB565: - return QVideoFrame::Format_RGB565; - case AndroidCamera::YUY2: - return QVideoFrame::Format_YUYV; - case AndroidCamera::JPEG: - return QVideoFrame::Format_Jpeg; - default: - return QVideoFrame::Format_Invalid; - } -} - -AndroidCamera::ImageFormat qt_androidImageFormatFromPixelFormat(QVideoFrame::PixelFormat f) -{ - switch (f) { - case QVideoFrame::Format_NV21: - return AndroidCamera::NV21; - case QVideoFrame::Format_YV12: - return AndroidCamera::YV12; - case QVideoFrame::Format_RGB565: - return AndroidCamera::RGB565; - case QVideoFrame::Format_YUYV: - return AndroidCamera::YUY2; - case QVideoFrame::Format_Jpeg: - return AndroidCamera::JPEG; - default: - return AndroidCamera::UnknownImageFormat; - } -} - -static bool androidRequestPermission(const QString &key) -{ - using namespace QtAndroidPrivate; - - if (androidSdkVersion() < 23) - return true; - - PermissionsResult res = checkPermission(key); - if (res == PermissionsResult::Granted) // Permission already granted? - return true; - - QJNIEnvironmentPrivate env; - const auto &results = requestPermissionsSync(env, QStringList() << key); - if (!results.contains(key)) { - qCWarning(qtAndroidMediaPlugin, "No permission found for key: %s", qPrintable(key)); - return false; - } - - if (results[key] == PermissionsResult::Denied) { - qCDebug(qtAndroidMediaPlugin, "%s - Permission denied by user!", qPrintable(key)); - return false; - } - - return true; -} - -bool qt_androidRequestCameraPermission() -{ - return androidRequestPermission(QLatin1String("android.permission.CAMERA")); -} - -bool qt_androidRequestRecordingPermission() -{ - return androidRequestPermission(QLatin1String("android.permission.RECORD_AUDIO")); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/common/qandroidmultimediautils.h b/src/plugins/android/src/common/qandroidmultimediautils.h deleted file mode 100644 index 381671cb8..000000000 --- a/src/plugins/android/src/common/qandroidmultimediautils.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDMULTIMEDIAUTILS_H -#define QANDROIDMULTIMEDIAUTILS_H - -#include <qglobal.h> -#include <qsize.h> -#include "androidcamera.h" - -QT_BEGIN_NAMESPACE - -// return the index of the closest value to <value> in <list> -// (binary search) -int qt_findClosestValue(const QList<int> &list, int value); - -bool qt_sizeLessThan(const QSize &s1, const QSize &s2); - -QVideoFrame::PixelFormat qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat f); -AndroidCamera::ImageFormat qt_androidImageFormatFromPixelFormat(QVideoFrame::PixelFormat f); - -bool qt_androidRequestCameraPermission(); -bool qt_androidRequestRecordingPermission(); - -QT_END_NAMESPACE - -#endif // QANDROIDMULTIMEDIAUTILS_H diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp deleted file mode 100644 index 3c6472482..000000000 --- a/src/plugins/android/src/common/qandroidvideooutput.cpp +++ /dev/null @@ -1,502 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidvideooutput.h" - -#include "androidsurfacetexture.h" -#include <QAbstractVideoSurface> -#include <QVideoSurfaceFormat> -#include <qevent.h> -#include <qcoreapplication.h> -#include <qopenglcontext.h> -#include <qopenglfunctions.h> -#include <qopenglshaderprogram.h> -#include <qopenglframebufferobject.h> -#include <QtCore/private/qjnihelpers_p.h> -#include <QtGui/QWindow> -#include <QtGui/QOffscreenSurface> - -QT_BEGIN_NAMESPACE - -static const GLfloat g_vertex_data[] = { - -1.f, 1.f, - 1.f, 1.f, - 1.f, -1.f, - -1.f, -1.f -}; - -static const GLfloat g_texture_data[] = { - 0.f, 0.f, - 1.f, 0.f, - 1.f, 1.f, - 0.f, 1.f -}; - -void OpenGLResourcesDeleter::deleteTextureHelper(quint32 id) -{ - if (id != 0) - glDeleteTextures(1, &id); -} - -void OpenGLResourcesDeleter::deleteFboHelper(void *fbo) -{ - delete reinterpret_cast<QOpenGLFramebufferObject *>(fbo); -} - -void OpenGLResourcesDeleter::deleteShaderProgramHelper(void *prog) -{ - delete reinterpret_cast<QOpenGLShaderProgram *>(prog); -} - -void OpenGLResourcesDeleter::deleteThisHelper() -{ - delete this; -} - -class AndroidTextureVideoBuffer : public QAbstractVideoBuffer -{ -public: - AndroidTextureVideoBuffer(QAndroidTextureVideoOutput *output, const QSize &size) - : QAbstractVideoBuffer(GLTextureHandle) - , m_mapMode(NotMapped) - , m_output(output) - , m_size(size) - , m_textureUpdated(false) - { - } - - virtual ~AndroidTextureVideoBuffer() {} - - MapMode mapMode() const override { return m_mapMode; } - - MapData map(MapMode mode) override - { - MapData mapData; - if (m_mapMode == NotMapped && mode == ReadOnly && updateFrame()) { - m_mapMode = mode; - m_image = m_output->m_fbo->toImage(); - - mapData.nBytes = static_cast<int>(m_image.sizeInBytes()); - mapData.nPlanes = 1; - mapData.bytesPerLine[0] = m_image.bytesPerLine(); - mapData.data[0] = m_image.bits(); - } - - return mapData; - } - - void unmap() override - { - m_image = QImage(); - m_mapMode = NotMapped; - } - - QVariant handle() const override - { - AndroidTextureVideoBuffer *that = const_cast<AndroidTextureVideoBuffer*>(this); - if (!that->updateFrame()) - return QVariant(); - - return m_output->m_fbo->texture(); - } - -private: - bool updateFrame() - { - // Even though the texture was updated in a previous call, we need to re-check - // that this has not become a stale buffer, e.g., if the output size changed or - // has since became invalid. - if (!m_output->m_nativeSize.isValid()) - return false; - - // Size changed - if (m_output->m_nativeSize != m_size) - return false; - - // In the unlikely event that we don't have a valid fbo, but have a valid size, - // force an update. - const bool forceUpdate = !m_output->m_fbo; - - if (m_textureUpdated && !forceUpdate) - return true; - - // update the video texture (called from the render thread) - return (m_textureUpdated = m_output->renderFrameToFbo()); - } - - MapMode m_mapMode; - QAndroidTextureVideoOutput *m_output; - QImage m_image; - QSize m_size; - bool m_textureUpdated; -}; - -QAndroidTextureVideoOutput::QAndroidTextureVideoOutput(QObject *parent) - : QAndroidVideoOutput(parent) - , m_surface(0) - , m_surfaceTexture(0) - , m_externalTex(0) - , m_fbo(0) - , m_program(0) - , m_glDeleter(0) - , m_surfaceTextureCanAttachToContext(QtAndroidPrivate::androidSdkVersion() >= 16) -{ - -} - -QAndroidTextureVideoOutput::~QAndroidTextureVideoOutput() -{ - delete m_offscreenSurface; - delete m_glContext; - clearSurfaceTexture(); - - if (m_glDeleter) { // Make sure all of these are deleted on the render thread. - m_glDeleter->deleteFbo(m_fbo); - m_glDeleter->deleteShaderProgram(m_program); - m_glDeleter->deleteTexture(m_externalTex); - m_glDeleter->deleteThis(); - } -} - -QAbstractVideoSurface *QAndroidTextureVideoOutput::surface() const -{ - return m_surface; -} - -void QAndroidTextureVideoOutput::setSurface(QAbstractVideoSurface *surface) -{ - if (surface == m_surface) - return; - - if (m_surface) { - if (m_surface->isActive()) - m_surface->stop(); - - if (!m_surfaceTextureCanAttachToContext) - m_surface->setProperty("_q_GLThreadCallback", QVariant()); - } - - m_surface = surface; - - if (m_surface && !m_surfaceTextureCanAttachToContext) { - m_surface->setProperty("_q_GLThreadCallback", - QVariant::fromValue<QObject*>(this)); - } -} - -bool QAndroidTextureVideoOutput::isReady() -{ - return m_surfaceTextureCanAttachToContext || QOpenGLContext::currentContext() || m_externalTex; -} - -bool QAndroidTextureVideoOutput::initSurfaceTexture() -{ - if (m_surfaceTexture) - return true; - - if (!m_surface) - return false; - - if (!m_surfaceTextureCanAttachToContext) { - // if we have an OpenGL context in the current thread, create a texture. Otherwise, wait - // for the GL render thread to call us back to do it. - if (QOpenGLContext::currentContext()) { - glGenTextures(1, &m_externalTex); - if (!m_glDeleter) - m_glDeleter = new OpenGLResourcesDeleter; - } else if (!m_externalTex) { - return false; - } - } - - QMutexLocker locker(&m_mutex); - - m_surfaceTexture = new AndroidSurfaceTexture(m_externalTex); - - if (m_surfaceTexture->surfaceTexture() != 0) { - connect(m_surfaceTexture, SIGNAL(frameAvailable()), this, SLOT(onFrameAvailable())); - } else { - delete m_surfaceTexture; - m_surfaceTexture = 0; - if (m_glDeleter) - m_glDeleter->deleteTexture(m_externalTex); - m_externalTex = 0; - } - - return m_surfaceTexture != 0; -} - -void QAndroidTextureVideoOutput::clearSurfaceTexture() -{ - QMutexLocker locker(&m_mutex); - if (m_surfaceTexture) { - delete m_surfaceTexture; - m_surfaceTexture = 0; - } - - // Also reset the attached OpenGL texture - // Note: The Android SurfaceTexture class does not release the texture on deletion, - // only if detachFromGLContext() called (API level >= 16), so we'll do it manually, - // on the render thread. - if (m_surfaceTextureCanAttachToContext) { - if (m_glDeleter) - m_glDeleter->deleteTexture(m_externalTex); - m_externalTex = 0; - } -} - -AndroidSurfaceTexture *QAndroidTextureVideoOutput::surfaceTexture() -{ - if (!initSurfaceTexture()) - return 0; - - return m_surfaceTexture; -} - -void QAndroidTextureVideoOutput::setVideoSize(const QSize &size) -{ - QMutexLocker locker(&m_mutex); - if (m_nativeSize == size) - return; - - stop(); - - m_nativeSize = size; -} - -void QAndroidTextureVideoOutput::stop() -{ - if (m_surface && m_surface->isActive()) - m_surface->stop(); - m_nativeSize = QSize(); -} - -void QAndroidTextureVideoOutput::reset() -{ - // flush pending frame - if (m_surface) - m_surface->present(QVideoFrame()); - - clearSurfaceTexture(); -} - -void QAndroidTextureVideoOutput::onFrameAvailable() -{ - if (!m_nativeSize.isValid() || !m_surface) - return; - - QAbstractVideoBuffer *buffer = new AndroidTextureVideoBuffer(this, m_nativeSize); - QVideoFrame frame(buffer, m_nativeSize, QVideoFrame::Format_ABGR32); - - if (m_surface->isActive() && (m_surface->surfaceFormat().pixelFormat() != frame.pixelFormat() - || m_surface->surfaceFormat().frameSize() != frame.size())) { - m_surface->stop(); - } - - if (!m_surface->isActive()) { - QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), - QAbstractVideoBuffer::GLTextureHandle); - - m_surface->start(format); - } - - if (m_surface->isActive()) - m_surface->present(frame); -} - -bool QAndroidTextureVideoOutput::renderFrameToFbo() -{ - QMutexLocker locker(&m_mutex); - - if (!m_nativeSize.isValid() || !m_surfaceTexture) - return false; - - QOpenGLContext *shareContext = !m_glContext && m_surface - ? qobject_cast<QOpenGLContext*>(m_surface->property("GLContext").value<QObject*>()) - : nullptr; - - // Make sure we have an OpenGL context to make current. - if (shareContext || (!QOpenGLContext::currentContext() && !m_glContext)) { - // Create Hidden QWindow surface to create context in this thread. - m_offscreenSurface = new QWindow(); - m_offscreenSurface->setSurfaceType(QWindow::OpenGLSurface); - // Needs geometry to be a valid surface, but size is not important. - m_offscreenSurface->setGeometry(0, 0, 1, 1); - m_offscreenSurface->create(); - m_offscreenSurface->moveToThread(m_surface->thread()); - - // Create OpenGL context and set share context from surface. - m_glContext = new QOpenGLContext(); - m_glContext->setFormat(m_offscreenSurface->requestedFormat()); - - auto surface = qobject_cast<QAbstractVideoSurface *>(m_surface->property("videoSurface").value<QObject *>()); - if (!surface) - surface = m_surface; - if (shareContext) - m_glContext->setShareContext(shareContext); - - if (!m_glContext->create()) { - qWarning("Failed to create QOpenGLContext"); - return false; - } - } - - if (m_glContext) - m_glContext->makeCurrent(m_offscreenSurface); - - createGLResources(); - - m_surfaceTexture->updateTexImage(); - - // save current render states - GLboolean stencilTestEnabled; - GLboolean depthTestEnabled; - GLboolean scissorTestEnabled; - GLboolean blendEnabled; - glGetBooleanv(GL_STENCIL_TEST, &stencilTestEnabled); - glGetBooleanv(GL_DEPTH_TEST, &depthTestEnabled); - glGetBooleanv(GL_SCISSOR_TEST, &scissorTestEnabled); - glGetBooleanv(GL_BLEND, &blendEnabled); - - if (stencilTestEnabled) - glDisable(GL_STENCIL_TEST); - if (depthTestEnabled) - glDisable(GL_DEPTH_TEST); - if (scissorTestEnabled) - glDisable(GL_SCISSOR_TEST); - if (blendEnabled) - glDisable(GL_BLEND); - - m_fbo->bind(); - - glViewport(0, 0, m_nativeSize.width(), m_nativeSize.height()); - - m_program->bind(); - m_program->enableAttributeArray(0); - m_program->enableAttributeArray(1); - m_program->setUniformValue("frameTexture", GLuint(0)); - m_program->setUniformValue("texMatrix", m_surfaceTexture->getTransformMatrix()); - - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, g_vertex_data); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, g_texture_data); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - m_program->disableAttributeArray(0); - m_program->disableAttributeArray(1); - - glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); - m_fbo->release(); - - // restore render states - if (stencilTestEnabled) - glEnable(GL_STENCIL_TEST); - if (depthTestEnabled) - glEnable(GL_DEPTH_TEST); - if (scissorTestEnabled) - glEnable(GL_SCISSOR_TEST); - if (blendEnabled) - glEnable(GL_BLEND); - - return true; -} - -void QAndroidTextureVideoOutput::createGLResources() -{ - Q_ASSERT(QOpenGLContext::currentContext() != NULL); - - if (!m_glDeleter) - m_glDeleter = new OpenGLResourcesDeleter; - - if (m_surfaceTextureCanAttachToContext && !m_externalTex) { - m_surfaceTexture->detachFromGLContext(); - glGenTextures(1, &m_externalTex); - m_surfaceTexture->attachToGLContext(m_externalTex); - } - - if (!m_fbo || m_fbo->size() != m_nativeSize) { - delete m_fbo; - m_fbo = new QOpenGLFramebufferObject(m_nativeSize); - } - - if (!m_program) { - m_program = new QOpenGLShaderProgram; - - QOpenGLShader *vertexShader = new QOpenGLShader(QOpenGLShader::Vertex, m_program); - vertexShader->compileSourceCode("attribute highp vec4 vertexCoordsArray; \n" \ - "attribute highp vec2 textureCoordArray; \n" \ - "uniform highp mat4 texMatrix; \n" \ - "varying highp vec2 textureCoords; \n" \ - "void main(void) \n" \ - "{ \n" \ - " gl_Position = vertexCoordsArray; \n" \ - " textureCoords = (texMatrix * vec4(textureCoordArray, 0.0, 1.0)).xy; \n" \ - "}\n"); - m_program->addShader(vertexShader); - - QOpenGLShader *fragmentShader = new QOpenGLShader(QOpenGLShader::Fragment, m_program); - fragmentShader->compileSourceCode("#extension GL_OES_EGL_image_external : require \n" \ - "varying highp vec2 textureCoords; \n" \ - "uniform samplerExternalOES frameTexture; \n" \ - "void main() \n" \ - "{ \n" \ - " gl_FragColor = texture2D(frameTexture, textureCoords); \n" \ - "}\n"); - m_program->addShader(fragmentShader); - - m_program->bindAttributeLocation("vertexCoordsArray", 0); - m_program->bindAttributeLocation("textureCoordArray", 1); - m_program->link(); - } -} - -void QAndroidTextureVideoOutput::customEvent(QEvent *e) -{ - if (e->type() == QEvent::User) { - // This is running in the render thread (OpenGL enabled) - if (!m_surfaceTextureCanAttachToContext && !m_externalTex) { - glGenTextures(1, &m_externalTex); - if (!m_glDeleter) // We'll use this to cleanup GL resources in the correct thread - m_glDeleter = new OpenGLResourcesDeleter; - emit readyChanged(true); - } - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/common/qandroidvideooutput.h b/src/plugins/android/src/common/qandroidvideooutput.h deleted file mode 100644 index 456fe8e22..000000000 --- a/src/plugins/android/src/common/qandroidvideooutput.h +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDVIDEOOUTPUT_H -#define QANDROIDVIDEOOUTPUT_H - -#include <qobject.h> -#include <qsize.h> -#include <qmutex.h> - -QT_BEGIN_NAMESPACE - -class AndroidSurfaceTexture; -class AndroidSurfaceHolder; -class QOpenGLFramebufferObject; -class QOpenGLShaderProgram; -class QAbstractVideoSurface; -class QWindow; -class QOpenGLContext; - -class QAndroidVideoOutput : public QObject -{ - Q_OBJECT -public: - virtual ~QAndroidVideoOutput() { } - - virtual AndroidSurfaceTexture *surfaceTexture() { return 0; } - virtual AndroidSurfaceHolder *surfaceHolder() { return 0; } - - virtual bool isReady() { return true; } - - virtual void setVideoSize(const QSize &) { } - virtual void stop() { } - virtual void reset() { } - -Q_SIGNALS: - void readyChanged(bool); - -protected: - QAndroidVideoOutput(QObject *parent) : QObject(parent) { } -}; - -class OpenGLResourcesDeleter : public QObject -{ - Q_OBJECT -public: - void deleteTexture(quint32 id) { QMetaObject::invokeMethod(this, "deleteTextureHelper", Qt::AutoConnection, Q_ARG(quint32, id)); } - void deleteFbo(QOpenGLFramebufferObject *fbo) { QMetaObject::invokeMethod(this, "deleteFboHelper", Qt::AutoConnection, Q_ARG(void *, fbo)); } - void deleteShaderProgram(QOpenGLShaderProgram *prog) { QMetaObject::invokeMethod(this, "deleteShaderProgramHelper", Qt::AutoConnection, Q_ARG(void *, prog)); } - void deleteThis() { QMetaObject::invokeMethod(this, "deleteThisHelper"); } - -private: - Q_INVOKABLE void deleteTextureHelper(quint32 id); - Q_INVOKABLE void deleteFboHelper(void *fbo); - Q_INVOKABLE void deleteShaderProgramHelper(void *prog); - Q_INVOKABLE void deleteThisHelper(); -}; - -class QAndroidTextureVideoOutput : public QAndroidVideoOutput -{ - Q_OBJECT -public: - explicit QAndroidTextureVideoOutput(QObject *parent = 0); - ~QAndroidTextureVideoOutput() override; - - QAbstractVideoSurface *surface() const; - void setSurface(QAbstractVideoSurface *surface); - - AndroidSurfaceTexture *surfaceTexture() override; - - bool isReady() override; - void setVideoSize(const QSize &) override; - void stop() override; - void reset() override; - - void customEvent(QEvent *) override; - -private Q_SLOTS: - void onFrameAvailable(); - -private: - bool initSurfaceTexture(); - bool renderFrameToFbo(); - void createGLResources(); - - QMutex m_mutex; - void clearSurfaceTexture(); - - QAbstractVideoSurface *m_surface; - QSize m_nativeSize; - - AndroidSurfaceTexture *m_surfaceTexture; - - quint32 m_externalTex; - QOpenGLFramebufferObject *m_fbo; - QOpenGLShaderProgram *m_program; - OpenGLResourcesDeleter *m_glDeleter; - - bool m_surfaceTextureCanAttachToContext; - - QWindow *m_offscreenSurface = nullptr; - QOpenGLContext *m_glContext = nullptr; - - friend class AndroidTextureVideoBuffer; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDVIDEOOUTPUT_H diff --git a/src/plugins/android/src/mediacapture/mediacapture.pri b/src/plugins/android/src/mediacapture/mediacapture.pri deleted file mode 100644 index 2ec62efc4..000000000 --- a/src/plugins/android/src/mediacapture/mediacapture.pri +++ /dev/null @@ -1,39 +0,0 @@ -INCLUDEPATH += $$PWD - -SOURCES += \ - $$PWD/qandroidcaptureservice.cpp \ - $$PWD/qandroidcameracontrol.cpp \ - $$PWD/qandroidvideodeviceselectorcontrol.cpp \ - $$PWD/qandroidcamerasession.cpp \ - $$PWD/qandroidcameraexposurecontrol.cpp \ - $$PWD/qandroidcameraimageprocessingcontrol.cpp \ - $$PWD/qandroidimageencodercontrol.cpp \ - $$PWD/qandroidcameraimagecapturecontrol.cpp \ - $$PWD/qandroidcamerafocuscontrol.cpp \ - $$PWD/qandroidcapturesession.cpp \ - $$PWD/qandroidmediarecordercontrol.cpp \ - $$PWD/qandroidaudioencodersettingscontrol.cpp \ - $$PWD/qandroidmediacontainercontrol.cpp \ - $$PWD/qandroidvideoencodersettingscontrol.cpp \ - $$PWD/qandroidaudioinputselectorcontrol.cpp \ - $$PWD/qandroidmediavideoprobecontrol.cpp \ - $$PWD/qandroidcameravideorenderercontrol.cpp - -HEADERS += \ - $$PWD/qandroidcaptureservice.h \ - $$PWD/qandroidcameracontrol.h \ - $$PWD/qandroidvideodeviceselectorcontrol.h \ - $$PWD/qandroidcamerasession.h \ - $$PWD/qandroidcameraexposurecontrol.h \ - $$PWD/qandroidcameraimageprocessingcontrol.h \ - $$PWD/qandroidimageencodercontrol.h \ - $$PWD/qandroidcameraimagecapturecontrol.h \ - $$PWD/qandroidcamerafocuscontrol.h \ - $$PWD/qandroidcapturesession.h \ - $$PWD/qandroidmediarecordercontrol.h \ - $$PWD/qandroidaudioencodersettingscontrol.h \ - $$PWD/qandroidmediacontainercontrol.h \ - $$PWD/qandroidvideoencodersettingscontrol.h \ - $$PWD/qandroidaudioinputselectorcontrol.h \ - $$PWD/qandroidmediavideoprobecontrol.h \ - $$PWD/qandroidcameravideorenderercontrol.h diff --git a/src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.cpp b/src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.cpp deleted file mode 100644 index 4bd94425d..000000000 --- a/src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidaudioencodersettingscontrol.h" - -#include "qandroidcapturesession.h" - -QT_BEGIN_NAMESPACE - -QAndroidAudioEncoderSettingsControl::QAndroidAudioEncoderSettingsControl(QAndroidCaptureSession *session) - : QAudioEncoderSettingsControl() - , m_session(session) -{ -} - -QStringList QAndroidAudioEncoderSettingsControl::supportedAudioCodecs() const -{ - return QStringList() << QLatin1String("amr-nb") << QLatin1String("amr-wb") << QLatin1String("aac"); -} - -QString QAndroidAudioEncoderSettingsControl::codecDescription(const QString &codecName) const -{ - if (codecName == QLatin1String("amr-nb")) - return tr("Adaptive Multi-Rate Narrowband (AMR-NB) audio codec"); - else if (codecName == QLatin1String("amr-wb")) - return tr("Adaptive Multi-Rate Wideband (AMR-WB) audio codec"); - else if (codecName == QLatin1String("aac")) - return tr("AAC Low Complexity (AAC-LC) audio codec"); - - return QString(); -} - -QList<int> QAndroidAudioEncoderSettingsControl::supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const -{ - if (continuous) - *continuous = false; - - if (settings.isNull() || settings.codec().isNull() || settings.codec() == QLatin1String("aac")) { - return QList<int>() << 8000 << 11025 << 12000 << 16000 << 22050 - << 24000 << 32000 << 44100 << 48000 << 96000; - } else if (settings.codec() == QLatin1String("amr-nb")) { - return QList<int>() << 8000; - } else if (settings.codec() == QLatin1String("amr-wb")) { - return QList<int>() << 16000; - } - - return QList<int>(); -} - -QAudioEncoderSettings QAndroidAudioEncoderSettingsControl::audioSettings() const -{ - return m_session->audioSettings(); -} - -void QAndroidAudioEncoderSettingsControl::setAudioSettings(const QAudioEncoderSettings &settings) -{ - m_session->setAudioSettings(settings); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.h b/src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.h deleted file mode 100644 index e68bf6ef7..000000000 --- a/src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDAUDIOENCODERSETTINGSCONTROL_H -#define QANDROIDAUDIOENCODERSETTINGSCONTROL_H - -#include <qaudioencodersettingscontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCaptureSession; - -class QAndroidAudioEncoderSettingsControl : public QAudioEncoderSettingsControl -{ - Q_OBJECT -public: - explicit QAndroidAudioEncoderSettingsControl(QAndroidCaptureSession *session); - - QStringList supportedAudioCodecs() const override; - QString codecDescription(const QString &codecName) const override; - QList<int> supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous = 0) const override; - QAudioEncoderSettings audioSettings() const override; - void setAudioSettings(const QAudioEncoderSettings &settings) override; - -private: - QAndroidCaptureSession *m_session; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDAUDIOENCODERSETTINGSCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.cpp deleted file mode 100644 index bf2161a7e..000000000 --- a/src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidaudioinputselectorcontrol.h" - -#include "qandroidcapturesession.h" - -QT_BEGIN_NAMESPACE - -QAndroidAudioInputSelectorControl::QAndroidAudioInputSelectorControl(QAndroidCaptureSession *session) - : QAudioInputSelectorControl() - , m_session(session) -{ - connect(m_session, SIGNAL(audioInputChanged(QString)), this, SIGNAL(activeInputChanged(QString))); -} - -QList<QString> QAndroidAudioInputSelectorControl::availableInputs() const -{ - return QList<QString>() << QLatin1String("default") - << QLatin1String("mic") - << QLatin1String("voice_uplink") - << QLatin1String("voice_downlink") - << QLatin1String("voice_call") - << QLatin1String("voice_recognition"); -} - -QString QAndroidAudioInputSelectorControl::inputDescription(const QString& name) const -{ - return availableDeviceDescription(name.toLatin1()); -} - -QString QAndroidAudioInputSelectorControl::defaultInput() const -{ - return QLatin1String("default"); -} - -QString QAndroidAudioInputSelectorControl::activeInput() const -{ - return m_session->audioInput(); -} - -void QAndroidAudioInputSelectorControl::setActiveInput(const QString& name) -{ - m_session->setAudioInput(name); -} - -QList<QByteArray> QAndroidAudioInputSelectorControl::availableDevices() -{ - return QList<QByteArray>() << "default" - << "mic" - << "voice_uplink" - << "voice_downlink" - << "voice_call" - << "voice_recognition"; -} - -QString QAndroidAudioInputSelectorControl::availableDeviceDescription(const QByteArray &device) -{ - if (device == "default") - return QLatin1String("Default audio source"); - else if (device == "mic") - return QLatin1String("Microphone audio source"); - else if (device == "voice_uplink") - return QLatin1String("Voice call uplink (Tx) audio source"); - else if (device == "voice_downlink") - return QLatin1String("Voice call downlink (Rx) audio source"); - else if (device == "voice_call") - return QLatin1String("Voice call uplink + downlink audio source"); - else if (device == "voice_recognition") - return QLatin1String("Microphone audio source tuned for voice recognition"); - else - return QString(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.h b/src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.h deleted file mode 100644 index c24167fb3..000000000 --- a/src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDAUDIOINPUTSELECTORCONTROL_H -#define QANDROIDAUDIOINPUTSELECTORCONTROL_H - -#include <qaudioinputselectorcontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCaptureSession; - -class QAndroidAudioInputSelectorControl : public QAudioInputSelectorControl -{ - Q_OBJECT -public: - explicit QAndroidAudioInputSelectorControl(QAndroidCaptureSession *session); - - QList<QString> availableInputs() const; - QString inputDescription(const QString& name) const; - QString defaultInput() const; - - QString activeInput() const; - void setActiveInput(const QString& name); - - static QList<QByteArray> availableDevices(); - static QString availableDeviceDescription(const QByteArray &device); - -private: - QAndroidCaptureSession *m_session; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDAUDIOINPUTSELECTORCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcameracontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameracontrol.cpp deleted file mode 100644 index f9efaea8a..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcameracontrol.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidcameracontrol.h" -#include "qandroidcamerasession.h" -#include <qtimer.h> - -QT_BEGIN_NAMESPACE - -QAndroidCameraControl::QAndroidCameraControl(QAndroidCameraSession *session) - : QCameraControl(0) - , m_cameraSession(session) - -{ - connect(m_cameraSession, SIGNAL(statusChanged(QCamera::Status)), - this, SIGNAL(statusChanged(QCamera::Status))); - - connect(m_cameraSession, SIGNAL(stateChanged(QCamera::State)), - this, SIGNAL(stateChanged(QCamera::State))); - - connect(m_cameraSession, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString))); - - connect(m_cameraSession, SIGNAL(captureModeChanged(QCamera::CaptureModes)), - this, SIGNAL(captureModeChanged(QCamera::CaptureModes))); - - connect(m_cameraSession, SIGNAL(opened()), this, SLOT(onCameraOpened())); - - m_recalculateTimer = new QTimer(this); - m_recalculateTimer->setInterval(1000); - m_recalculateTimer->setSingleShot(true); - connect(m_recalculateTimer, SIGNAL(timeout()), this, SLOT(onRecalculateTimeOut())); -} - -QAndroidCameraControl::~QAndroidCameraControl() -{ -} - -QCamera::CaptureModes QAndroidCameraControl::captureMode() const -{ - return m_cameraSession->captureMode(); -} - -void QAndroidCameraControl::setCaptureMode(QCamera::CaptureModes mode) -{ - m_cameraSession->setCaptureMode(mode); -} - -bool QAndroidCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const -{ - return m_cameraSession->isCaptureModeSupported(mode); -} - -void QAndroidCameraControl::setState(QCamera::State state) -{ - m_cameraSession->setState(state); -} - -QCamera::State QAndroidCameraControl::state() const -{ - return m_cameraSession->state(); -} - -QCamera::Status QAndroidCameraControl::status() const -{ - return m_cameraSession->status(); -} - -bool QAndroidCameraControl::canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const -{ - Q_UNUSED(status); - - switch (changeType) { - case QCameraControl::CaptureMode: - case QCameraControl::ImageEncodingSettings: - case QCameraControl::VideoEncodingSettings: - case QCameraControl::Viewfinder: - return true; - default: - return false; - } -} - - -QCamera::LockTypes QAndroidCameraControl::supportedLocks() const -{ - return m_supportedLocks; -} - -QCamera::LockStatus QAndroidCameraControl::lockStatus(QCamera::LockType lock) const -{ - if (!m_supportedLocks.testFlag(lock) || !m_cameraSession->camera()) - return QCamera::Unlocked; - - if (lock == QCamera::LockFocus) - return m_focusLockStatus; - - if (lock == QCamera::LockExposure) - return m_exposureLockStatus; - - if (lock == QCamera::LockWhiteBalance) - return m_whiteBalanceLockStatus; - - return QCamera::Unlocked; -} - -void QAndroidCameraControl::searchAndLock(QCamera::LockTypes locks) -{ - if (!m_cameraSession->camera()) - return; - - // filter out unsupported locks - locks &= m_supportedLocks; - - if (locks.testFlag(QCamera::LockFocus)) { - QString focusMode = m_cameraSession->camera()->getFocusMode(); - if (focusMode == QLatin1String("auto") - || focusMode == QLatin1String("macro") - || focusMode == QLatin1String("continuous-picture") - || focusMode == QLatin1String("continuous-video")) { - - if (m_focusLockStatus == QCamera::Searching) - m_cameraSession->camera()->cancelAutoFocus(); - else - setFocusLockStatus(QCamera::Searching, QCamera::UserRequest); - - m_cameraSession->camera()->autoFocus(); - - } else { - setFocusLockStatus(QCamera::Locked, QCamera::LockAcquired); - } - } - - if (locks.testFlag(QCamera::LockExposure) && m_exposureLockStatus != QCamera::Searching) { - if (m_cameraSession->camera()->getAutoExposureLock()) { - // if already locked, unlock and give some time to recalculate exposure - m_cameraSession->camera()->setAutoExposureLock(false); - setExposureLockStatus(QCamera::Searching, QCamera::UserRequest); - } else { - m_cameraSession->camera()->setAutoExposureLock(true); - setExposureLockStatus(QCamera::Locked, QCamera::LockAcquired); - } - } - - if (locks.testFlag(QCamera::LockWhiteBalance) && m_whiteBalanceLockStatus != QCamera::Searching) { - if (m_cameraSession->camera()->getAutoWhiteBalanceLock()) { - // if already locked, unlock and give some time to recalculate white balance - m_cameraSession->camera()->setAutoWhiteBalanceLock(false); - setWhiteBalanceLockStatus(QCamera::Searching, QCamera::UserRequest); - } else { - m_cameraSession->camera()->setAutoWhiteBalanceLock(true); - setWhiteBalanceLockStatus(QCamera::Locked, QCamera::LockAcquired); - } - } - - if (m_exposureLockStatus == QCamera::Searching || m_whiteBalanceLockStatus == QCamera::Searching) - m_recalculateTimer->start(); -} - -void QAndroidCameraControl::unlock(QCamera::LockTypes locks) -{ - if (!m_cameraSession->camera()) - return; - - if (m_recalculateTimer->isActive()) - m_recalculateTimer->stop(); - - // filter out unsupported locks - locks &= m_supportedLocks; - - if (locks.testFlag(QCamera::LockFocus)) { - m_cameraSession->camera()->cancelAutoFocus(); - setFocusLockStatus(QCamera::Unlocked, QCamera::UserRequest); - } - - if (locks.testFlag(QCamera::LockExposure)) { - m_cameraSession->camera()->setAutoExposureLock(false); - setExposureLockStatus(QCamera::Unlocked, QCamera::UserRequest); - } - - if (locks.testFlag(QCamera::LockWhiteBalance)) { - m_cameraSession->camera()->setAutoWhiteBalanceLock(false); - setWhiteBalanceLockStatus(QCamera::Unlocked, QCamera::UserRequest); - } -} - -void QAndroidCameraControl::onCameraOpened() -{ - m_supportedLocks = QCamera::NoLock; - m_focusLockStatus = QCamera::Unlocked; - m_exposureLockStatus = QCamera::Unlocked; - m_whiteBalanceLockStatus = QCamera::Unlocked; - - // check if focus lock is supported - QStringList focusModes = m_cameraSession->camera()->getSupportedFocusModes(); - for (int i = 0; i < focusModes.size(); ++i) { - const QString &focusMode = focusModes.at(i); - if (focusMode == QLatin1String("auto") - || focusMode == QLatin1String("continuous-picture") - || focusMode == QLatin1String("continuous-video") - || focusMode == QLatin1String("macro")) { - - m_supportedLocks |= QCamera::LockFocus; - setFocusLockStatus(QCamera::Unlocked, QCamera::UserRequest); - - connect(m_cameraSession->camera(), SIGNAL(autoFocusComplete(bool)), - this, SLOT(onCameraAutoFocusComplete(bool))); - - break; - } - } - - if (m_cameraSession->camera()->isAutoExposureLockSupported()) { - m_supportedLocks |= QCamera::LockExposure; - setExposureLockStatus(QCamera::Unlocked, QCamera::UserRequest); - } - - if (m_cameraSession->camera()->isAutoWhiteBalanceLockSupported()) { - m_supportedLocks |= QCamera::LockWhiteBalance; - setWhiteBalanceLockStatus(QCamera::Unlocked, QCamera::UserRequest); - - connect(m_cameraSession->camera(), SIGNAL(whiteBalanceChanged()), - this, SLOT(onWhiteBalanceChanged())); - } -} - -void QAndroidCameraControl::onCameraAutoFocusComplete(bool success) -{ - m_focusLockStatus = success ? QCamera::Locked : QCamera::Unlocked; - QCamera::LockChangeReason reason = success ? QCamera::LockAcquired : QCamera::LockFailed; - emit lockStatusChanged(QCamera::LockFocus, m_focusLockStatus, reason); -} - -void QAndroidCameraControl::onRecalculateTimeOut() -{ - if (m_exposureLockStatus == QCamera::Searching) { - m_cameraSession->camera()->setAutoExposureLock(true); - setExposureLockStatus(QCamera::Locked, QCamera::LockAcquired); - } - - if (m_whiteBalanceLockStatus == QCamera::Searching) { - m_cameraSession->camera()->setAutoWhiteBalanceLock(true); - setWhiteBalanceLockStatus(QCamera::Locked, QCamera::LockAcquired); - } -} - -void QAndroidCameraControl::onWhiteBalanceChanged() -{ - // changing the white balance mode releases the white balance lock - if (m_whiteBalanceLockStatus != QCamera::Unlocked) - setWhiteBalanceLockStatus(QCamera::Unlocked, QCamera::LockLost); -} - -void QAndroidCameraControl::setFocusLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason) -{ - m_focusLockStatus = status; - emit lockStatusChanged(QCamera::LockFocus, m_focusLockStatus, reason); -} - -void QAndroidCameraControl::setWhiteBalanceLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason) -{ - m_whiteBalanceLockStatus = status; - emit lockStatusChanged(QCamera::LockWhiteBalance, m_whiteBalanceLockStatus, reason); -} - -void QAndroidCameraControl::setExposureLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason) -{ - m_exposureLockStatus = status; - emit lockStatusChanged(QCamera::LockExposure, m_exposureLockStatus, reason); -} - -QList<QCameraViewfinderSettings> QAndroidCameraControl::supportedViewfinderSettings() const -{ - QList<QCameraViewfinderSettings> viewfinderSettings; - - const QList<QSize> previewSizes = m_cameraSession->getSupportedPreviewSizes(); - const QList<QVideoFrame::PixelFormat> pixelFormats = m_cameraSession->getSupportedPixelFormats(); - const QList<AndroidCamera::FpsRange> fpsRanges = m_cameraSession->getSupportedPreviewFpsRange(); - - viewfinderSettings.reserve(previewSizes.size() * pixelFormats.size() * fpsRanges.size()); - - for (const QSize& size : previewSizes) { - for (QVideoFrame::PixelFormat pixelFormat : pixelFormats) { - for (const AndroidCamera::FpsRange& fpsRange : fpsRanges) { - QCameraViewfinderSettings s; - s.setResolution(size); - s.setPixelAspectRatio(QSize(1, 1)); - s.setPixelFormat(pixelFormat); - s.setMinimumFrameRate(fpsRange.getMinReal()); - s.setMaximumFrameRate(fpsRange.getMaxReal()); - viewfinderSettings << s; - } - } - } - return viewfinderSettings; -} - -QCameraViewfinderSettings QAndroidCameraControl::viewfinderSettings() const -{ - return m_cameraSession->viewfinderSettings(); -} - -void QAndroidCameraControl::setViewfinderSettings(const QCameraViewfinderSettings &settings) -{ - m_cameraSession->setViewfinderSettings(settings); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameracontrol.h b/src/plugins/android/src/mediacapture/qandroidcameracontrol.h deleted file mode 100644 index d30f507c3..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcameracontrol.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QANDROIDCAMERACONTROL_H -#define QANDROIDCAMERACONTROL_H - -#include <qcameracontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCameraSession; - -class QAndroidCameraControl : public QCameraControl -{ - Q_OBJECT -public: - explicit QAndroidCameraControl(QAndroidCameraSession *session); - virtual ~QAndroidCameraControl(); - - QCamera::State state() const override; - void setState(QCamera::State state) override; - - QCamera::Status status() const override; - - QCamera::CaptureModes captureMode() const override; - void setCaptureMode(QCamera::CaptureModes mode) override; - bool isCaptureModeSupported(QCamera::CaptureModes mode) const override; - - bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const override; - - QCamera::LockTypes supportedLocks() const override; - QCamera::LockStatus lockStatus(QCamera::LockType lock) const override; - void searchAndLock(QCamera::LockTypes locks) override; - void unlock(QCamera::LockTypes locks) override; - - QList<QCameraViewfinderSettings> supportedViewfinderSettings() const override; - QCameraViewfinderSettings viewfinderSettings() const override; - void setViewfinderSettings(const QCameraViewfinderSettings &settings) override; - -private Q_SLOTS: - void onCameraOpened(); - void onCameraAutoFocusComplete(bool success); - void onRecalculateTimeOut(); - void onWhiteBalanceChanged(); - -private: - void setFocusLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason); - void setWhiteBalanceLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason); - void setExposureLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason); - - QAndroidCameraSession *m_cameraSession; - - QTimer *m_recalculateTimer; - - QCamera::LockTypes m_supportedLocks; - - QCamera::LockStatus m_focusLockStatus; - QCamera::LockStatus m_exposureLockStatus; - QCamera::LockStatus m_whiteBalanceLockStatus; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDCAMERACONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.cpp deleted file mode 100644 index 154e66f47..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidcameraexposurecontrol.h" - -#include "qandroidcamerasession.h" -#include "androidcamera.h" - -QT_BEGIN_NAMESPACE - -QAndroidCameraExposureControl::QAndroidCameraExposureControl(QAndroidCameraSession *session) - : QCameraExposureControl() - , m_session(session) - , m_minExposureCompensationIndex(0) - , m_maxExposureCompensationIndex(0) - , m_exposureCompensationStep(0.0) - , m_requestedExposureCompensation(0.0) - , m_actualExposureCompensation(0.0) - , m_requestedExposureMode(QCameraExposure::ExposureAuto) - , m_actualExposureMode(QCameraExposure::ExposureAuto) -{ - connect(m_session, SIGNAL(opened()), - this, SLOT(onCameraOpened())); -} - -bool QAndroidCameraExposureControl::isParameterSupported(ExposureParameter parameter) const -{ - if (!m_session->camera()) - return false; - - switch (parameter) { - case QCameraExposureControl::ISO: - return false; - case QCameraExposureControl::Aperture: - return false; - case QCameraExposureControl::ShutterSpeed: - return false; - case QCameraExposureControl::ExposureCompensation: - return !m_supportedExposureCompensations.isEmpty(); - case QCameraExposureControl::TorchPower: - return false; - case QCameraExposureControl::ExposureMode: - return !m_supportedExposureModes.isEmpty(); - default: - return false; - } -} - -QVariantList QAndroidCameraExposureControl::supportedParameterRange(ExposureParameter parameter, bool *continuous) const -{ - if (!m_session->camera()) - return QVariantList(); - - if (continuous) - *continuous = false; - - if (parameter == QCameraExposureControl::ExposureCompensation) - return m_supportedExposureCompensations; - else if (parameter == QCameraExposureControl::ExposureMode) - return m_supportedExposureModes; - - return QVariantList(); -} - -QVariant QAndroidCameraExposureControl::requestedValue(ExposureParameter parameter) const -{ - if (parameter == QCameraExposureControl::ExposureCompensation) - return QVariant::fromValue(m_requestedExposureCompensation); - else if (parameter == QCameraExposureControl::ExposureMode) - return QVariant::fromValue(m_requestedExposureMode); - - return QVariant(); -} - -QVariant QAndroidCameraExposureControl::actualValue(ExposureParameter parameter) const -{ - if (parameter == QCameraExposureControl::ExposureCompensation) - return QVariant::fromValue(m_actualExposureCompensation); - else if (parameter == QCameraExposureControl::ExposureMode) - return QVariant::fromValue(m_actualExposureMode); - - return QVariant(); -} - -bool QAndroidCameraExposureControl::setValue(ExposureParameter parameter, const QVariant& value) -{ - if (!value.isValid()) - return false; - - if (parameter == QCameraExposureControl::ExposureCompensation) { - qreal expComp = value.toReal(); - if (!qFuzzyCompare(m_requestedExposureCompensation, expComp)) { - m_requestedExposureCompensation = expComp; - emit requestedValueChanged(QCameraExposureControl::ExposureCompensation); - } - - if (!m_session->camera()) - return true; - - int expCompIndex = qRound(m_requestedExposureCompensation / m_exposureCompensationStep); - if (expCompIndex >= m_minExposureCompensationIndex - && expCompIndex <= m_maxExposureCompensationIndex) { - qreal comp = expCompIndex * m_exposureCompensationStep; - m_session->camera()->setExposureCompensation(expCompIndex); - if (!qFuzzyCompare(m_actualExposureCompensation, comp)) { - m_actualExposureCompensation = expCompIndex * m_exposureCompensationStep; - emit actualValueChanged(QCameraExposureControl::ExposureCompensation); - } - - return true; - } - - } else if (parameter == QCameraExposureControl::ExposureMode) { - QCameraExposure::ExposureMode expMode = value.value<QCameraExposure::ExposureMode>(); - if (m_requestedExposureMode != expMode) { - m_requestedExposureMode = expMode; - emit requestedValueChanged(QCameraExposureControl::ExposureMode); - } - - if (!m_session->camera()) - return true; - - if (!m_supportedExposureModes.isEmpty()) { - m_actualExposureMode = m_requestedExposureMode; - - QString sceneMode; - switch (m_requestedExposureMode) { - case QCameraExposure::ExposureAuto: - sceneMode = QLatin1String("auto"); - break; - case QCameraExposure::ExposureSports: - sceneMode = QLatin1String("sports"); - break; - case QCameraExposure::ExposurePortrait: - sceneMode = QLatin1String("portrait"); - break; - case QCameraExposure::ExposureBeach: - sceneMode = QLatin1String("beach"); - break; - case QCameraExposure::ExposureSnow: - sceneMode = QLatin1String("snow"); - break; - case QCameraExposure::ExposureNight: - sceneMode = QLatin1String("night"); - break; - case QCameraExposure::ExposureAction: - sceneMode = QLatin1String("action"); - break; - case QCameraExposure::ExposureLandscape: - sceneMode = QLatin1String("landscape"); - break; - case QCameraExposure::ExposureNightPortrait: - sceneMode = QLatin1String("night-portrait"); - break; - case QCameraExposure::ExposureTheatre: - sceneMode = QLatin1String("theatre"); - break; - case QCameraExposure::ExposureSunset: - sceneMode = QLatin1String("sunset"); - break; - case QCameraExposure::ExposureSteadyPhoto: - sceneMode = QLatin1String("steadyphoto"); - break; - case QCameraExposure::ExposureFireworks: - sceneMode = QLatin1String("fireworks"); - break; - case QCameraExposure::ExposureParty: - sceneMode = QLatin1String("party"); - break; - case QCameraExposure::ExposureCandlelight: - sceneMode = QLatin1String("candlelight"); - break; - case QCameraExposure::ExposureBarcode: - sceneMode = QLatin1String("barcode"); - break; - default: - sceneMode = QLatin1String("auto"); - m_actualExposureMode = QCameraExposure::ExposureAuto; - break; - } - - m_session->camera()->setSceneMode(sceneMode); - emit actualValueChanged(QCameraExposureControl::ExposureMode); - - return true; - } - } - - return false; -} - -void QAndroidCameraExposureControl::onCameraOpened() -{ - m_supportedExposureCompensations.clear(); - m_minExposureCompensationIndex = m_session->camera()->getMinExposureCompensation(); - m_maxExposureCompensationIndex = m_session->camera()->getMaxExposureCompensation(); - m_exposureCompensationStep = m_session->camera()->getExposureCompensationStep(); - if (m_minExposureCompensationIndex != 0 || m_maxExposureCompensationIndex != 0) { - for (int i = m_minExposureCompensationIndex; i <= m_maxExposureCompensationIndex; ++i) - m_supportedExposureCompensations.append(i * m_exposureCompensationStep); - emit parameterRangeChanged(QCameraExposureControl::ExposureCompensation); - } - - m_supportedExposureModes.clear(); - QStringList sceneModes = m_session->camera()->getSupportedSceneModes(); - if (!sceneModes.isEmpty()) { - for (int i = 0; i < sceneModes.size(); ++i) { - const QString &sceneMode = sceneModes.at(i); - if (sceneMode == QLatin1String("auto")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureAuto); - else if (sceneMode == QLatin1String("beach")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureBeach); - else if (sceneMode == QLatin1String("night")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureNight); - else if (sceneMode == QLatin1String("portrait")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposurePortrait); - else if (sceneMode == QLatin1String("snow")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureSnow); - else if (sceneMode == QLatin1String("sports")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureSports); - else if (sceneMode == QLatin1String("action")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureAction); - else if (sceneMode == QLatin1String("landscape")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureLandscape); - else if (sceneMode == QLatin1String("night-portrait")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureNightPortrait); - else if (sceneMode == QLatin1String("theatre")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureTheatre); - else if (sceneMode == QLatin1String("sunset")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureSunset); - else if (sceneMode == QLatin1String("steadyphoto")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureSteadyPhoto); - else if (sceneMode == QLatin1String("fireworks")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureFireworks); - else if (sceneMode == QLatin1String("party")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureParty); - else if (sceneMode == QLatin1String("candlelight")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureCandlelight); - else if (sceneMode == QLatin1String("barcode")) - m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureBarcode); - } - emit parameterRangeChanged(QCameraExposureControl::ExposureMode); - } - - setValue(QCameraExposureControl::ExposureCompensation, QVariant::fromValue(m_requestedExposureCompensation)); - setValue(QCameraExposureControl::ExposureMode, QVariant::fromValue(m_requestedExposureMode)); - - m_supportedFlashModes.clear(); - - QStringList flashModes = m_session->camera()->getSupportedFlashModes(); - for (int i = 0; i < flashModes.size(); ++i) { - const QString &flashMode = flashModes.at(i); - if (flashMode == QLatin1String("off")) - m_supportedFlashModes << QCameraExposure::FlashOff; - else if (flashMode == QLatin1String("auto")) - m_supportedFlashModes << QCameraExposure::FlashAuto; - else if (flashMode == QLatin1String("on")) - m_supportedFlashModes << QCameraExposure::FlashOn; - else if (flashMode == QLatin1String("red-eye")) - m_supportedFlashModes << QCameraExposure::FlashRedEyeReduction; - else if (flashMode == QLatin1String("torch")) - m_supportedFlashModes << QCameraExposure::FlashVideoLight; - } - - if (!m_supportedFlashModes.contains(m_flashMode)) - m_flashMode = QCameraExposure::FlashOff; - - setFlashMode(m_flashMode); -} - - -QCameraExposure::FlashModes QAndroidCameraExposureControl::flashMode() const -{ - return m_flashMode; -} - -void QAndroidCameraExposureControl::setFlashMode(QCameraExposure::FlashModes mode) -{ - if (!m_session->camera()) { - m_flashMode = mode; - return; - } - - if (!isFlashModeSupported(mode)) - return; - - // if torch was enabled, it first needs to be turned off before setting another mode - if (m_flashMode == QCameraExposure::FlashVideoLight) - m_session->camera()->setFlashMode(QLatin1String("off")); - - m_flashMode = mode; - - QString flashMode; - if (mode.testFlag(QCameraExposure::FlashAuto)) - flashMode = QLatin1String("auto"); - else if (mode.testFlag(QCameraExposure::FlashOn)) - flashMode = QLatin1String("on"); - else if (mode.testFlag(QCameraExposure::FlashRedEyeReduction)) - flashMode = QLatin1String("red-eye"); - else if (mode.testFlag(QCameraExposure::FlashVideoLight)) - flashMode = QLatin1String("torch"); - else // FlashOff - flashMode = QLatin1String("off"); - - m_session->camera()->setFlashMode(flashMode); -} - -bool QAndroidCameraExposureControl::isFlashModeSupported(QCameraExposure::FlashModes mode) const -{ - return m_session->camera() ? m_supportedFlashModes.contains(mode) : false; -} - -bool QAndroidCameraExposureControl::isFlashReady() const -{ - // Android doesn't have an API for that - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.h b/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.h deleted file mode 100644 index df1e26eea..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDCAMERAEXPOSURECONTROL_H -#define QANDROIDCAMERAEXPOSURECONTROL_H - -#include <qcameraexposurecontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCameraSession; - -class QAndroidCameraExposureControl : public QCameraExposureControl -{ - Q_OBJECT -public: - explicit QAndroidCameraExposureControl(QAndroidCameraSession *session); - - bool isParameterSupported(ExposureParameter parameter) const override; - QVariantList supportedParameterRange(ExposureParameter parameter, bool *continuous) const override; - - QVariant requestedValue(ExposureParameter parameter) const override; - QVariant actualValue(ExposureParameter parameter) const override; - bool setValue(ExposureParameter parameter, const QVariant& value) override; - - QCameraExposure::FlashModes flashMode() const override; - void setFlashMode(QCameraExposure::FlashModes mode) override; - bool isFlashModeSupported(QCameraExposure::FlashModes mode) const override; - bool isFlashReady() const override; - -private Q_SLOTS: - void onCameraOpened(); - -private: - QAndroidCameraSession *m_session; - - QVariantList m_supportedExposureCompensations; - QVariantList m_supportedExposureModes; - - int m_minExposureCompensationIndex; - int m_maxExposureCompensationIndex; - qreal m_exposureCompensationStep; - - qreal m_requestedExposureCompensation; - qreal m_actualExposureCompensation; - QCameraExposure::ExposureMode m_requestedExposureMode; - QCameraExposure::ExposureMode m_actualExposureMode; - - QList<QCameraExposure::FlashModes> m_supportedFlashModes; - QCameraExposure::FlashModes m_flashMode; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDCAMERAEXPOSURECONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.cpp deleted file mode 100644 index b6145330e..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidcamerafocuscontrol.h" - -#include "qandroidcamerasession.h" -#include "androidcamera.h" - -#include "qandroidmultimediautils.h" -#include <qmath.h> - -QT_BEGIN_NAMESPACE - -static QRect adjustedArea(const QRectF &area) -{ - // Qt maps focus points in the range (0.0, 0.0) -> (1.0, 1.0) - // Android maps focus points in the range (-1000, -1000) -> (1000, 1000) - // Converts an area in Qt coordinates to Android coordinates - return QRect(-1000 + qRound(area.x() * 2000), - -1000 + qRound(area.y() * 2000), - qRound(area.width() * 2000), - qRound(area.height() * 2000)) - .intersected(QRect(-1000, -1000, 2000, 2000)); -} - -QAndroidCameraFocusControl::QAndroidCameraFocusControl(QAndroidCameraSession *session) - : QCameraFocusControl() - , m_session(session) - , m_focusMode(QCameraFocus::AutoFocus) - , m_focusPointMode(QCameraFocus::FocusPointAuto) - , m_actualFocusPoint(0.5, 0.5) - , m_continuousPictureFocusSupported(false) - , m_continuousVideoFocusSupported(false) -{ - connect(m_session, SIGNAL(opened()), - this, SLOT(onCameraOpened())); - connect(m_session, SIGNAL(captureModeChanged(QCamera::CaptureModes)), - this, SLOT(onCameraCaptureModeChanged())); -} - -QCameraFocus::FocusModes QAndroidCameraFocusControl::focusMode() const -{ - return m_focusMode; -} - -void QAndroidCameraFocusControl::setFocusMode(QCameraFocus::FocusModes mode) -{ - if (!m_session->camera()) { - setFocusModeHelper(mode); - return; - } - - if (isFocusModeSupported(mode)) { - QString focusMode = QLatin1String("fixed"); - - if (mode.testFlag(QCameraFocus::HyperfocalFocus)) { - focusMode = QLatin1String("edof"); - } else if (mode.testFlag(QCameraFocus::ManualFocus)) { - focusMode = QLatin1String("fixed"); - } else if (mode.testFlag(QCameraFocus::AutoFocus)) { - focusMode = QLatin1String("auto"); - } else if (mode.testFlag(QCameraFocus::MacroFocus)) { - focusMode = QLatin1String("macro"); - } else if (mode.testFlag(QCameraFocus::ContinuousFocus)) { - if ((m_session->captureMode().testFlag(QCamera::CaptureVideo) && m_continuousVideoFocusSupported) - || !m_continuousPictureFocusSupported) { - focusMode = QLatin1String("continuous-video"); - } else { - focusMode = QLatin1String("continuous-picture"); - } - } else if (mode.testFlag(QCameraFocus::InfinityFocus)) { - focusMode = QLatin1String("infinity"); - } - - m_session->camera()->setFocusMode(focusMode); - - // reset focus position - m_session->camera()->cancelAutoFocus(); - - setFocusModeHelper(mode); - } -} - -bool QAndroidCameraFocusControl::isFocusModeSupported(QCameraFocus::FocusModes mode) const -{ - return m_session->camera() ? m_supportedFocusModes.contains(mode) : false; -} - -QCameraFocus::FocusPointMode QAndroidCameraFocusControl::focusPointMode() const -{ - return m_focusPointMode; -} - -void QAndroidCameraFocusControl::setFocusPointMode(QCameraFocus::FocusPointMode mode) -{ - if (!m_session->camera()) { - setFocusPointModeHelper(mode); - return; - } - - if (isFocusPointModeSupported(mode)) { - if (mode == QCameraFocus::FocusPointCustom) { - m_actualFocusPoint = m_customFocusPoint; - } else { - // FocusPointAuto | FocusPointCenter - // note: there is no way to know the actual focus point in FocusPointAuto mode, - // so just report the focus point to be at the center of the frame - m_actualFocusPoint = QPointF(0.5, 0.5); - } - - setFocusPointModeHelper(mode); - - updateFocusZones(); - setCameraFocusArea(); - } -} - -bool QAndroidCameraFocusControl::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const -{ - return m_session->camera() ? m_supportedFocusPointModes.contains(mode) : false; -} - -QPointF QAndroidCameraFocusControl::customFocusPoint() const -{ - return m_customFocusPoint; -} - -void QAndroidCameraFocusControl::setCustomFocusPoint(const QPointF &point) -{ - if (m_customFocusPoint != point) { - m_customFocusPoint = point; - emit customFocusPointChanged(m_customFocusPoint); - } - - if (m_session->camera() && m_focusPointMode == QCameraFocus::FocusPointCustom) { - m_actualFocusPoint = m_customFocusPoint; - updateFocusZones(); - setCameraFocusArea(); - } -} - -QCameraFocusZoneList QAndroidCameraFocusControl::focusZones() const -{ - return m_focusZones; -} - -void QAndroidCameraFocusControl::onCameraOpened() -{ - connect(m_session->camera(), SIGNAL(previewSizeChanged()), - this, SLOT(onViewportSizeChanged())); - connect(m_session->camera(), SIGNAL(autoFocusStarted()), - this, SLOT(onAutoFocusStarted())); - connect(m_session->camera(), SIGNAL(autoFocusComplete(bool)), - this, SLOT(onAutoFocusComplete(bool))); - - m_supportedFocusModes.clear(); - m_continuousPictureFocusSupported = false; - m_continuousVideoFocusSupported = false; - m_supportedFocusPointModes.clear(); - - QStringList focusModes = m_session->camera()->getSupportedFocusModes(); - for (int i = 0; i < focusModes.size(); ++i) { - const QString &focusMode = focusModes.at(i); - if (focusMode == QLatin1String("auto")) { - m_supportedFocusModes << QCameraFocus::AutoFocus; - } else if (focusMode == QLatin1String("continuous-picture")) { - m_supportedFocusModes << QCameraFocus::ContinuousFocus; - m_continuousPictureFocusSupported = true; - } else if (focusMode == QLatin1String("continuous-video")) { - m_supportedFocusModes << QCameraFocus::ContinuousFocus; - m_continuousVideoFocusSupported = true; - } else if (focusMode == QLatin1String("edof")) { - m_supportedFocusModes << QCameraFocus::HyperfocalFocus; - } else if (focusMode == QLatin1String("fixed")) { - m_supportedFocusModes << QCameraFocus::ManualFocus; - } else if (focusMode == QLatin1String("infinity")) { - m_supportedFocusModes << QCameraFocus::InfinityFocus; - } else if (focusMode == QLatin1String("macro")) { - m_supportedFocusModes << QCameraFocus::MacroFocus; - } - } - - m_supportedFocusPointModes << QCameraFocus::FocusPointAuto; - if (m_session->camera()->getMaxNumFocusAreas() > 0) - m_supportedFocusPointModes << QCameraFocus::FocusPointCenter << QCameraFocus::FocusPointCustom; - - if (!m_supportedFocusModes.contains(m_focusMode)) - setFocusModeHelper(QCameraFocus::AutoFocus); - if (!m_supportedFocusPointModes.contains(m_focusPointMode)) - setFocusPointModeHelper(QCameraFocus::FocusPointAuto); - - setFocusMode(m_focusMode); - setCustomFocusPoint(m_customFocusPoint); - setFocusPointMode(m_focusPointMode); - - if (m_session->camera()->isZoomSupported()) { - m_zoomRatios = m_session->camera()->getZoomRatios(); - qreal maxZoom = m_zoomRatios.last() / qreal(100); - if (m_maximumZoom != maxZoom) { - m_maximumZoom = maxZoom; - emit maximumDigitalZoomChanged(m_maximumZoom); - } - zoomTo(1, m_requestedZoom); - } else { - m_zoomRatios.clear(); - if (!qFuzzyCompare(m_maximumZoom, qreal(1))) { - m_maximumZoom = 1.0; - emit maximumDigitalZoomChanged(m_maximumZoom); - } - } -} - -void QAndroidCameraFocusControl::updateFocusZones(QCameraFocusZone::FocusZoneStatus status) -{ - if (!m_session->camera()) - return; - - // create a focus zone (50x50 pixel) around the focus point - m_focusZones.clear(); - - if (!m_actualFocusPoint.isNull()) { - QSize viewportSize = m_session->camera()->previewSize(); - - if (!viewportSize.isValid()) - return; - - QSizeF focusSize(50.f / viewportSize.width(), 50.f / viewportSize.height()); - float x = qBound(qreal(0), - m_actualFocusPoint.x() - (focusSize.width() / 2), - 1.f - focusSize.width()); - float y = qBound(qreal(0), - m_actualFocusPoint.y() - (focusSize.height() / 2), - 1.f - focusSize.height()); - - QRectF area(QPointF(x, y), focusSize); - - m_focusZones.append(QCameraFocusZone(area, status)); - } - - emit focusZonesChanged(); -} - -void QAndroidCameraFocusControl::setCameraFocusArea() -{ - QList<QRect> areas; - if (m_focusPointMode != QCameraFocus::FocusPointAuto) { - // in FocusPointAuto mode, leave the area list empty - // to let the driver choose the focus point. - - for (int i = 0; i < m_focusZones.size(); ++i) - areas.append(adjustedArea(m_focusZones.at(i).area())); - - } - m_session->camera()->setFocusAreas(areas); -} - -void QAndroidCameraFocusControl::onViewportSizeChanged() -{ - QCameraFocusZone::FocusZoneStatus status = QCameraFocusZone::Selected; - if (!m_focusZones.isEmpty()) - status = m_focusZones.at(0).status(); - updateFocusZones(status); - setCameraFocusArea(); -} - -void QAndroidCameraFocusControl::onCameraCaptureModeChanged() -{ - if (m_session->camera() && m_focusMode == QCameraFocus::ContinuousFocus) { - QString focusMode; - if ((m_session->captureMode().testFlag(QCamera::CaptureVideo) && m_continuousVideoFocusSupported) - || !m_continuousPictureFocusSupported) { - focusMode = QLatin1String("continuous-video"); - } else { - focusMode = QLatin1String("continuous-picture"); - } - m_session->camera()->setFocusMode(focusMode); - m_session->camera()->cancelAutoFocus(); - } -} - -void QAndroidCameraFocusControl::onAutoFocusStarted() -{ - updateFocusZones(QCameraFocusZone::Selected); -} - -void QAndroidCameraFocusControl::onAutoFocusComplete(bool success) -{ - if (success) - updateFocusZones(QCameraFocusZone::Focused); -} - - -qreal QAndroidCameraFocusControl::maximumOpticalZoom() const -{ - // Optical zoom not supported - return 1.0; -} - -qreal QAndroidCameraFocusControl::maximumDigitalZoom() const -{ - return m_maximumZoom; -} - -qreal QAndroidCameraFocusControl::requestedOpticalZoom() const -{ - // Optical zoom not supported - return 1.0; -} - -qreal QAndroidCameraFocusControl::requestedDigitalZoom() const -{ - return m_requestedZoom; -} - -qreal QAndroidCameraFocusControl::currentOpticalZoom() const -{ - // Optical zoom not supported - return 1.0; -} - -qreal QAndroidCameraFocusControl::currentDigitalZoom() const -{ - return m_currentZoom; -} - -void QAndroidCameraFocusControl::zoomTo(qreal optical, qreal digital) -{ - Q_UNUSED(optical); - - if (!qFuzzyCompare(m_requestedZoom, digital)) { - m_requestedZoom = digital; - emit requestedDigitalZoomChanged(m_requestedZoom); - } - - if (m_session->camera()) { - digital = qBound(qreal(1), digital, m_maximumZoom); - int validZoomIndex = qt_findClosestValue(m_zoomRatios, qRound(digital * 100)); - qreal newZoom = m_zoomRatios.at(validZoomIndex) / qreal(100); - if (!qFuzzyCompare(m_currentZoom, newZoom)) { - m_session->camera()->setZoom(validZoomIndex); - m_currentZoom = newZoom; - emit currentDigitalZoomChanged(m_currentZoom); - } - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.h b/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.h deleted file mode 100644 index 13e560beb..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.h +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDCAMERAFOCUSCONTROL_H -#define QANDROIDCAMERAFOCUSCONTROL_H - -#include <qcamerafocuscontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCameraSession; - -class QAndroidCameraFocusControl : public QCameraFocusControl -{ - Q_OBJECT -public: - explicit QAndroidCameraFocusControl(QAndroidCameraSession *session); - - QCameraFocus::FocusModes focusMode() const override; - void setFocusMode(QCameraFocus::FocusModes mode) override; - bool isFocusModeSupported(QCameraFocus::FocusModes mode) const override; - QCameraFocus::FocusPointMode focusPointMode() const override; - void setFocusPointMode(QCameraFocus::FocusPointMode mode) override; - bool isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const override; - QPointF customFocusPoint() const override; - void setCustomFocusPoint(const QPointF &point) override; - QCameraFocusZoneList focusZones() const override; - - qreal maximumOpticalZoom() const override; - qreal maximumDigitalZoom() const override; - qreal requestedOpticalZoom() const override; - qreal requestedDigitalZoom() const override; - qreal currentOpticalZoom() const override; - qreal currentDigitalZoom() const override; - void zoomTo(qreal optical, qreal digital) override; - -private Q_SLOTS: - void onCameraOpened(); - void onViewportSizeChanged(); - void onCameraCaptureModeChanged(); - void onAutoFocusStarted(); - void onAutoFocusComplete(bool success); - -private: - inline void setFocusModeHelper(QCameraFocus::FocusModes mode) - { - if (m_focusMode != mode) { - m_focusMode = mode; - emit focusModeChanged(mode); - } - } - - inline void setFocusPointModeHelper(QCameraFocus::FocusPointMode mode) - { - if (m_focusPointMode != mode) { - m_focusPointMode = mode; - emit focusPointModeChanged(mode); - } - } - - void updateFocusZones(QCameraFocusZone::FocusZoneStatus status = QCameraFocusZone::Selected); - void setCameraFocusArea(); - - QAndroidCameraSession *m_session; - - QCameraFocus::FocusModes m_focusMode; - QCameraFocus::FocusPointMode m_focusPointMode; - QPointF m_actualFocusPoint; - QPointF m_customFocusPoint; - QCameraFocusZoneList m_focusZones; - - QList<QCameraFocus::FocusModes> m_supportedFocusModes; - bool m_continuousPictureFocusSupported; - bool m_continuousVideoFocusSupported; - - QList<QCameraFocus::FocusPointMode> m_supportedFocusPointModes; - - qreal m_maximumZoom; - QList<int> m_zoomRatios; - qreal m_requestedZoom; - qreal m_currentZoom; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDCAMERAFOCUSCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.cpp deleted file mode 100644 index 85169af23..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidcameraimagecapturecontrol.h" - -#include "qandroidcamerasession.h" - -QT_BEGIN_NAMESPACE - -QAndroidCameraImageCaptureControl::QAndroidCameraImageCaptureControl(QAndroidCameraSession *session) - : QCameraImageCaptureControl() - , m_session(session) -{ - connect(m_session, SIGNAL(readyForCaptureChanged(bool)), this, SIGNAL(readyForCaptureChanged(bool))); - connect(m_session, SIGNAL(imageExposed(int)), this, SIGNAL(imageExposed(int))); - connect(m_session, SIGNAL(imageCaptured(int,QImage)), this, SIGNAL(imageCaptured(int,QImage))); - connect(m_session, SIGNAL(imageMetadataAvailable(int,QString,QVariant)), this, SIGNAL(imageMetadataAvailable(int,QString,QVariant))); - connect(m_session, SIGNAL(imageAvailable(int,QVideoFrame)), this, SIGNAL(imageAvailable(int,QVideoFrame))); - connect(m_session, SIGNAL(imageSaved(int,QString)), this, SIGNAL(imageSaved(int,QString))); - connect(m_session, SIGNAL(imageCaptureError(int,int,QString)), this, SIGNAL(error(int,int,QString))); -} - -bool QAndroidCameraImageCaptureControl::isReadyForCapture() const -{ - return m_session->isReadyForCapture(); -} - -QCameraImageCapture::DriveMode QAndroidCameraImageCaptureControl::driveMode() const -{ - return m_session->driveMode(); -} - -void QAndroidCameraImageCaptureControl::setDriveMode(QCameraImageCapture::DriveMode mode) -{ - m_session->setDriveMode(mode); -} - -int QAndroidCameraImageCaptureControl::capture(const QString &fileName) -{ - return m_session->capture(fileName); -} - -void QAndroidCameraImageCaptureControl::cancelCapture() -{ - m_session->cancelCapture(); -} - -QCameraImageCapture::CaptureDestinations QAndroidCameraImageCaptureControl::captureDestination() const -{ - return m_session->captureDestination();; -} - -void QAndroidCameraImageCaptureControl::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) -{ - m_session->setCaptureDestination(destination); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.h b/src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.h deleted file mode 100644 index c0e496c7b..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDCAMERAIMAGECAPTURECONTROL_H -#define QANDROIDCAMERAIMAGECAPTURECONTROL_H - -#include <qcameraimagecapturecontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCameraSession; - -class QAndroidCameraImageCaptureControl : public QCameraImageCaptureControl -{ - Q_OBJECT -public: - explicit QAndroidCameraImageCaptureControl(QAndroidCameraSession *session); - - bool isReadyForCapture() const override; - - QCameraImageCapture::DriveMode driveMode() const override; - void setDriveMode(QCameraImageCapture::DriveMode mode) override; - - int capture(const QString &fileName) override; - void cancelCapture() override; - - QCameraImageCapture::CaptureDestinations captureDestination() const override; - void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) override; - -private: - QAndroidCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDCAMERAIMAGECAPTURECONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.cpp deleted file mode 100644 index c69f1946b..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidcameraimageprocessingcontrol.h" - -#include "qandroidcamerasession.h" -#include "androidcamera.h" - -QT_BEGIN_NAMESPACE - -QAndroidCameraImageProcessingControl::QAndroidCameraImageProcessingControl(QAndroidCameraSession *session) - : QCameraImageProcessingControl() - , m_session(session) - , m_whiteBalanceMode(QCameraImageProcessing::WhiteBalanceAuto) -{ - connect(m_session, SIGNAL(opened()), - this, SLOT(onCameraOpened())); -} - -bool QAndroidCameraImageProcessingControl::isParameterSupported(ProcessingParameter parameter) const -{ - return parameter == QCameraImageProcessingControl::WhiteBalancePreset - && m_session->camera() - && !m_supportedWhiteBalanceModes.isEmpty(); -} - -bool QAndroidCameraImageProcessingControl::isParameterValueSupported(ProcessingParameter parameter, - const QVariant &value) const -{ - return parameter == QCameraImageProcessingControl::WhiteBalancePreset - && m_session->camera() - && m_supportedWhiteBalanceModes.contains(value.value<QCameraImageProcessing::WhiteBalanceMode>()); -} - -QVariant QAndroidCameraImageProcessingControl::parameter(ProcessingParameter parameter) const -{ - if (parameter != QCameraImageProcessingControl::WhiteBalancePreset) - return QVariant(); - - return QVariant::fromValue(m_whiteBalanceMode); -} - -void QAndroidCameraImageProcessingControl::setParameter(ProcessingParameter parameter, const QVariant &value) -{ - if (parameter != QCameraImageProcessingControl::WhiteBalancePreset) - return; - - QCameraImageProcessing::WhiteBalanceMode mode = value.value<QCameraImageProcessing::WhiteBalanceMode>(); - - if (m_session->camera()) - setWhiteBalanceModeHelper(mode); - else - m_whiteBalanceMode = mode; -} - -void QAndroidCameraImageProcessingControl::setWhiteBalanceModeHelper(QCameraImageProcessing::WhiteBalanceMode mode) -{ - QString wb = m_supportedWhiteBalanceModes.value(mode, QString()); - if (!wb.isEmpty()) { - m_session->camera()->setWhiteBalance(wb); - m_whiteBalanceMode = mode; - } -} - -void QAndroidCameraImageProcessingControl::onCameraOpened() -{ - m_supportedWhiteBalanceModes.clear(); - QStringList whiteBalanceModes = m_session->camera()->getSupportedWhiteBalance(); - for (int i = 0; i < whiteBalanceModes.size(); ++i) { - const QString &wb = whiteBalanceModes.at(i); - if (wb == QLatin1String("auto")) { - m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceAuto, - QStringLiteral("auto")); - } else if (wb == QLatin1String("cloudy-daylight")) { - m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceCloudy, - QStringLiteral("cloudy-daylight")); - } else if (wb == QLatin1String("daylight")) { - m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceSunlight, - QStringLiteral("daylight")); - } else if (wb == QLatin1String("fluorescent")) { - m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceFluorescent, - QStringLiteral("fluorescent")); - } else if (wb == QLatin1String("incandescent")) { - m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceTungsten, - QStringLiteral("incandescent")); - } else if (wb == QLatin1String("shade")) { - m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceShade, - QStringLiteral("shade")); - } else if (wb == QLatin1String("twilight")) { - m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceSunset, - QStringLiteral("twilight")); - } else if (wb == QLatin1String("warm-fluorescent")) { - m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceFlash, - QStringLiteral("warm-fluorescent")); - } - } - - if (!m_supportedWhiteBalanceModes.contains(m_whiteBalanceMode)) - m_whiteBalanceMode = QCameraImageProcessing::WhiteBalanceAuto; - - setWhiteBalanceModeHelper(m_whiteBalanceMode); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.h b/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.h deleted file mode 100644 index 9845c80dc..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDCAMERAIMAGEPROCESSINGCONTROL_H -#define QANDROIDCAMERAIMAGEPROCESSINGCONTROL_H - -#include <qcameraimageprocessingcontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCameraSession; - -class QAndroidCameraImageProcessingControl : public QCameraImageProcessingControl -{ - Q_OBJECT -public: - explicit QAndroidCameraImageProcessingControl(QAndroidCameraSession *session); - - bool isParameterSupported(ProcessingParameter) const override; - bool isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const override; - QVariant parameter(ProcessingParameter parameter) const override; - void setParameter(ProcessingParameter parameter, const QVariant &value) override; - -private Q_SLOTS: - void onCameraOpened(); - -private: - void setWhiteBalanceModeHelper(QCameraImageProcessing::WhiteBalanceMode mode); - - QAndroidCameraSession *m_session; - - QCameraImageProcessing::WhiteBalanceMode m_whiteBalanceMode; - - QMap<QCameraImageProcessing::WhiteBalanceMode, QString> m_supportedWhiteBalanceModes; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDCAMERAIMAGEPROCESSINGCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp deleted file mode 100644 index 9e3c37736..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ /dev/null @@ -1,939 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Ruslan Baratov -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidcamerasession.h" - -#include "androidcamera.h" -#include "androidmultimediautils.h" -#include "qandroidvideooutput.h" -#include "qandroidmediavideoprobecontrol.h" -#include "qandroidmultimediautils.h" -#include "qandroidcameravideorenderercontrol.h" -#include <qabstractvideosurface.h> -#include <QtConcurrent/qtconcurrentrun.h> -#include <qfile.h> -#include <qguiapplication.h> -#include <qdebug.h> -#include <qvideoframe.h> -#include <private/qmemoryvideobuffer_p.h> -#include <QtCore/private/qjnihelpers_p.h> - -QT_BEGIN_NAMESPACE - -Q_GLOBAL_STATIC(QList<AndroidCameraInfo>, g_availableCameras) - -QAndroidCameraSession::QAndroidCameraSession(QObject *parent) - : QObject(parent) - , m_selectedCamera(0) - , m_camera(0) - , m_nativeOrientation(0) - , m_videoOutput(0) - , m_captureMode(QCamera::CaptureStillImage) - , m_state(QCamera::UnloadedState) - , m_savedState(-1) - , m_status(QCamera::UnloadedStatus) - , m_previewStarted(false) - , m_captureDestination(QCameraImageCapture::CaptureToFile) - , m_captureImageDriveMode(QCameraImageCapture::SingleImageCapture) - , m_lastImageCaptureId(0) - , m_readyForCapture(false) - , m_captureCanceled(false) - , m_currentImageCaptureId(-1) - , m_previewCallback(0) - , m_keepActive(false) -{ - m_mediaStorageLocation.addStorageLocation( - QMediaStorageLocation::Pictures, - AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::DCIM)); - - if (qApp) { - connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), - this, SLOT(onApplicationStateChanged(Qt::ApplicationState))); - } -} - -QAndroidCameraSession::~QAndroidCameraSession() -{ - close(); -} - -void QAndroidCameraSession::setCaptureMode(QCamera::CaptureModes mode) -{ - if (m_captureMode == mode || !isCaptureModeSupported(mode)) - return; - - m_captureMode = mode; - emit captureModeChanged(m_captureMode); - - if (m_previewStarted && m_captureMode.testFlag(QCamera::CaptureStillImage)) - applyViewfinderSettings(m_actualImageSettings.resolution()); -} - -bool QAndroidCameraSession::isCaptureModeSupported(QCamera::CaptureModes mode) const -{ - if (mode & (QCamera::CaptureStillImage & QCamera::CaptureVideo)) - return false; - - return true; -} - -void QAndroidCameraSession::setState(QCamera::State state) -{ - if (m_state == state) - return; - - m_state = state; - emit stateChanged(m_state); - - // If the application is inactive, the camera shouldn't be started. Save the desired state - // instead and it will be set when the application becomes active. - if (qApp->applicationState() == Qt::ApplicationActive) - setStateHelper(state); - else - m_savedState = state; -} - -void QAndroidCameraSession::setStateHelper(QCamera::State state) -{ - switch (state) { - case QCamera::UnloadedState: - close(); - break; - case QCamera::LoadedState: - case QCamera::ActiveState: - if (!m_camera && !open()) { - m_state = QCamera::UnloadedState; - emit stateChanged(m_state); - emit error(QCamera::CameraError, QStringLiteral("Failed to open camera")); - m_status = QCamera::UnloadedStatus; - emit statusChanged(m_status); - return; - } - if (state == QCamera::ActiveState) - startPreview(); - else if (state == QCamera::LoadedState) - stopPreview(); - break; - } -} - -void QAndroidCameraSession::updateAvailableCameras() -{ - g_availableCameras->clear(); - - const int numCameras = AndroidCamera::getNumberOfCameras(); - for (int i = 0; i < numCameras; ++i) { - AndroidCameraInfo info; - AndroidCamera::getCameraInfo(i, &info); - - if (!info.name.isNull()) - g_availableCameras->append(info); - } -} - -const QList<AndroidCameraInfo> &QAndroidCameraSession::availableCameras() -{ - if (g_availableCameras->isEmpty()) - updateAvailableCameras(); - - return *g_availableCameras; -} - -bool QAndroidCameraSession::open() -{ - close(); - - m_status = QCamera::LoadingStatus; - emit statusChanged(m_status); - - m_camera = AndroidCamera::open(m_selectedCamera); - - if (m_camera) { - connect(m_camera, SIGNAL(pictureExposed()), this, SLOT(onCameraPictureExposed())); - connect(m_camera, SIGNAL(lastPreviewFrameFetched(QVideoFrame)), - this, SLOT(onLastPreviewFrameFetched(QVideoFrame)), - Qt::DirectConnection); - connect(m_camera, SIGNAL(newPreviewFrame(QVideoFrame)), - this, SLOT(onNewPreviewFrame(QVideoFrame)), - Qt::DirectConnection); - connect(m_camera, SIGNAL(pictureCaptured(QByteArray)), this, SLOT(onCameraPictureCaptured(QByteArray))); - connect(m_camera, SIGNAL(previewStarted()), this, SLOT(onCameraPreviewStarted())); - connect(m_camera, SIGNAL(previewStopped()), this, SLOT(onCameraPreviewStopped())); - connect(m_camera, &AndroidCamera::previewFailedToStart, this, &QAndroidCameraSession::onCameraPreviewFailedToStart); - connect(m_camera, &AndroidCamera::takePictureFailed, this, &QAndroidCameraSession::onCameraTakePictureFailed); - - m_nativeOrientation = m_camera->getNativeOrientation(); - - m_status = QCamera::LoadedStatus; - - if (m_camera->getPreviewFormat() != AndroidCamera::NV21) - m_camera->setPreviewFormat(AndroidCamera::NV21); - - m_camera->notifyNewFrames(m_videoProbes.count() || m_previewCallback); - - emit opened(); - emit statusChanged(m_status); - } - - return m_camera != 0; -} - -void QAndroidCameraSession::close() -{ - if (!m_camera) - return; - - stopPreview(); - - m_status = QCamera::UnloadingStatus; - emit statusChanged(m_status); - - m_readyForCapture = false; - m_currentImageCaptureId = -1; - m_currentImageCaptureFileName.clear(); - m_actualImageSettings = m_requestedImageSettings; - m_actualViewfinderSettings = m_requestedViewfinderSettings; - - m_camera->release(); - delete m_camera; - m_camera = 0; - - m_status = QCamera::UnloadedStatus; - emit statusChanged(m_status); -} - -void QAndroidCameraSession::setVideoOutput(QAndroidVideoOutput *output) -{ - if (m_videoOutput) { - m_videoOutput->stop(); - m_videoOutput->reset(); - } - - if (output) { - m_videoOutput = output; - if (m_videoOutput->isReady()) - onVideoOutputReady(true); - else - connect(m_videoOutput, SIGNAL(readyChanged(bool)), this, SLOT(onVideoOutputReady(bool))); - } else { - m_videoOutput = 0; - } -} - -void QAndroidCameraSession::setViewfinderSettings(const QCameraViewfinderSettings &settings) -{ - if (m_requestedViewfinderSettings == settings) - return; - - m_requestedViewfinderSettings = m_actualViewfinderSettings = settings; - - if (m_readyForCapture) - applyViewfinderSettings(); -} - -void QAndroidCameraSession::applyViewfinderSettings(const QSize &captureSize, bool restartPreview) -{ - if (!m_camera) - return; - - const QSize currentViewfinderResolution = m_camera->previewSize(); - const AndroidCamera::ImageFormat currentPreviewFormat = m_camera->getPreviewFormat(); - const AndroidCamera::FpsRange currentFpsRange = m_camera->getPreviewFpsRange(); - - // -- adjust resolution - QSize adjustedViewfinderResolution; - const bool validCaptureSize = captureSize.width() > 0 && captureSize.height() > 0; - if (m_captureMode.testFlag(QCamera::CaptureVideo) - && validCaptureSize - && m_camera->getPreferredPreviewSizeForVideo().isEmpty()) { - // According to the Android doc, if getPreferredPreviewSizeForVideo() returns null, it means - // the preview size cannot be different from the capture size - adjustedViewfinderResolution = captureSize; - } else { - qreal captureAspectRatio = 0; - if (validCaptureSize) - captureAspectRatio = qreal(captureSize.width()) / qreal(captureSize.height()); - - const QList<QSize> previewSizes = m_camera->getSupportedPreviewSizes(); - - const QSize vfRes = m_requestedViewfinderSettings.resolution(); - if (vfRes.width() > 0 && vfRes.height() > 0 - && (!validCaptureSize || qAbs(captureAspectRatio - (qreal(vfRes.width()) / vfRes.height())) < 0.01) - && previewSizes.contains(vfRes)) { - adjustedViewfinderResolution = vfRes; - } else if (validCaptureSize) { - // search for viewfinder resolution with the same aspect ratio - qreal minAspectDiff = 1; - QSize closestResolution; - for (int i = previewSizes.count() - 1; i >= 0; --i) { - const QSize &size = previewSizes.at(i); - const qreal sizeAspect = qreal(size.width()) / size.height(); - if (qFuzzyCompare(captureAspectRatio, sizeAspect)) { - adjustedViewfinderResolution = size; - break; - } else if (minAspectDiff > qAbs(sizeAspect - captureAspectRatio)) { - closestResolution = size; - minAspectDiff = qAbs(sizeAspect - captureAspectRatio); - } - } - if (!adjustedViewfinderResolution.isValid()) { - qWarning("Cannot find a viewfinder resolution matching the capture aspect ratio."); - if (closestResolution.isValid()) { - adjustedViewfinderResolution = closestResolution; - qWarning("Using closest viewfinder resolution."); - } else { - return; - } - } - } else { - adjustedViewfinderResolution = previewSizes.last(); - } - } - m_actualViewfinderSettings.setResolution(adjustedViewfinderResolution); - - // -- adjust pixel format - - AndroidCamera::ImageFormat adjustedPreviewFormat = AndroidCamera::NV21; - if (m_requestedViewfinderSettings.pixelFormat() != QVideoFrame::Format_Invalid) { - const AndroidCamera::ImageFormat f = AndroidImageFormatFromQtPixelFormat(m_requestedViewfinderSettings.pixelFormat()); - if (f == AndroidCamera::UnknownImageFormat || !m_camera->getSupportedPreviewFormats().contains(f)) - qWarning("Unsupported viewfinder pixel format"); - else - adjustedPreviewFormat = f; - } - m_actualViewfinderSettings.setPixelFormat(QtPixelFormatFromAndroidImageFormat(adjustedPreviewFormat)); - - // -- adjust FPS - - AndroidCamera::FpsRange adjustedFps = currentFpsRange; - const AndroidCamera::FpsRange requestedFpsRange = AndroidCamera::FpsRange::makeFromQReal(m_requestedViewfinderSettings.minimumFrameRate(), - m_requestedViewfinderSettings.maximumFrameRate()); - if (requestedFpsRange.min > 0 || requestedFpsRange.max > 0) { - int minDist = INT_MAX; - const QList<AndroidCamera::FpsRange> supportedFpsRanges = m_camera->getSupportedPreviewFpsRange(); - auto it = supportedFpsRanges.rbegin(), end = supportedFpsRanges.rend(); - for (; it != end; ++it) { - int dist = (requestedFpsRange.min > 0 ? qAbs(requestedFpsRange.min - it->min) : 0) - + (requestedFpsRange.max > 0 ? qAbs(requestedFpsRange.max - it->max) : 0); - if (dist < minDist) { - minDist = dist; - adjustedFps = *it; - if (minDist == 0) - break; // exact match - } - } - } - m_actualViewfinderSettings.setMinimumFrameRate(adjustedFps.getMinReal()); - m_actualViewfinderSettings.setMaximumFrameRate(adjustedFps.getMaxReal()); - - // -- Set values on camera - - if (currentViewfinderResolution != adjustedViewfinderResolution - || currentPreviewFormat != adjustedPreviewFormat - || currentFpsRange.min != adjustedFps.min - || currentFpsRange.max != adjustedFps.max) { - - if (m_videoOutput) - m_videoOutput->setVideoSize(adjustedViewfinderResolution); - - // if preview is started, we have to stop it first before changing its size - if (m_previewStarted && restartPreview) - m_camera->stopPreview(); - - m_camera->setPreviewSize(adjustedViewfinderResolution); - m_camera->setPreviewFormat(adjustedPreviewFormat); - m_camera->setPreviewFpsRange(adjustedFps); - - // restart preview - if (m_previewStarted && restartPreview) - m_camera->startPreview(); - } -} - -QList<QSize> QAndroidCameraSession::getSupportedPreviewSizes() const -{ - return m_camera ? m_camera->getSupportedPreviewSizes() : QList<QSize>(); -} - -QList<QVideoFrame::PixelFormat> QAndroidCameraSession::getSupportedPixelFormats() const -{ - QList<QVideoFrame::PixelFormat> formats; - - if (!m_camera) - return formats; - - const QList<AndroidCamera::ImageFormat> nativeFormats = m_camera->getSupportedPreviewFormats(); - - formats.reserve(nativeFormats.size()); - - for (AndroidCamera::ImageFormat nativeFormat : nativeFormats) { - QVideoFrame::PixelFormat format = QtPixelFormatFromAndroidImageFormat(nativeFormat); - if (format != QVideoFrame::Format_Invalid) - formats.append(format); - } - - return formats; -} - -QList<AndroidCamera::FpsRange> QAndroidCameraSession::getSupportedPreviewFpsRange() const -{ - return m_camera ? m_camera->getSupportedPreviewFpsRange() : QList<AndroidCamera::FpsRange>(); -} - -struct NullSurface : QAbstractVideoSurface -{ - NullSurface(QObject *parent = nullptr) : QAbstractVideoSurface(parent) { } - QList<QVideoFrame::PixelFormat> supportedPixelFormats( - QAbstractVideoBuffer::HandleType type = QAbstractVideoBuffer::NoHandle) const override - { - QList<QVideoFrame::PixelFormat> result; - if (type == QAbstractVideoBuffer::NoHandle) - result << QVideoFrame::Format_NV21; - - return result; - } - - bool present(const QVideoFrame &) { return false; } -}; - -bool QAndroidCameraSession::startPreview() -{ - if (!m_camera) - return false; - - if (m_previewStarted) - return true; - - if (m_videoOutput) { - if (!m_videoOutput->isReady()) - return true; // delay starting until the video output is ready - - Q_ASSERT(m_videoOutput->surfaceTexture() || m_videoOutput->surfaceHolder()); - - if ((m_videoOutput->surfaceTexture() && !m_camera->setPreviewTexture(m_videoOutput->surfaceTexture())) - || (m_videoOutput->surfaceHolder() && !m_camera->setPreviewDisplay(m_videoOutput->surfaceHolder()))) - return false; - } else { - auto control = new QAndroidCameraVideoRendererControl(this, this); - control->setSurface(new NullSurface(this)); - qWarning() << "Starting camera without viewfinder available"; - - return true; - } - - m_status = QCamera::StartingStatus; - emit statusChanged(m_status); - - applyImageSettings(); - applyViewfinderSettings(m_captureMode.testFlag(QCamera::CaptureStillImage) ? m_actualImageSettings.resolution() - : QSize()); - - AndroidMultimediaUtils::enableOrientationListener(true); - - // Before API level 24 the orientation was always 0, which is what we're expecting, so - // we'll enforce that here. - if (QtAndroidPrivate::androidSdkVersion() > 23) - m_camera->setDisplayOrientation(0); - - m_camera->startPreview(); - m_previewStarted = true; - - return true; -} - -void QAndroidCameraSession::stopPreview() -{ - if (!m_camera || !m_previewStarted) - return; - - m_status = QCamera::StoppingStatus; - emit statusChanged(m_status); - - AndroidMultimediaUtils::enableOrientationListener(false); - - m_camera->stopPreview(); - m_camera->setPreviewSize(QSize()); - m_camera->setPreviewTexture(0); - m_camera->setPreviewDisplay(0); - - if (m_videoOutput) { - m_videoOutput->stop(); - m_videoOutput->reset(); - } - m_previewStarted = false; -} - -void QAndroidCameraSession::setImageSettings(const QImageEncoderSettings &settings) -{ - if (m_requestedImageSettings == settings) - return; - - m_requestedImageSettings = m_actualImageSettings = settings; - - applyImageSettings(); - - if (m_readyForCapture && m_captureMode.testFlag(QCamera::CaptureStillImage)) - applyViewfinderSettings(m_actualImageSettings.resolution()); -} - -int QAndroidCameraSession::currentCameraRotation() const -{ - if (!m_camera) - return 0; - - // subtract natural camera orientation and physical device orientation - int rotation = 0; - int deviceOrientation = (AndroidMultimediaUtils::getDeviceOrientation() + 45) / 90 * 90; - if (m_camera->getFacing() == AndroidCamera::CameraFacingFront) - rotation = (m_nativeOrientation - deviceOrientation + 360) % 360; - else // back-facing camera - rotation = (m_nativeOrientation + deviceOrientation) % 360; - - return rotation; -} - -void QAndroidCameraSession::addProbe(QAndroidMediaVideoProbeControl *probe) -{ - m_videoProbesMutex.lock(); - if (probe) - m_videoProbes << probe; - if (m_camera) - m_camera->notifyNewFrames(m_videoProbes.count() || m_previewCallback); - m_videoProbesMutex.unlock(); -} - -void QAndroidCameraSession::removeProbe(QAndroidMediaVideoProbeControl *probe) -{ - m_videoProbesMutex.lock(); - m_videoProbes.remove(probe); - if (m_camera) - m_camera->notifyNewFrames(m_videoProbes.count() || m_previewCallback); - m_videoProbesMutex.unlock(); -} - -void QAndroidCameraSession::setPreviewFormat(AndroidCamera::ImageFormat format) -{ - if (format == AndroidCamera::UnknownImageFormat) - return; - - m_camera->setPreviewFormat(format); -} - -void QAndroidCameraSession::setPreviewCallback(PreviewCallback *callback) -{ - m_videoProbesMutex.lock(); - m_previewCallback = callback; - if (m_camera) - m_camera->notifyNewFrames(m_videoProbes.count() || m_previewCallback); - m_videoProbesMutex.unlock(); -} - -void QAndroidCameraSession::applyImageSettings() -{ - if (!m_camera) - return; - - if (m_actualImageSettings.codec().isEmpty()) - m_actualImageSettings.setCodec(QLatin1String("jpeg")); - - const QSize requestedResolution = m_requestedImageSettings.resolution(); - const QList<QSize> supportedResolutions = m_camera->getSupportedPictureSizes(); - if (!requestedResolution.isValid()) { - // if the viewfinder resolution is explicitly set, pick the highest available capture - // resolution with the same aspect ratio - if (m_requestedViewfinderSettings.resolution().isValid()) { - const QSize vfResolution = m_actualViewfinderSettings.resolution(); - const qreal vfAspectRatio = qreal(vfResolution.width()) / vfResolution.height(); - - auto it = supportedResolutions.rbegin(), end = supportedResolutions.rend(); - for (; it != end; ++it) { - if (qAbs(vfAspectRatio - (qreal(it->width()) / it->height())) < 0.01) { - m_actualImageSettings.setResolution(*it); - break; - } - } - } else { - // otherwise, use the highest supported one - m_actualImageSettings.setResolution(supportedResolutions.last()); - } - } else if (!supportedResolutions.contains(requestedResolution)) { - // if the requested resolution is not supported, find the closest one - int reqPixelCount = requestedResolution.width() * requestedResolution.height(); - QList<int> supportedPixelCounts; - for (int i = 0; i < supportedResolutions.size(); ++i) { - const QSize &s = supportedResolutions.at(i); - supportedPixelCounts.append(s.width() * s.height()); - } - int closestIndex = qt_findClosestValue(supportedPixelCounts, reqPixelCount); - m_actualImageSettings.setResolution(supportedResolutions.at(closestIndex)); - } - m_camera->setPictureSize(m_actualImageSettings.resolution()); - - int jpegQuality = 100; - switch (m_requestedImageSettings.quality()) { - case QMultimedia::VeryLowQuality: - jpegQuality = 20; - break; - case QMultimedia::LowQuality: - jpegQuality = 40; - break; - case QMultimedia::NormalQuality: - jpegQuality = 60; - break; - case QMultimedia::HighQuality: - jpegQuality = 80; - break; - case QMultimedia::VeryHighQuality: - jpegQuality = 100; - break; - } - m_camera->setJpegQuality(jpegQuality); -} - -bool QAndroidCameraSession::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const -{ - return destination & (QCameraImageCapture::CaptureToFile | QCameraImageCapture::CaptureToBuffer); -} - -QCameraImageCapture::CaptureDestinations QAndroidCameraSession::captureDestination() const -{ - return m_captureDestination; -} - -void QAndroidCameraSession::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) -{ - m_captureDestination = destination; -} - -bool QAndroidCameraSession::isReadyForCapture() const -{ - return m_status == QCamera::ActiveStatus && m_readyForCapture; -} - -void QAndroidCameraSession::setReadyForCapture(bool ready) -{ - if (m_readyForCapture == ready) - return; - - m_readyForCapture = ready; - emit readyForCaptureChanged(ready); -} - -QCameraImageCapture::DriveMode QAndroidCameraSession::driveMode() const -{ - return m_captureImageDriveMode; -} - -void QAndroidCameraSession::setDriveMode(QCameraImageCapture::DriveMode mode) -{ - m_captureImageDriveMode = mode; -} - -int QAndroidCameraSession::capture(const QString &fileName) -{ - ++m_lastImageCaptureId; - - if (!isReadyForCapture()) { - emit imageCaptureError(m_lastImageCaptureId, QCameraImageCapture::NotReadyError, - tr("Camera not ready")); - return m_lastImageCaptureId; - } - - if (m_captureImageDriveMode == QCameraImageCapture::SingleImageCapture) { - setReadyForCapture(false); - - m_currentImageCaptureId = m_lastImageCaptureId; - m_currentImageCaptureFileName = fileName; - - applyImageSettings(); - applyViewfinderSettings(m_actualImageSettings.resolution()); - - // adjust picture rotation depending on the device orientation - m_camera->setRotation(currentCameraRotation()); - - m_camera->takePicture(); - } else { - //: Drive mode is the camera's shutter mode, for example single shot, continuos exposure, etc. - emit imageCaptureError(m_lastImageCaptureId, QCameraImageCapture::NotSupportedFeatureError, - tr("Drive mode not supported")); - } - - return m_lastImageCaptureId; -} - -void QAndroidCameraSession::cancelCapture() -{ - if (m_readyForCapture) - return; - - m_captureCanceled = true; -} - -void QAndroidCameraSession::onCameraTakePictureFailed() -{ - emit imageCaptureError(m_currentImageCaptureId, QCameraImageCapture::ResourceError, - tr("Failed to capture image")); - - // Preview needs to be restarted and the preview call back must be setup again - m_camera->startPreview(); -} - -void QAndroidCameraSession::onCameraPictureExposed() -{ - if (m_captureCanceled || !m_camera) - return; - - emit imageExposed(m_currentImageCaptureId); - m_camera->fetchLastPreviewFrame(); -} - -void QAndroidCameraSession::onLastPreviewFrameFetched(const QVideoFrame &frame) -{ - if (m_captureCanceled || !m_camera) - return; - - QtConcurrent::run(&QAndroidCameraSession::processPreviewImage, this, - m_currentImageCaptureId, - frame, - m_camera->getRotation()); -} - -void QAndroidCameraSession::processPreviewImage(int id, const QVideoFrame &frame, int rotation) -{ - // Preview display of front-facing cameras is flipped horizontally, but the frame data - // we get here is not. Flip it ourselves if the camera is front-facing to match what the user - // sees on the viewfinder. - QTransform transform; - if (m_camera->getFacing() == AndroidCamera::CameraFacingFront) - transform.scale(-1, 1); - transform.rotate(rotation); - - emit imageCaptured(id, frame.image().transformed(transform)); -} - -void QAndroidCameraSession::onNewPreviewFrame(const QVideoFrame &frame) -{ - if (!m_camera) - return; - - m_videoProbesMutex.lock(); - - for (QAndroidMediaVideoProbeControl *probe : qAsConst(m_videoProbes)) - probe->newFrameProbed(frame); - - if (m_previewCallback) - m_previewCallback->onFrameAvailable(frame); - - m_videoProbesMutex.unlock(); -} - -void QAndroidCameraSession::onCameraPictureCaptured(const QByteArray &data) -{ - if (!m_captureCanceled) { - // Loading and saving the captured image can be slow, do it in a separate thread - QtConcurrent::run(&QAndroidCameraSession::processCapturedImage, this, - m_currentImageCaptureId, - data, - m_actualImageSettings.resolution(), - m_captureDestination, - m_currentImageCaptureFileName); - } - - m_captureCanceled = false; - - // Preview needs to be restarted after taking a picture - if (m_camera) - m_camera->startPreview(); -} - -void QAndroidCameraSession::onCameraPreviewStarted() -{ - if (m_status == QCamera::StartingStatus) { - m_status = QCamera::ActiveStatus; - emit statusChanged(m_status); - } - - setReadyForCapture(true); -} - -void QAndroidCameraSession::onCameraPreviewFailedToStart() -{ - if (m_status == QCamera::StartingStatus) { - Q_EMIT error(QCamera::CameraError, tr("Camera preview failed to start.")); - - AndroidMultimediaUtils::enableOrientationListener(false); - m_camera->setPreviewSize(QSize()); - m_camera->setPreviewTexture(0); - if (m_videoOutput) { - m_videoOutput->stop(); - m_videoOutput->reset(); - } - m_previewStarted = false; - - m_status = QCamera::LoadedStatus; - emit statusChanged(m_status); - - setReadyForCapture(false); - } -} - -void QAndroidCameraSession::onCameraPreviewStopped() -{ - if (m_status == QCamera::StoppingStatus) { - m_status = QCamera::LoadedStatus; - emit statusChanged(m_status); - } - - setReadyForCapture(false); -} - -void QAndroidCameraSession::processCapturedImage(int id, - const QByteArray &data, - const QSize &resolution, - QCameraImageCapture::CaptureDestinations dest, - const QString &fileName) -{ - - - if (dest & QCameraImageCapture::CaptureToFile) { - const QString actualFileName = m_mediaStorageLocation.generateFileName(fileName, - QMediaStorageLocation::Pictures, - QLatin1String("IMG_"), - QLatin1String("jpg")); - - QFile file(actualFileName); - if (file.open(QFile::WriteOnly)) { - if (file.write(data) == data.size()) { - // if the picture is saved into the standard picture location, register it - // with the Android media scanner so it appears immediately in apps - // such as the gallery. - QString standardLoc = AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::DCIM); - if (actualFileName.startsWith(standardLoc)) - AndroidMultimediaUtils::registerMediaFile(actualFileName); - - emit imageSaved(id, actualFileName); - } else { - emit imageCaptureError(id, QCameraImageCapture::OutOfSpaceError, file.errorString()); - } - } else { - const QString errorMessage = tr("Could not open destination file: %1").arg(actualFileName); - emit imageCaptureError(id, QCameraImageCapture::ResourceError, errorMessage); - } - } - - if (dest & QCameraImageCapture::CaptureToBuffer) { - QVideoFrame frame(new QMemoryVideoBuffer(data, -1), resolution, QVideoFrame::Format_Jpeg); - emit imageAvailable(id, frame); - } -} - -QVideoFrame::PixelFormat QAndroidCameraSession::QtPixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat format) -{ - switch (format) { - case AndroidCamera::RGB565: - return QVideoFrame::Format_RGB565; - case AndroidCamera::NV21: - return QVideoFrame::Format_NV21; - case AndroidCamera::YUY2: - return QVideoFrame::Format_YUYV; - case AndroidCamera::JPEG: - return QVideoFrame::Format_Jpeg; - case AndroidCamera::YV12: - return QVideoFrame::Format_YV12; - default: - return QVideoFrame::Format_Invalid; - } -} - -AndroidCamera::ImageFormat QAndroidCameraSession::AndroidImageFormatFromQtPixelFormat(QVideoFrame::PixelFormat format) -{ - switch (format) { - case QVideoFrame::Format_RGB565: - return AndroidCamera::RGB565; - case QVideoFrame::Format_NV21: - return AndroidCamera::NV21; - case QVideoFrame::Format_YUYV: - return AndroidCamera::YUY2; - case QVideoFrame::Format_Jpeg: - return AndroidCamera::JPEG; - case QVideoFrame::Format_YV12: - return AndroidCamera::YV12; - default: - return AndroidCamera::UnknownImageFormat; - } -} - -void QAndroidCameraSession::onVideoOutputReady(bool ready) -{ - if (ready && m_state == QCamera::ActiveState) - startPreview(); -} - -void QAndroidCameraSession::onApplicationStateChanged(Qt::ApplicationState state) -{ - switch (state) { - case Qt::ApplicationInactive: - if (!m_keepActive && m_state != QCamera::UnloadedState) { - m_savedState = m_state; - close(); - m_state = QCamera::UnloadedState; - emit stateChanged(m_state); - } - break; - case Qt::ApplicationActive: - if (m_savedState != -1) { - setStateHelper(QCamera::State(m_savedState)); - m_savedState = -1; - } - break; - default: - break; - } -} - -bool QAndroidCameraSession::requestRecordingPermission() -{ - m_keepActive = true; - const bool result = qt_androidRequestRecordingPermission(); - m_keepActive = false; - return result; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.h b/src/plugins/android/src/mediacapture/qandroidcamerasession.h deleted file mode 100644 index 728dc484e..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.h +++ /dev/null @@ -1,205 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Ruslan Baratov -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDCAMERASESSION_H -#define QANDROIDCAMERASESSION_H - -#include <qcamera.h> -#include <qmediaencodersettings.h> -#include <QCameraImageCapture> -#include <QSet> -#include <QMutex> -#include <private/qmediastoragelocation_p.h> -#include "androidcamera.h" - -QT_BEGIN_NAMESPACE - -class QAndroidVideoOutput; -class QAndroidMediaVideoProbeControl; - -class QAndroidCameraSession : public QObject -{ - Q_OBJECT -public: - explicit QAndroidCameraSession(QObject *parent = 0); - ~QAndroidCameraSession(); - - static const QList<AndroidCameraInfo> &availableCameras(); - - void setSelectedCamera(int cameraId) { m_selectedCamera = cameraId; } - AndroidCamera *camera() const { return m_camera; } - - QCamera::State state() const { return m_state; } - void setState(QCamera::State state); - - QCamera::Status status() const { return m_status; } - - QCamera::CaptureModes captureMode() const { return m_captureMode; } - void setCaptureMode(QCamera::CaptureModes mode); - bool isCaptureModeSupported(QCamera::CaptureModes mode) const; - - QCameraViewfinderSettings viewfinderSettings() const { return m_actualViewfinderSettings; } - void setViewfinderSettings(const QCameraViewfinderSettings &settings); - void applyViewfinderSettings(const QSize &captureSize = QSize(), bool restartPreview = true); - - QAndroidVideoOutput *videoOutput() const { return m_videoOutput; } - void setVideoOutput(QAndroidVideoOutput *output); - - QList<QSize> getSupportedPreviewSizes() const; - QList<QVideoFrame::PixelFormat> getSupportedPixelFormats() const; - QList<AndroidCamera::FpsRange> getSupportedPreviewFpsRange() const; - - QImageEncoderSettings imageSettings() const { return m_actualImageSettings; } - void setImageSettings(const QImageEncoderSettings &settings); - - bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const; - QCameraImageCapture::CaptureDestinations captureDestination() const; - void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination); - - bool isReadyForCapture() const; - void setReadyForCapture(bool ready); - QCameraImageCapture::DriveMode driveMode() const; - void setDriveMode(QCameraImageCapture::DriveMode mode); - int capture(const QString &fileName); - void cancelCapture(); - - int currentCameraRotation() const; - - void addProbe(QAndroidMediaVideoProbeControl *probe); - void removeProbe(QAndroidMediaVideoProbeControl *probe); - - void setPreviewFormat(AndroidCamera::ImageFormat format); - - struct PreviewCallback - { - virtual void onFrameAvailable(const QVideoFrame &frame) = 0; - }; - void setPreviewCallback(PreviewCallback *callback); - bool requestRecordingPermission(); - -Q_SIGNALS: - void statusChanged(QCamera::Status status); - void stateChanged(QCamera::State); - void error(int error, const QString &errorString); - void captureModeChanged(QCamera::CaptureModes); - void opened(); - - void captureDestinationChanged(QCameraImageCapture::CaptureDestinations destination); - - void readyForCaptureChanged(bool); - void imageExposed(int id); - void imageCaptured(int id, const QImage &preview); - void imageMetadataAvailable(int id, const QString &key, const QVariant &value); - void imageAvailable(int id, const QVideoFrame &buffer); - void imageSaved(int id, const QString &fileName); - void imageCaptureError(int id, int error, const QString &errorString); - -private Q_SLOTS: - void onVideoOutputReady(bool ready); - - void onApplicationStateChanged(Qt::ApplicationState state); - - void onCameraTakePictureFailed(); - void onCameraPictureExposed(); - void onCameraPictureCaptured(const QByteArray &data); - void onLastPreviewFrameFetched(const QVideoFrame &frame); - void onNewPreviewFrame(const QVideoFrame &frame); - void onCameraPreviewStarted(); - void onCameraPreviewFailedToStart(); - void onCameraPreviewStopped(); - -private: - static void updateAvailableCameras(); - - bool open(); - void close(); - - bool startPreview(); - void stopPreview(); - - void applyImageSettings(); - - void processPreviewImage(int id, const QVideoFrame &frame, int rotation); - void processCapturedImage(int id, - const QByteArray &data, - const QSize &resolution, - QCameraImageCapture::CaptureDestinations dest, - const QString &fileName); - - static QVideoFrame::PixelFormat QtPixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat); - static AndroidCamera::ImageFormat AndroidImageFormatFromQtPixelFormat(QVideoFrame::PixelFormat); - - void setStateHelper(QCamera::State state); - - int m_selectedCamera; - AndroidCamera *m_camera; - int m_nativeOrientation; - QAndroidVideoOutput *m_videoOutput; - - QCamera::CaptureModes m_captureMode; - QCamera::State m_state; - int m_savedState; - QCamera::Status m_status; - bool m_previewStarted; - - QCameraViewfinderSettings m_requestedViewfinderSettings; - QCameraViewfinderSettings m_actualViewfinderSettings; - - QImageEncoderSettings m_requestedImageSettings; - QImageEncoderSettings m_actualImageSettings; - QCameraImageCapture::CaptureDestinations m_captureDestination; - QCameraImageCapture::DriveMode m_captureImageDriveMode; - int m_lastImageCaptureId; - bool m_readyForCapture; - bool m_captureCanceled; - int m_currentImageCaptureId; - QString m_currentImageCaptureFileName; - - QMediaStorageLocation m_mediaStorageLocation; - - QSet<QAndroidMediaVideoProbeControl *> m_videoProbes; - QMutex m_videoProbesMutex; - PreviewCallback *m_previewCallback; - bool m_keepActive; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDCAMERASESSION_H diff --git a/src/plugins/android/src/mediacapture/qandroidcameravideorenderercontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameravideorenderercontrol.cpp deleted file mode 100644 index 2243df732..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcameravideorenderercontrol.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidcameravideorenderercontrol.h" - -#include "qandroidcamerasession.h" -#include "qandroidvideooutput.h" -#include "androidsurfaceview.h" -#include "qandroidmultimediautils.h" -#include <qabstractvideosurface.h> -#include <qvideosurfaceformat.h> -#include <qcoreapplication.h> -#include <qthread.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCameraDataVideoOutput : public QAndroidVideoOutput - , public QAndroidCameraSession::PreviewCallback -{ - Q_OBJECT -public: - explicit QAndroidCameraDataVideoOutput(QAndroidCameraVideoRendererControl *control); - ~QAndroidCameraDataVideoOutput() override; - - AndroidSurfaceHolder *surfaceHolder() override; - - bool isReady() override; - - void stop() override; - -private Q_SLOTS: - void onSurfaceCreated(); - void configureFormat(); - -private: - void onFrameAvailable(const QVideoFrame &frame); - void presentFrame(); - bool event(QEvent *); - - QAndroidCameraVideoRendererControl *m_control; - AndroidSurfaceView *m_surfaceView; - QMutex m_mutex; - QVideoFrame::PixelFormat m_pixelFormat; - QVideoFrame m_lastFrame; -}; - -QAndroidCameraDataVideoOutput::QAndroidCameraDataVideoOutput(QAndroidCameraVideoRendererControl *control) - : QAndroidVideoOutput(control) - , m_control(control) - , m_pixelFormat(QVideoFrame::Format_Invalid) -{ - // The camera preview cannot be started unless we set a SurfaceTexture or a - // SurfaceHolder. In this case we don't actually care about either of these, but since - // we need to, we setup an offscreen dummy SurfaceView in order to be able to start - // the camera preview. We'll then be able to use setPreviewCallbackWithBuffer() to - // get the raw data. - - m_surfaceView = new AndroidSurfaceView; - - connect(m_surfaceView, &AndroidSurfaceView::surfaceCreated, - this, &QAndroidCameraDataVideoOutput::onSurfaceCreated); - - m_surfaceView->setGeometry(-1, -1, 1, 1); - m_surfaceView->setVisible(true); - - connect(m_control->cameraSession(), &QAndroidCameraSession::opened, - this, &QAndroidCameraDataVideoOutput::configureFormat); - connect(m_control->surface(), &QAbstractVideoSurface::supportedFormatsChanged, - this, &QAndroidCameraDataVideoOutput::configureFormat); - configureFormat(); -} - -QAndroidCameraDataVideoOutput::~QAndroidCameraDataVideoOutput() -{ - m_control->cameraSession()->setPreviewCallback(nullptr); - delete m_surfaceView; -} - -AndroidSurfaceHolder *QAndroidCameraDataVideoOutput::surfaceHolder() -{ - return m_surfaceView->holder(); -} - -bool QAndroidCameraDataVideoOutput::isReady() -{ - return m_surfaceView->holder() && m_surfaceView->holder()->isSurfaceCreated(); -} - -void QAndroidCameraDataVideoOutput::onSurfaceCreated() -{ - emit readyChanged(true); -} - -void QAndroidCameraDataVideoOutput::configureFormat() -{ - m_pixelFormat = QVideoFrame::Format_Invalid; - - if (!m_control->cameraSession()->camera()) - return; - - QList<QVideoFrame::PixelFormat> surfaceFormats = m_control->surface()->supportedPixelFormats(); - QList<AndroidCamera::ImageFormat> previewFormats = m_control->cameraSession()->camera()->getSupportedPreviewFormats(); - for (int i = 0; i < surfaceFormats.size(); ++i) { - QVideoFrame::PixelFormat pixFormat = surfaceFormats.at(i); - AndroidCamera::ImageFormat f = qt_androidImageFormatFromPixelFormat(pixFormat); - if (previewFormats.contains(f)) { - m_pixelFormat = pixFormat; - break; - } - } - - if (m_pixelFormat == QVideoFrame::Format_Invalid) { - m_control->cameraSession()->setPreviewCallback(nullptr); - qWarning("The video surface is not compatible with any format supported by the camera"); - } else { - m_control->cameraSession()->setPreviewCallback(this); - - if (m_control->cameraSession()->status() > QCamera::LoadedStatus) - m_control->cameraSession()->camera()->stopPreview(); - - m_control->cameraSession()->setPreviewFormat(qt_androidImageFormatFromPixelFormat(m_pixelFormat)); - - if (m_control->cameraSession()->status() > QCamera::LoadedStatus) - m_control->cameraSession()->camera()->startPreview(); - } -} - -void QAndroidCameraDataVideoOutput::stop() -{ - m_mutex.lock(); - m_lastFrame = QVideoFrame(); - m_mutex.unlock(); - - if (m_control->surface() && m_control->surface()->isActive()) - m_control->surface()->stop(); -} - -void QAndroidCameraDataVideoOutput::onFrameAvailable(const QVideoFrame &frame) -{ - m_mutex.lock(); - m_lastFrame = frame; - m_mutex.unlock(); - - if (thread() == QThread::currentThread()) - presentFrame(); - else - QCoreApplication::postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority); -} - -bool QAndroidCameraDataVideoOutput::event(QEvent *e) -{ - if (e->type() == QEvent::User) { - presentFrame(); - return true; - } - - return QObject::event(e); -} - -void QAndroidCameraDataVideoOutput::presentFrame() -{ - Q_ASSERT(thread() == QThread::currentThread()); - - QMutexLocker locker(&m_mutex); - - if (m_control->surface() && m_lastFrame.isValid() && m_lastFrame.pixelFormat() == m_pixelFormat) { - - if (m_control->surface()->isActive() && (m_control->surface()->surfaceFormat().pixelFormat() != m_lastFrame.pixelFormat() - || m_control->surface()->surfaceFormat().frameSize() != m_lastFrame.size())) { - m_control->surface()->stop(); - } - - if (!m_control->surface()->isActive()) { - QVideoSurfaceFormat format(m_lastFrame.size(), m_lastFrame.pixelFormat(), m_lastFrame.handleType()); - // Front camera frames are automatically mirrored when using SurfaceTexture or SurfaceView, - // but the buffers we get from the data callback are not. Tell the QAbstractVideoSurface - // that it needs to mirror the frames. - if (m_control->cameraSession()->camera()->getFacing() == AndroidCamera::CameraFacingFront) - format.setProperty("mirrored", true); - - m_control->surface()->start(format); - } - - if (m_control->surface()->isActive()) - m_control->surface()->present(m_lastFrame); - } - - m_lastFrame = QVideoFrame(); -} - - -QAndroidCameraVideoRendererControl::QAndroidCameraVideoRendererControl(QAndroidCameraSession *session, QObject *parent) - : QVideoRendererControl(parent) - , m_cameraSession(session) - , m_surface(0) - , m_textureOutput(0) - , m_dataOutput(0) -{ -} - -QAndroidCameraVideoRendererControl::~QAndroidCameraVideoRendererControl() -{ - m_cameraSession->setVideoOutput(0); -} - -QAbstractVideoSurface *QAndroidCameraVideoRendererControl::surface() const -{ - return m_surface; -} - -void QAndroidCameraVideoRendererControl::setSurface(QAbstractVideoSurface *surface) -{ - if (m_surface == surface) - return; - - m_surface = surface; - QAndroidVideoOutput *oldOutput = m_textureOutput ? static_cast<QAndroidVideoOutput*>(m_textureOutput) - : static_cast<QAndroidVideoOutput*>(m_dataOutput); - QAndroidVideoOutput *newOutput = 0; - - if (m_surface) { - if (!m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty()) { - if (!m_textureOutput) { - m_dataOutput = 0; - newOutput = m_textureOutput = new QAndroidTextureVideoOutput(this); - } - } else if (!m_dataOutput) { - m_textureOutput = 0; - newOutput = m_dataOutput = new QAndroidCameraDataVideoOutput(this); - } - - if (m_textureOutput) - m_textureOutput->setSurface(m_surface); - } - - if (newOutput != oldOutput) { - m_cameraSession->setVideoOutput(newOutput); - delete oldOutput; - } -} - -QT_END_NAMESPACE - -#include "qandroidcameravideorenderercontrol.moc" - diff --git a/src/plugins/android/src/mediacapture/qandroidcameravideorenderercontrol.h b/src/plugins/android/src/mediacapture/qandroidcameravideorenderercontrol.h deleted file mode 100644 index 538226239..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcameravideorenderercontrol.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDCAMERAVIDEORENDERERCONTROL_H -#define QANDROIDCAMERAVIDEORENDERERCONTROL_H - -#include <qvideorenderercontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCameraSession; -class QAndroidTextureVideoOutput; -class QAndroidCameraDataVideoOutput; - -class QAndroidCameraVideoRendererControl : public QVideoRendererControl -{ - Q_OBJECT -public: - QAndroidCameraVideoRendererControl(QAndroidCameraSession *session, QObject *parent = 0); - ~QAndroidCameraVideoRendererControl() override; - - QAbstractVideoSurface *surface() const override; - void setSurface(QAbstractVideoSurface *surface) override; - - QAndroidCameraSession *cameraSession() const { return m_cameraSession; } - -private: - QAndroidCameraSession *m_cameraSession; - QAbstractVideoSurface *m_surface; - QAndroidTextureVideoOutput *m_textureOutput; - QAndroidCameraDataVideoOutput *m_dataOutput; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDCAMERAVIDEORENDERERCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcaptureservice.cpp b/src/plugins/android/src/mediacapture/qandroidcaptureservice.cpp deleted file mode 100644 index 469867ca8..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcaptureservice.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Ruslan Baratov -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidcaptureservice.h" - -#include "qandroidmediarecordercontrol.h" -#include "qandroidcapturesession.h" -#include "qandroidcameracontrol.h" -#include "qandroidvideodeviceselectorcontrol.h" -#include "qandroidaudioinputselectorcontrol.h" -#include "qandroidcamerasession.h" -#include "qandroidcameravideorenderercontrol.h" -#include "qandroidcameraexposurecontrol.h" -#include "qandroidcamerafocuscontrol.h" -#include "qandroidcameraimageprocessingcontrol.h" -#include "qandroidimageencodercontrol.h" -#include "qandroidcameraimagecapturecontrol.h" -#include "qandroidaudioencodersettingscontrol.h" -#include "qandroidvideoencodersettingscontrol.h" -#include "qandroidmediacontainercontrol.h" -#include "qandroidmediavideoprobecontrol.h" - -#include <qmediaserviceproviderplugin.h> - -QT_BEGIN_NAMESPACE - -QAndroidCaptureService::QAndroidCaptureService(const QString &service, QObject *parent) - : QMediaService(parent) - , m_service(service) - , m_videoRendererControl(0) -{ - if (m_service == QLatin1String(Q_MEDIASERVICE_CAMERA)) { - m_cameraSession = new QAndroidCameraSession; - m_cameraControl = new QAndroidCameraControl(m_cameraSession); - m_videoInputControl = new QAndroidVideoDeviceSelectorControl(m_cameraSession); - m_cameraExposureControl = new QAndroidCameraExposureControl(m_cameraSession); - m_cameraFocusControl = new QAndroidCameraFocusControl(m_cameraSession); - m_cameraImageProcessingControl = new QAndroidCameraImageProcessingControl(m_cameraSession); - m_imageEncoderControl = new QAndroidImageEncoderControl(m_cameraSession); - m_imageCaptureControl = new QAndroidCameraImageCaptureControl(m_cameraSession); - m_audioInputControl = 0; - } else { - m_cameraSession = 0; - m_cameraControl = 0; - m_videoInputControl = 0; - m_cameraExposureControl = 0; - m_cameraFocusControl = 0; - m_cameraImageProcessingControl = 0; - m_imageEncoderControl = 0; - m_imageCaptureControl = 0; - m_videoEncoderSettingsControl = 0; - } - - m_captureSession = new QAndroidCaptureSession(m_cameraSession); - m_recorderControl = new QAndroidMediaRecorderControl(m_captureSession); - m_audioEncoderSettingsControl = new QAndroidAudioEncoderSettingsControl(m_captureSession); - m_mediaContainerControl = new QAndroidMediaContainerControl(m_captureSession); - - if (m_service == QLatin1String(Q_MEDIASERVICE_CAMERA)) { - m_videoEncoderSettingsControl = new QAndroidVideoEncoderSettingsControl(m_captureSession); - } else { - m_audioInputControl = new QAndroidAudioInputSelectorControl(m_captureSession); - m_captureSession->setAudioInput(m_audioInputControl->defaultInput()); - } -} - -QAndroidCaptureService::~QAndroidCaptureService() -{ - delete m_audioEncoderSettingsControl; - delete m_videoEncoderSettingsControl; - delete m_mediaContainerControl; - delete m_recorderControl; - delete m_captureSession; - delete m_cameraControl; - delete m_audioInputControl; - delete m_videoInputControl; - delete m_videoRendererControl; - delete m_cameraExposureControl; - delete m_cameraFocusControl; - delete m_cameraImageProcessingControl; - delete m_imageEncoderControl; - delete m_imageCaptureControl; - delete m_cameraSession; -} - -QObject *QAndroidCaptureService::requestControl(const char *name) -{ - if (qstrcmp(name, QMediaRecorderControl_iid) == 0) - return m_recorderControl; - - if (qstrcmp(name, QMediaContainerControl_iid) == 0) - return m_mediaContainerControl; - - if (qstrcmp(name, QAudioEncoderSettingsControl_iid) == 0) - return m_audioEncoderSettingsControl; - - if (qstrcmp(name, QVideoEncoderSettingsControl_iid) == 0) - return m_videoEncoderSettingsControl; - - if (qstrcmp(name, QCameraControl_iid) == 0) - return m_cameraControl; - - if (qstrcmp(name, QAudioInputSelectorControl_iid) == 0) - return m_audioInputControl; - - if (qstrcmp(name, QVideoDeviceSelectorControl_iid) == 0) - return m_videoInputControl; - - if (qstrcmp(name, QCameraExposureControl_iid) == 0) - return m_cameraExposureControl; - - if (qstrcmp(name, QCameraFocusControl_iid) == 0) - return m_cameraFocusControl; - - if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0) - return m_cameraImageProcessingControl; - - if (qstrcmp(name, QImageEncoderControl_iid) == 0) - return m_imageEncoderControl; - - if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) - return m_imageCaptureControl; - - if (qstrcmp(name, QVideoRendererControl_iid) == 0 - && m_service == QLatin1String(Q_MEDIASERVICE_CAMERA) - && !m_videoRendererControl) { - m_videoRendererControl = new QAndroidCameraVideoRendererControl(m_cameraSession); - return m_videoRendererControl; - } - - if (qstrcmp(name,QMediaVideoProbeControl_iid) == 0) { - QAndroidMediaVideoProbeControl *videoProbe = 0; - if (m_cameraSession) { - videoProbe = new QAndroidMediaVideoProbeControl(this); - m_cameraSession->addProbe(videoProbe); - } - return videoProbe; - } - - return 0; -} - -void QAndroidCaptureService::releaseControl(QObject *control) -{ - if (control) { - if (control == m_videoRendererControl) { - delete m_videoRendererControl; - m_videoRendererControl = 0; - return; - } - - QAndroidMediaVideoProbeControl *videoProbe = qobject_cast<QAndroidMediaVideoProbeControl *>(control); - if (videoProbe) { - if (m_cameraSession) - m_cameraSession->removeProbe(videoProbe); - delete videoProbe; - return; - } - } - -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcaptureservice.h b/src/plugins/android/src/mediacapture/qandroidcaptureservice.h deleted file mode 100644 index 7c2e53c5f..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcaptureservice.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Ruslan Baratov -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDCAPTURESERVICE_H -#define QANDROIDCAPTURESERVICE_H - -#include <qmediaservice.h> -#include <qmediaservice.h> - -QT_BEGIN_NAMESPACE - -class QAndroidMediaRecorderControl; -class QAndroidCaptureSession; -class QAndroidCameraControl; -class QAndroidVideoDeviceSelectorControl; -class QAndroidAudioInputSelectorControl; -class QAndroidCameraSession; -class QAndroidCameraVideoRendererControl; -class QAndroidCameraExposureControl; -class QAndroidCameraFocusControl; -class QAndroidCameraImageProcessingControl; -class QAndroidImageEncoderControl; -class QAndroidCameraImageCaptureControl; -class QAndroidAudioEncoderSettingsControl; -class QAndroidVideoEncoderSettingsControl; -class QAndroidMediaContainerControl; - -class QAndroidCaptureService : public QMediaService -{ - Q_OBJECT - -public: - explicit QAndroidCaptureService(const QString &service, QObject *parent = 0); - virtual ~QAndroidCaptureService(); - - QObject *requestControl(const char *name); - void releaseControl(QObject *); - -private: - QString m_service; - - QAndroidMediaRecorderControl *m_recorderControl; - QAndroidCaptureSession *m_captureSession; - QAndroidCameraControl *m_cameraControl; - QAndroidVideoDeviceSelectorControl *m_videoInputControl; - QAndroidAudioInputSelectorControl *m_audioInputControl; - QAndroidCameraSession *m_cameraSession; - QAndroidCameraVideoRendererControl *m_videoRendererControl; - QAndroidCameraExposureControl *m_cameraExposureControl; - QAndroidCameraFocusControl *m_cameraFocusControl; - QAndroidCameraImageProcessingControl *m_cameraImageProcessingControl; - QAndroidImageEncoderControl *m_imageEncoderControl; - QAndroidCameraImageCaptureControl *m_imageCaptureControl; - QAndroidAudioEncoderSettingsControl *m_audioEncoderSettingsControl; - QAndroidVideoEncoderSettingsControl *m_videoEncoderSettingsControl; - QAndroidMediaContainerControl *m_mediaContainerControl; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDCAPTURESERVICE_H diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp deleted file mode 100644 index 768bb4442..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp +++ /dev/null @@ -1,594 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidcapturesession.h" - -#include "androidcamera.h" -#include "qandroidcamerasession.h" -#include "androidmultimediautils.h" -#include "qandroidmultimediautils.h" -#include "qandroidvideooutput.h" -#include "qandroidglobal.h" - -#include <algorithm> - -QT_BEGIN_NAMESPACE - -QAndroidCaptureSession::QAndroidCaptureSession(QAndroidCameraSession *cameraSession) - : QObject() - , m_mediaRecorder(0) - , m_cameraSession(cameraSession) - , m_audioSource(AndroidMediaRecorder::DefaultAudioSource) - , m_duration(0) - , m_state(QMediaRecorder::StoppedState) - , m_status(QMediaRecorder::UnloadedStatus) - , m_containerFormatDirty(true) - , m_videoSettingsDirty(true) - , m_audioSettingsDirty(true) - , m_outputFormat(AndroidMediaRecorder::DefaultOutputFormat) - , m_audioEncoder(AndroidMediaRecorder::DefaultAudioEncoder) - , m_videoEncoder(AndroidMediaRecorder::DefaultVideoEncoder) -{ - m_mediaStorageLocation.addStorageLocation( - QMediaStorageLocation::Movies, - AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::DCIM)); - - m_mediaStorageLocation.addStorageLocation( - QMediaStorageLocation::Sounds, - AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::Sounds)); - - if (cameraSession) { - connect(cameraSession, SIGNAL(opened()), this, SLOT(onCameraOpened())); - connect(cameraSession, &QAndroidCameraSession::statusChanged, this, - [this](QCamera::Status status) { - if (status == QCamera::UnavailableStatus) { - setState(QMediaRecorder::StoppedState); - setStatus(QMediaRecorder::UnavailableStatus); - return; - } - - // Stop recording when stopping the camera. - if (status == QCamera::StoppingStatus) { - setState(QMediaRecorder::StoppedState); - setStatus(QMediaRecorder::UnloadedStatus); - return; - } - - if (status == QCamera::LoadingStatus) - setStatus(QMediaRecorder::LoadingStatus); - }); - connect(cameraSession, &QAndroidCameraSession::captureModeChanged, this, - [this](QCamera::CaptureModes mode) { - if (!mode.testFlag(QCamera::CaptureVideo)) { - setState(QMediaRecorder::StoppedState); - setStatus(QMediaRecorder::UnloadedStatus); - } - }); - connect(cameraSession, &QAndroidCameraSession::readyForCaptureChanged, this, - [this](bool ready) { - if (ready) - setStatus(QMediaRecorder::LoadedStatus); - }); - } else { - // Audio-only recording. - setStatus(QMediaRecorder::LoadedStatus); - } - - m_notifyTimer.setInterval(1000); - connect(&m_notifyTimer, SIGNAL(timeout()), this, SLOT(updateDuration())); -} - -QAndroidCaptureSession::~QAndroidCaptureSession() -{ - stop(); - delete m_mediaRecorder; -} - -void QAndroidCaptureSession::setAudioInput(const QString &input) -{ - if (m_audioInput == input) - return; - - m_audioInput = input; - - if (m_audioInput == QLatin1String("default")) - m_audioSource = AndroidMediaRecorder::DefaultAudioSource; - else if (m_audioInput == QLatin1String("mic")) - m_audioSource = AndroidMediaRecorder::Mic; - else if (m_audioInput == QLatin1String("voice_uplink")) - m_audioSource = AndroidMediaRecorder::VoiceUplink; - else if (m_audioInput == QLatin1String("voice_downlink")) - m_audioSource = AndroidMediaRecorder::VoiceDownlink; - else if (m_audioInput == QLatin1String("voice_call")) - m_audioSource = AndroidMediaRecorder::VoiceCall; - else if (m_audioInput == QLatin1String("voice_recognition")) - m_audioSource = AndroidMediaRecorder::VoiceRecognition; - else - m_audioSource = AndroidMediaRecorder::DefaultAudioSource; - - emit audioInputChanged(m_audioInput); -} - -QUrl QAndroidCaptureSession::outputLocation() const -{ - return m_actualOutputLocation; -} - -bool QAndroidCaptureSession::setOutputLocation(const QUrl &location) -{ - if (m_requestedOutputLocation == location) - return false; - - m_actualOutputLocation = QUrl(); - m_requestedOutputLocation = location; - - if (m_requestedOutputLocation.isEmpty()) - return true; - - if (m_requestedOutputLocation.isValid() - && (m_requestedOutputLocation.isLocalFile() || m_requestedOutputLocation.isRelative())) { - return true; - } - - m_requestedOutputLocation = QUrl(); - return false; -} - -QMediaRecorder::State QAndroidCaptureSession::state() const -{ - return m_state; -} - -void QAndroidCaptureSession::setState(QMediaRecorder::State state) -{ - if (m_state == state) - return; - - switch (state) { - case QMediaRecorder::StoppedState: - stop(); - break; - case QMediaRecorder::RecordingState: - start(); - break; - case QMediaRecorder::PausedState: - // Not supported by Android API - qWarning("QMediaRecorder::PausedState is not supported on Android"); - break; - } -} - -void QAndroidCaptureSession::start() -{ - if (m_state == QMediaRecorder::RecordingState || m_status != QMediaRecorder::LoadedStatus) - return; - - setStatus(QMediaRecorder::StartingStatus); - - if (m_mediaRecorder) { - m_mediaRecorder->release(); - delete m_mediaRecorder; - } - - const bool granted = m_cameraSession - ? m_cameraSession->requestRecordingPermission() - : qt_androidRequestRecordingPermission(); - if (!granted) { - setStatus(QMediaRecorder::UnavailableStatus); - Q_EMIT error(QMediaRecorder::ResourceError, QLatin1String("Permission denied.")); - return; - } - - m_mediaRecorder = new AndroidMediaRecorder; - connect(m_mediaRecorder, SIGNAL(error(int,int)), this, SLOT(onError(int,int))); - connect(m_mediaRecorder, SIGNAL(info(int,int)), this, SLOT(onInfo(int,int))); - - // Set audio/video sources - if (m_cameraSession) { - updateViewfinder(); - m_cameraSession->camera()->unlock(); - m_mediaRecorder->setCamera(m_cameraSession->camera()); - m_mediaRecorder->setAudioSource(AndroidMediaRecorder::Camcorder); - m_mediaRecorder->setVideoSource(AndroidMediaRecorder::Camera); - } else { - m_mediaRecorder->setAudioSource(m_audioSource); - } - - // Set output format - m_mediaRecorder->setOutputFormat(m_outputFormat); - - // Set audio encoder settings - m_mediaRecorder->setAudioChannels(m_audioSettings.channelCount()); - m_mediaRecorder->setAudioEncodingBitRate(m_audioSettings.bitRate()); - m_mediaRecorder->setAudioSamplingRate(m_audioSettings.sampleRate()); - m_mediaRecorder->setAudioEncoder(m_audioEncoder); - - // Set video encoder settings - if (m_cameraSession) { - m_mediaRecorder->setVideoSize(m_videoSettings.resolution()); - m_mediaRecorder->setVideoFrameRate(qRound(m_videoSettings.frameRate())); - m_mediaRecorder->setVideoEncodingBitRate(m_videoSettings.bitRate()); - m_mediaRecorder->setVideoEncoder(m_videoEncoder); - - m_mediaRecorder->setOrientationHint(m_cameraSession->currentCameraRotation()); - } - - // Set output file - QString filePath = m_mediaStorageLocation.generateFileName( - m_requestedOutputLocation.isLocalFile() ? m_requestedOutputLocation.toLocalFile() - : m_requestedOutputLocation.toString(), - m_cameraSession ? QMediaStorageLocation::Movies - : QMediaStorageLocation::Sounds, - m_cameraSession ? QLatin1String("VID_") - : QLatin1String("REC_"), - m_containerFormat); - - m_usedOutputLocation = QUrl::fromLocalFile(filePath); - m_mediaRecorder->setOutputFile(filePath); - - // Even though the Android doc explicitly says that calling MediaRecorder.setPreviewDisplay() - // is not necessary when the Camera already has a Surface, it doesn't actually work on some - // devices. For example on the Samsung Galaxy Tab 2, the camera server dies after prepare() - // and start() if MediaRecorder.setPreviewDispaly() is not called. - if (m_cameraSession) { - // When using a SurfaceTexture, we need to pass a new one to the MediaRecorder, not the same - // one that is set on the Camera or it will crash, hence the reset(). - m_cameraSession->videoOutput()->reset(); - if (m_cameraSession->videoOutput()->surfaceTexture()) - m_mediaRecorder->setSurfaceTexture(m_cameraSession->videoOutput()->surfaceTexture()); - else if (m_cameraSession->videoOutput()->surfaceHolder()) - m_mediaRecorder->setSurfaceHolder(m_cameraSession->videoOutput()->surfaceHolder()); - } - - if (!m_mediaRecorder->prepare()) { - emit error(QMediaRecorder::FormatError, QLatin1String("Unable to prepare the media recorder.")); - if (m_cameraSession) - restartViewfinder(); - return; - } - - if (!m_mediaRecorder->start()) { - emit error(QMediaRecorder::FormatError, QLatin1String("Unable to start the media recorder.")); - if (m_cameraSession) - restartViewfinder(); - return; - } - - m_elapsedTime.start(); - m_notifyTimer.start(); - updateDuration(); - - if (m_cameraSession) { - m_cameraSession->setReadyForCapture(false); - - // Preview frame callback is cleared when setting up the camera with the media recorder. - // We need to reset it. - m_cameraSession->camera()->setupPreviewFrameCallback(); - } - - m_state = QMediaRecorder::RecordingState; - emit stateChanged(m_state); - setStatus(QMediaRecorder::RecordingStatus); -} - -void QAndroidCaptureSession::stop(bool error) -{ - if (m_state == QMediaRecorder::StoppedState || m_mediaRecorder == 0) - return; - - setStatus(QMediaRecorder::FinalizingStatus); - - m_mediaRecorder->stop(); - m_notifyTimer.stop(); - updateDuration(); - m_elapsedTime.invalidate(); - m_mediaRecorder->release(); - delete m_mediaRecorder; - m_mediaRecorder = 0; - - if (m_cameraSession && m_cameraSession->status() == QCamera::ActiveStatus) { - // Viewport needs to be restarted after recording - restartViewfinder(); - } - - if (!error) { - // if the media is saved into the standard media location, register it - // with the Android media scanner so it appears immediately in apps - // such as the gallery. - QString mediaPath = m_usedOutputLocation.toLocalFile(); - QString standardLoc = m_cameraSession ? AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::DCIM) - : AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::Sounds); - if (mediaPath.startsWith(standardLoc)) - AndroidMultimediaUtils::registerMediaFile(mediaPath); - - m_actualOutputLocation = m_usedOutputLocation; - emit actualLocationChanged(m_actualOutputLocation); - } - - m_state = QMediaRecorder::StoppedState; - emit stateChanged(m_state); - if (!m_cameraSession) - setStatus(QMediaRecorder::LoadedStatus); -} - -void QAndroidCaptureSession::setStatus(QMediaRecorder::Status status) -{ - if (m_status == status) - return; - - m_status = status; - emit statusChanged(m_status); -} - -QMediaRecorder::Status QAndroidCaptureSession::status() const -{ - return m_status; -} - -qint64 QAndroidCaptureSession::duration() const -{ - return m_duration; -} - -void QAndroidCaptureSession::setContainerFormat(const QString &format) -{ - if (m_containerFormat == format) - return; - - m_containerFormat = format; - m_containerFormatDirty = true; -} - -void QAndroidCaptureSession::setAudioSettings(const QAudioEncoderSettings &settings) -{ - if (m_audioSettings == settings) - return; - - m_audioSettings = settings; - m_audioSettingsDirty = true; -} - -void QAndroidCaptureSession::setVideoSettings(const QVideoEncoderSettings &settings) -{ - if (!m_cameraSession || m_videoSettings == settings) - return; - - m_videoSettings = settings; - m_videoSettingsDirty = true; -} - -void QAndroidCaptureSession::applySettings() -{ - // container settings - if (m_containerFormatDirty) { - if (m_containerFormat.isEmpty()) { - m_containerFormat = m_defaultSettings.outputFileExtension; - m_outputFormat = m_defaultSettings.outputFormat; - } else if (m_containerFormat == QLatin1String("3gp")) { - m_outputFormat = AndroidMediaRecorder::THREE_GPP; - } else if (!m_cameraSession && m_containerFormat == QLatin1String("amr")) { - m_outputFormat = AndroidMediaRecorder::AMR_NB_Format; - } else if (!m_cameraSession && m_containerFormat == QLatin1String("awb")) { - m_outputFormat = AndroidMediaRecorder::AMR_WB_Format; - } else { - m_containerFormat = QStringLiteral("mp4"); - m_outputFormat = AndroidMediaRecorder::MPEG_4; - } - - m_containerFormatDirty = false; - } - - // audio settings - if (m_audioSettingsDirty) { - if (m_audioSettings.channelCount() <= 0) - m_audioSettings.setChannelCount(m_defaultSettings.audioChannels); - if (m_audioSettings.bitRate() <= 0) - m_audioSettings.setBitRate(m_defaultSettings.audioBitRate); - if (m_audioSettings.sampleRate() <= 0) - m_audioSettings.setSampleRate(m_defaultSettings.audioSampleRate); - - if (m_audioSettings.codec().isEmpty()) - m_audioEncoder = m_defaultSettings.audioEncoder; - else if (m_audioSettings.codec() == QLatin1String("aac")) - m_audioEncoder = AndroidMediaRecorder::AAC; - else if (m_audioSettings.codec() == QLatin1String("amr-nb")) - m_audioEncoder = AndroidMediaRecorder::AMR_NB_Encoder; - else if (m_audioSettings.codec() == QLatin1String("amr-wb")) - m_audioEncoder = AndroidMediaRecorder::AMR_WB_Encoder; - else - m_audioEncoder = m_defaultSettings.audioEncoder; - - m_audioSettingsDirty = false; - } - - // video settings - if (m_cameraSession && m_cameraSession->camera() && m_videoSettingsDirty) { - if (m_videoSettings.resolution().isEmpty()) { - m_videoSettings.setResolution(m_defaultSettings.videoResolution); - } else if (!m_supportedResolutions.contains(m_videoSettings.resolution())) { - // if the requested resolution is not supported, find the closest one - QSize reqSize = m_videoSettings.resolution(); - int reqPixelCount = reqSize.width() * reqSize.height(); - QList<int> supportedPixelCounts; - for (int i = 0; i < m_supportedResolutions.size(); ++i) { - const QSize &s = m_supportedResolutions.at(i); - supportedPixelCounts.append(s.width() * s.height()); - } - int closestIndex = qt_findClosestValue(supportedPixelCounts, reqPixelCount); - m_videoSettings.setResolution(m_supportedResolutions.at(closestIndex)); - } - - if (m_videoSettings.frameRate() <= 0) - m_videoSettings.setFrameRate(m_defaultSettings.videoFrameRate); - if (m_videoSettings.bitRate() <= 0) - m_videoSettings.setBitRate(m_defaultSettings.videoBitRate); - - if (m_videoSettings.codec().isEmpty()) - m_videoEncoder = m_defaultSettings.videoEncoder; - else if (m_videoSettings.codec() == QLatin1String("h263")) - m_videoEncoder = AndroidMediaRecorder::H263; - else if (m_videoSettings.codec() == QLatin1String("h264")) - m_videoEncoder = AndroidMediaRecorder::H264; - else if (m_videoSettings.codec() == QLatin1String("mpeg4_sp")) - m_videoEncoder = AndroidMediaRecorder::MPEG_4_SP; - else - m_videoEncoder = m_defaultSettings.videoEncoder; - - m_videoSettingsDirty = false; - } -} - -void QAndroidCaptureSession::updateViewfinder() -{ - m_cameraSession->camera()->stopPreviewSynchronous(); - m_cameraSession->applyViewfinderSettings(m_videoSettings.resolution(), false); -} - -void QAndroidCaptureSession::restartViewfinder() -{ - if (!m_cameraSession) - return; - - m_cameraSession->camera()->reconnect(); - - // This is not necessary on most devices, but it crashes on some if we don't stop the - // preview and reset the preview display on the camera when recording is over. - m_cameraSession->camera()->stopPreviewSynchronous(); - m_cameraSession->videoOutput()->reset(); - if (m_cameraSession->videoOutput()->surfaceTexture()) - m_cameraSession->camera()->setPreviewTexture(m_cameraSession->videoOutput()->surfaceTexture()); - else if (m_cameraSession->videoOutput()->surfaceHolder()) - m_cameraSession->camera()->setPreviewDisplay(m_cameraSession->videoOutput()->surfaceHolder()); - - m_cameraSession->camera()->startPreview(); - m_cameraSession->setReadyForCapture(true); -} - -void QAndroidCaptureSession::updateDuration() -{ - if (m_elapsedTime.isValid()) - m_duration = m_elapsedTime.elapsed(); - - emit durationChanged(m_duration); -} - -void QAndroidCaptureSession::onCameraOpened() -{ - m_supportedResolutions.clear(); - m_supportedFramerates.clear(); - - // get supported resolutions from predefined profiles - for (int i = 0; i < 8; ++i) { - CaptureProfile profile = getProfile(i); - if (!profile.isNull) { - if (i == AndroidCamcorderProfile::QUALITY_HIGH) - m_defaultSettings = profile; - - if (!m_supportedResolutions.contains(profile.videoResolution)) - m_supportedResolutions.append(profile.videoResolution); - if (!m_supportedFramerates.contains(profile.videoFrameRate)) - m_supportedFramerates.append(profile.videoFrameRate); - } - } - - std::sort(m_supportedResolutions.begin(), m_supportedResolutions.end(), qt_sizeLessThan); - std::sort(m_supportedFramerates.begin(), m_supportedFramerates.end()); - - applySettings(); -} - -QAndroidCaptureSession::CaptureProfile QAndroidCaptureSession::getProfile(int id) -{ - CaptureProfile profile; - const bool hasProfile = AndroidCamcorderProfile::hasProfile(m_cameraSession->camera()->cameraId(), - AndroidCamcorderProfile::Quality(id)); - - if (hasProfile) { - AndroidCamcorderProfile camProfile = AndroidCamcorderProfile::get(m_cameraSession->camera()->cameraId(), - AndroidCamcorderProfile::Quality(id)); - - profile.outputFormat = AndroidMediaRecorder::OutputFormat(camProfile.getValue(AndroidCamcorderProfile::fileFormat)); - profile.audioEncoder = AndroidMediaRecorder::AudioEncoder(camProfile.getValue(AndroidCamcorderProfile::audioCodec)); - profile.audioBitRate = camProfile.getValue(AndroidCamcorderProfile::audioBitRate); - profile.audioChannels = camProfile.getValue(AndroidCamcorderProfile::audioChannels); - profile.audioSampleRate = camProfile.getValue(AndroidCamcorderProfile::audioSampleRate); - profile.videoEncoder = AndroidMediaRecorder::VideoEncoder(camProfile.getValue(AndroidCamcorderProfile::videoCodec)); - profile.videoBitRate = camProfile.getValue(AndroidCamcorderProfile::videoBitRate); - profile.videoFrameRate = camProfile.getValue(AndroidCamcorderProfile::videoFrameRate); - profile.videoResolution = QSize(camProfile.getValue(AndroidCamcorderProfile::videoFrameWidth), - camProfile.getValue(AndroidCamcorderProfile::videoFrameHeight)); - - if (profile.outputFormat == AndroidMediaRecorder::MPEG_4) - profile.outputFileExtension = QStringLiteral("mp4"); - else if (profile.outputFormat == AndroidMediaRecorder::THREE_GPP) - profile.outputFileExtension = QStringLiteral("3gp"); - else if (profile.outputFormat == AndroidMediaRecorder::AMR_NB_Format) - profile.outputFileExtension = QStringLiteral("amr"); - else if (profile.outputFormat == AndroidMediaRecorder::AMR_WB_Format) - profile.outputFileExtension = QStringLiteral("awb"); - - profile.isNull = false; - } - - return profile; -} - -void QAndroidCaptureSession::onError(int what, int extra) -{ - Q_UNUSED(what); - Q_UNUSED(extra); - stop(true); - emit error(QMediaRecorder::ResourceError, QLatin1String("Unknown error.")); -} - -void QAndroidCaptureSession::onInfo(int what, int extra) -{ - Q_UNUSED(extra); - if (what == 800) { - // MEDIA_RECORDER_INFO_MAX_DURATION_REACHED - setState(QMediaRecorder::StoppedState); - emit error(QMediaRecorder::OutOfSpaceError, QLatin1String("Maximum duration reached.")); - } else if (what == 801) { - // MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED - setState(QMediaRecorder::StoppedState); - emit error(QMediaRecorder::OutOfSpaceError, QLatin1String("Maximum file size reached.")); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.h b/src/plugins/android/src/mediacapture/qandroidcapturesession.h deleted file mode 100644 index 8cfb9ad2a..000000000 --- a/src/plugins/android/src/mediacapture/qandroidcapturesession.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDCAPTURESESSION_H -#define QANDROIDCAPTURESESSION_H - -#include <qobject.h> -#include <qmediarecorder.h> -#include <qurl.h> -#include <qelapsedtimer.h> -#include <qtimer.h> -#include <private/qmediastoragelocation_p.h> -#include "androidmediarecorder.h" - -QT_BEGIN_NAMESPACE - -class QAndroidCameraSession; - -class QAndroidCaptureSession : public QObject -{ - Q_OBJECT -public: - explicit QAndroidCaptureSession(QAndroidCameraSession *cameraSession = 0); - ~QAndroidCaptureSession(); - - QList<QSize> supportedResolutions() const { return m_supportedResolutions; } - QList<qreal> supportedFrameRates() const { return m_supportedFramerates; } - - QString audioInput() const { return m_audioInput; } - void setAudioInput(const QString &input); - - QUrl outputLocation() const; - bool setOutputLocation(const QUrl &location); - - QMediaRecorder::State state() const; - void setState(QMediaRecorder::State state); - - QMediaRecorder::Status status() const; - - qint64 duration() const; - - QString containerFormat() const { return m_containerFormat; } - void setContainerFormat(const QString &format); - - QAudioEncoderSettings audioSettings() const { return m_audioSettings; } - void setAudioSettings(const QAudioEncoderSettings &settings); - - QVideoEncoderSettings videoSettings() const { return m_videoSettings; } - void setVideoSettings(const QVideoEncoderSettings &settings); - - void applySettings(); - -Q_SIGNALS: - void audioInputChanged(const QString& name); - void stateChanged(QMediaRecorder::State state); - void statusChanged(QMediaRecorder::Status status); - void durationChanged(qint64 position); - void actualLocationChanged(const QUrl &location); - void error(int error, const QString &errorString); - -private Q_SLOTS: - void updateDuration(); - void onCameraOpened(); - - void onError(int what, int extra); - void onInfo(int what, int extra); - -private: - struct CaptureProfile { - AndroidMediaRecorder::OutputFormat outputFormat; - QString outputFileExtension; - - AndroidMediaRecorder::AudioEncoder audioEncoder; - int audioBitRate; - int audioChannels; - int audioSampleRate; - - AndroidMediaRecorder::VideoEncoder videoEncoder; - int videoBitRate; - int videoFrameRate; - QSize videoResolution; - - bool isNull; - - CaptureProfile() - : outputFormat(AndroidMediaRecorder::MPEG_4) - , outputFileExtension(QLatin1String("mp4")) - , audioEncoder(AndroidMediaRecorder::DefaultAudioEncoder) - , audioBitRate(128000) - , audioChannels(2) - , audioSampleRate(44100) - , videoEncoder(AndroidMediaRecorder::DefaultVideoEncoder) - , videoBitRate(1) - , videoFrameRate(-1) - , videoResolution(320, 240) - , isNull(true) - { } - }; - - CaptureProfile getProfile(int id); - - void start(); - void stop(bool error = false); - - void setStatus(QMediaRecorder::Status status); - - void updateViewfinder(); - void restartViewfinder(); - - AndroidMediaRecorder *m_mediaRecorder; - QAndroidCameraSession *m_cameraSession; - - QString m_audioInput; - AndroidMediaRecorder::AudioSource m_audioSource; - - QMediaStorageLocation m_mediaStorageLocation; - - QElapsedTimer m_elapsedTime; - QTimer m_notifyTimer; - qint64 m_duration; - - QMediaRecorder::State m_state; - QMediaRecorder::Status m_status; - QUrl m_requestedOutputLocation; - QUrl m_usedOutputLocation; - QUrl m_actualOutputLocation; - - CaptureProfile m_defaultSettings; - - QString m_containerFormat; - QAudioEncoderSettings m_audioSettings; - QVideoEncoderSettings m_videoSettings; - bool m_containerFormatDirty; - bool m_videoSettingsDirty; - bool m_audioSettingsDirty; - AndroidMediaRecorder::OutputFormat m_outputFormat; - AndroidMediaRecorder::AudioEncoder m_audioEncoder; - AndroidMediaRecorder::VideoEncoder m_videoEncoder; - - QList<QSize> m_supportedResolutions; - QList<qreal> m_supportedFramerates; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDCAPTURESESSION_H diff --git a/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.cpp b/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.cpp deleted file mode 100644 index 666f553e5..000000000 --- a/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidimageencodercontrol.h" - -#include "qandroidcamerasession.h" -#include "androidcamera.h" - -QT_BEGIN_NAMESPACE - -QAndroidImageEncoderControl::QAndroidImageEncoderControl(QAndroidCameraSession *session) - : QImageEncoderControl() - , m_session(session) -{ - connect(m_session, SIGNAL(opened()), - this, SLOT(onCameraOpened())); -} - -QStringList QAndroidImageEncoderControl::supportedImageCodecs() const -{ - return QStringList() << QLatin1String("jpeg"); -} - -QString QAndroidImageEncoderControl::imageCodecDescription(const QString &codecName) const -{ - if (codecName == QLatin1String("jpeg")) - return tr("JPEG image"); - - return QString(); -} - -QList<QSize> QAndroidImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const -{ - Q_UNUSED(settings); - - if (continuous) - *continuous = false; - - return m_supportedResolutions; -} - -QImageEncoderSettings QAndroidImageEncoderControl::imageSettings() const -{ - return m_session->imageSettings(); -} - -void QAndroidImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings) -{ - m_session->setImageSettings(settings); -} - -void QAndroidImageEncoderControl::onCameraOpened() -{ - m_supportedResolutions = m_session->camera()->getSupportedPictureSizes(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.h b/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.h deleted file mode 100644 index 52f602e78..000000000 --- a/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDIMAGEENCODERCONTROL_H -#define QANDROIDIMAGEENCODERCONTROL_H - -#include <qimageencodercontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCameraSession; - -class QAndroidImageEncoderControl : public QImageEncoderControl -{ - Q_OBJECT -public: - explicit QAndroidImageEncoderControl(QAndroidCameraSession *session); - - QStringList supportedImageCodecs() const override; - QString imageCodecDescription(const QString &codecName) const override; - QList<QSize> supportedResolutions(const QImageEncoderSettings &settings, bool *continuous = 0) const override; - QImageEncoderSettings imageSettings() const override; - void setImageSettings(const QImageEncoderSettings &settings) override; - -private Q_SLOTS: - void onCameraOpened(); - -private: - QAndroidCameraSession *m_session; - - QList<QSize> m_supportedResolutions; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDIMAGEENCODERCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.cpp b/src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.cpp deleted file mode 100644 index bda711367..000000000 --- a/src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidmediacontainercontrol.h" - -#include "qandroidcapturesession.h" - -QT_BEGIN_NAMESPACE - -QAndroidMediaContainerControl::QAndroidMediaContainerControl(QAndroidCaptureSession *session) - : QMediaContainerControl() - , m_session(session) -{ -} - -QStringList QAndroidMediaContainerControl::supportedContainers() const -{ - return QStringList() << QLatin1String("mp4") - << QLatin1String("3gp") - << QLatin1String("amr") - << QLatin1String("awb"); -} - -QString QAndroidMediaContainerControl::containerFormat() const -{ - return m_session->containerFormat(); -} - -void QAndroidMediaContainerControl::setContainerFormat(const QString &format) -{ - m_session->setContainerFormat(format); -} - -QString QAndroidMediaContainerControl::containerDescription(const QString &formatMimeType) const -{ - if (formatMimeType == QLatin1String("mp4")) - return tr("MPEG4 media file format"); - else if (formatMimeType == QLatin1String("3gp")) - return tr("3GPP media file format"); - else if (formatMimeType == QLatin1String("amr")) - return tr("AMR NB file format"); - else if (formatMimeType == QLatin1String("awb")) - return tr("AMR WB file format"); - - return QString(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.h b/src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.h deleted file mode 100644 index 1d90fb6cd..000000000 --- a/src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDMEDIACONTAINERCONTROL_H -#define QANDROIDMEDIACONTAINERCONTROL_H - -#include <qmediacontainercontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCaptureSession; - -class QAndroidMediaContainerControl : public QMediaContainerControl -{ - Q_OBJECT -public: - QAndroidMediaContainerControl(QAndroidCaptureSession *session); - - QStringList supportedContainers() const override; - QString containerFormat() const override; - void setContainerFormat(const QString &format) override; - QString containerDescription(const QString &formatMimeType) const override; - -private: - QAndroidCaptureSession *m_session; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDMEDIACONTAINERCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.cpp b/src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.cpp deleted file mode 100644 index fa68409d3..000000000 --- a/src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidmediarecordercontrol.h" - -#include "qandroidcapturesession.h" - -QT_BEGIN_NAMESPACE - -QAndroidMediaRecorderControl::QAndroidMediaRecorderControl(QAndroidCaptureSession *session) - : QMediaRecorderControl() - , m_session(session) -{ - connect(m_session, SIGNAL(stateChanged(QMediaRecorder::State)), this, SIGNAL(stateChanged(QMediaRecorder::State))); - connect(m_session, SIGNAL(statusChanged(QMediaRecorder::Status)), this, SIGNAL(statusChanged(QMediaRecorder::Status))); - connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64))); - connect(m_session, SIGNAL(actualLocationChanged(QUrl)), this, SIGNAL(actualLocationChanged(QUrl))); - connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString))); -} - -QUrl QAndroidMediaRecorderControl::outputLocation() const -{ - return m_session->outputLocation(); -} - -bool QAndroidMediaRecorderControl::setOutputLocation(const QUrl &location) -{ - return m_session->setOutputLocation(location); -} - -QMediaRecorder::State QAndroidMediaRecorderControl::state() const -{ - return m_session->state(); -} - -QMediaRecorder::Status QAndroidMediaRecorderControl::status() const -{ - return m_session->status(); -} - -qint64 QAndroidMediaRecorderControl::duration() const -{ - return m_session->duration(); -} - -bool QAndroidMediaRecorderControl::isMuted() const -{ - // No API for this in Android - return false; -} - -qreal QAndroidMediaRecorderControl::volume() const -{ - // No API for this in Android - return 1.0; -} - -void QAndroidMediaRecorderControl::applySettings() -{ - m_session->applySettings(); -} - -void QAndroidMediaRecorderControl::setState(QMediaRecorder::State state) -{ - m_session->setState(state); -} - -void QAndroidMediaRecorderControl::setMuted(bool muted) -{ - // No API for this in Android - Q_UNUSED(muted); - qWarning("QMediaRecorder::setMuted() is not supported on Android."); -} - -void QAndroidMediaRecorderControl::setVolume(qreal volume) -{ - // No API for this in Android - Q_UNUSED(volume); - qWarning("QMediaRecorder::setVolume() is not supported on Android."); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.h b/src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.h deleted file mode 100644 index 6da59a50d..000000000 --- a/src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDMEDIARECORDERCONTROL_H -#define QANDROIDMEDIARECORDERCONTROL_H - -#include <qmediarecordercontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCaptureSession; - -class QAndroidMediaRecorderControl : public QMediaRecorderControl -{ - Q_OBJECT -public: - explicit QAndroidMediaRecorderControl(QAndroidCaptureSession *session); - - QUrl outputLocation() const override; - bool setOutputLocation(const QUrl &location) override; - QMediaRecorder::State state() const override; - QMediaRecorder::Status status() const override; - qint64 duration() const override; - bool isMuted() const override; - qreal volume() const override; - void applySettings() override; - -public Q_SLOTS: - void setState(QMediaRecorder::State state) override; - void setMuted(bool muted) override; - void setVolume(qreal volume) override; - -private: - QAndroidCaptureSession *m_session; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDMEDIARECORDERCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.cpp b/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.cpp deleted file mode 100644 index 1995ebf6a..000000000 --- a/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Integrated Computer Solutions, Inc -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidmediavideoprobecontrol.h" -#include <qvideoframe.h> - -QT_BEGIN_NAMESPACE - -QAndroidMediaVideoProbeControl::QAndroidMediaVideoProbeControl(QObject *parent) : - QMediaVideoProbeControl(parent) -{ -} - -QAndroidMediaVideoProbeControl::~QAndroidMediaVideoProbeControl() -{ - -} - -void QAndroidMediaVideoProbeControl::newFrameProbed(const QVideoFrame &frame) -{ - emit videoFrameProbed(frame); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.h b/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.h deleted file mode 100644 index 3306ad224..000000000 --- a/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Integrated Computer Solutions, Inc -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDMEDIAVIDEOPROBECONTROL_H -#define QANDROIDMEDIAVIDEOPROBECONTROL_H - -#include <qmediavideoprobecontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidMediaVideoProbeControl : public QMediaVideoProbeControl -{ - Q_OBJECT -public: - explicit QAndroidMediaVideoProbeControl(QObject *parent = 0); - virtual ~QAndroidMediaVideoProbeControl(); - - void newFrameProbed(const QVideoFrame& frame); - -}; - -QT_END_NAMESPACE - -#endif // QANDROIDMEDIAVIDEOPROBECONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.cpp deleted file mode 100644 index 0c7756693..000000000 --- a/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidvideodeviceselectorcontrol.h" - -#include "qandroidcamerasession.h" -#include "androidcamera.h" - -QT_BEGIN_NAMESPACE - -QAndroidVideoDeviceSelectorControl::QAndroidVideoDeviceSelectorControl(QAndroidCameraSession *session) - : QVideoDeviceSelectorControl(0) - , m_selectedDevice(0) - , m_cameraSession(session) -{ -} - -QAndroidVideoDeviceSelectorControl::~QAndroidVideoDeviceSelectorControl() -{ -} - -int QAndroidVideoDeviceSelectorControl::deviceCount() const -{ - return QAndroidCameraSession::availableCameras().count(); -} - -QString QAndroidVideoDeviceSelectorControl::deviceName(int index) const -{ - if (index < 0 || index >= QAndroidCameraSession::availableCameras().count()) - return QString(); - - return QString::fromLatin1(QAndroidCameraSession::availableCameras().at(index).name); -} - -QString QAndroidVideoDeviceSelectorControl::deviceDescription(int index) const -{ - if (index < 0 || index >= QAndroidCameraSession::availableCameras().count()) - return QString(); - - return QAndroidCameraSession::availableCameras().at(index).description; -} - -QCamera::Position QAndroidVideoDeviceSelectorControl::cameraPosition(int index) const -{ - if (index < 0 || index >= QAndroidCameraSession::availableCameras().count()) - return QCamera::UnspecifiedPosition; - - return QAndroidCameraSession::availableCameras().at(index).position; -} - -int QAndroidVideoDeviceSelectorControl::cameraOrientation(int index) const -{ - if (index < 0 || index >= QAndroidCameraSession::availableCameras().count()) - return QCamera::UnspecifiedPosition; - - return QAndroidCameraSession::availableCameras().at(index).orientation; -} - -int QAndroidVideoDeviceSelectorControl::defaultDevice() const -{ - return 0; -} - -int QAndroidVideoDeviceSelectorControl::selectedDevice() const -{ - return m_selectedDevice; -} - -void QAndroidVideoDeviceSelectorControl::setSelectedDevice(int index) -{ - if (index != m_selectedDevice) { - m_selectedDevice = index; - m_cameraSession->setSelectedCamera(m_selectedDevice); - emit selectedDeviceChanged(index); - emit selectedDeviceChanged(deviceName(index)); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.h b/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.h deleted file mode 100644 index cdfffcaf0..000000000 --- a/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDVIDEODEVICESELECTORCONTROL_H -#define QANDROIDVIDEODEVICESELECTORCONTROL_H - -#include <qvideodeviceselectorcontrol.h> -#include <QtCore/qstringlist.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCameraSession; - -class QAndroidVideoDeviceSelectorControl : public QVideoDeviceSelectorControl -{ - Q_OBJECT -public: - explicit QAndroidVideoDeviceSelectorControl(QAndroidCameraSession *session); - ~QAndroidVideoDeviceSelectorControl(); - - int deviceCount() const; - - QString deviceName(int index) const; - QString deviceDescription(int index) const; - QCamera::Position cameraPosition(int index) const; - int cameraOrientation(int index) const; - - int defaultDevice() const; - int selectedDevice() const; - void setSelectedDevice(int index); - -private: - int m_selectedDevice; - - QAndroidCameraSession *m_cameraSession; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDVIDEODEVICESELECTORCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.cpp b/src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.cpp deleted file mode 100644 index 3d67e8cfa..000000000 --- a/src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidvideoencodersettingscontrol.h" - -#include "qandroidcapturesession.h" - -QT_BEGIN_NAMESPACE - -QAndroidVideoEncoderSettingsControl::QAndroidVideoEncoderSettingsControl(QAndroidCaptureSession *session) - : QVideoEncoderSettingsControl() - , m_session(session) -{ -} - -QList<QSize> QAndroidVideoEncoderSettingsControl::supportedResolutions(const QVideoEncoderSettings &, bool *continuous) const -{ - if (continuous) - *continuous = false; - - return m_session->supportedResolutions(); -} - -QList<qreal> QAndroidVideoEncoderSettingsControl::supportedFrameRates(const QVideoEncoderSettings &, bool *continuous) const -{ - if (continuous) - *continuous = false; - - return m_session->supportedFrameRates(); -} - -QStringList QAndroidVideoEncoderSettingsControl::supportedVideoCodecs() const -{ - return QStringList() << QLatin1String("h263") - << QLatin1String("h264") - << QLatin1String("mpeg4_sp"); -} - -QString QAndroidVideoEncoderSettingsControl::videoCodecDescription(const QString &codecName) const -{ - if (codecName == QLatin1String("h263")) - return tr("H.263 compression"); - else if (codecName == QLatin1String("h264")) - return tr("H.264 compression"); - else if (codecName == QLatin1String("mpeg4_sp")) - return tr("MPEG-4 SP compression"); - - return QString(); -} - -QVideoEncoderSettings QAndroidVideoEncoderSettingsControl::videoSettings() const -{ - return m_session->videoSettings(); -} - -void QAndroidVideoEncoderSettingsControl::setVideoSettings(const QVideoEncoderSettings &settings) -{ - m_session->setVideoSettings(settings); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.h b/src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.h deleted file mode 100644 index 146b44ac4..000000000 --- a/src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDVIDEOENCODERSETTINGSCONTROL_H -#define QANDROIDVIDEOENCODERSETTINGSCONTROL_H - -#include <qvideoencodersettingscontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidCaptureSession; - -class QAndroidVideoEncoderSettingsControl : public QVideoEncoderSettingsControl -{ - Q_OBJECT -public: - explicit QAndroidVideoEncoderSettingsControl(QAndroidCaptureSession *session); - - QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous = 0) const override; - QList<qreal> supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous = 0) const override; - QStringList supportedVideoCodecs() const override; - QString videoCodecDescription(const QString &codecName) const override; - QVideoEncoderSettings videoSettings() const override; - void setVideoSettings(const QVideoEncoderSettings &settings) override; - -private: - QAndroidCaptureSession *m_session; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDVIDEOENCODERSETTINGSCONTROL_H diff --git a/src/plugins/android/src/mediaplayer/mediaplayer.pri b/src/plugins/android/src/mediaplayer/mediaplayer.pri deleted file mode 100644 index 9f758a993..000000000 --- a/src/plugins/android/src/mediaplayer/mediaplayer.pri +++ /dev/null @@ -1,13 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/qandroidmediaplayercontrol.h \ - $$PWD/qandroidmediaservice.h \ - $$PWD/qandroidmetadatareadercontrol.h \ - $$PWD/qandroidmediaplayervideorenderercontrol.h - -SOURCES += \ - $$PWD/qandroidmediaplayercontrol.cpp \ - $$PWD/qandroidmediaservice.cpp \ - $$PWD/qandroidmetadatareadercontrol.cpp \ - $$PWD/qandroidmediaplayervideorenderercontrol.cpp diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp deleted file mode 100644 index f667413dd..000000000 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp +++ /dev/null @@ -1,835 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidmediaplayercontrol.h" -#include "androidmediaplayer.h" -#include "qandroidvideooutput.h" - -QT_BEGIN_NAMESPACE - -class StateChangeNotifier -{ -public: - StateChangeNotifier(QAndroidMediaPlayerControl *mp) - : mControl(mp) - , mPreviousState(mp->state()) - , mPreviousMediaStatus(mp->mediaStatus()) - { - ++mControl->mActiveStateChangeNotifiers; - } - - ~StateChangeNotifier() - { - if (--mControl->mActiveStateChangeNotifiers) - return; - - if (mPreviousMediaStatus != mControl->mediaStatus()) - Q_EMIT mControl->mediaStatusChanged(mControl->mediaStatus()); - - if (mPreviousState != mControl->state()) - Q_EMIT mControl->stateChanged(mControl->state()); - } - -private: - QAndroidMediaPlayerControl *mControl; - QMediaPlayer::State mPreviousState; - QMediaPlayer::MediaStatus mPreviousMediaStatus; -}; - - -QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent) - : QMediaPlayerControl(parent), - mMediaPlayer(new AndroidMediaPlayer), - mCurrentState(QMediaPlayer::StoppedState), - mCurrentMediaStatus(QMediaPlayer::NoMedia), - mMediaStream(0), - mVideoOutput(0), - mSeekable(true), - mBufferPercent(-1), - mBufferFilled(false), - mAudioAvailable(false), - mVideoAvailable(false), - mBuffering(false), - mState(AndroidMediaPlayer::Uninitialized), - mPendingState(-1), - mPendingPosition(-1), - mPendingSetMedia(false), - mPendingVolume(-1), - mPendingMute(-1), - mReloadingMedia(false), - mActiveStateChangeNotifiers(0), - mPendingPlaybackRate(1.0), - mHasPendingPlaybackRate(false) -{ - connect(mMediaPlayer,SIGNAL(bufferingChanged(qint32)), - this,SLOT(onBufferingChanged(qint32))); - connect(mMediaPlayer,SIGNAL(info(qint32,qint32)), - this,SLOT(onInfo(qint32,qint32))); - connect(mMediaPlayer,SIGNAL(error(qint32,qint32)), - this,SLOT(onError(qint32,qint32))); - connect(mMediaPlayer,SIGNAL(stateChanged(qint32)), - this,SLOT(onStateChanged(qint32))); - connect(mMediaPlayer,SIGNAL(videoSizeChanged(qint32,qint32)), - this,SLOT(onVideoSizeChanged(qint32,qint32))); - connect(mMediaPlayer,SIGNAL(progressChanged(qint64)), - this,SIGNAL(positionChanged(qint64))); - connect(mMediaPlayer,SIGNAL(durationChanged(qint64)), - this,SIGNAL(durationChanged(qint64))); -} - -QAndroidMediaPlayerControl::~QAndroidMediaPlayerControl() -{ - mMediaPlayer->release(); - delete mMediaPlayer; -} - -QMediaPlayer::State QAndroidMediaPlayerControl::state() const -{ - return mCurrentState; -} - -QMediaPlayer::MediaStatus QAndroidMediaPlayerControl::mediaStatus() const -{ - return mCurrentMediaStatus; -} - -qint64 QAndroidMediaPlayerControl::duration() const -{ - if ((mState & (AndroidMediaPlayer::Prepared - | AndroidMediaPlayer::Started - | AndroidMediaPlayer::Paused - | AndroidMediaPlayer::Stopped - | AndroidMediaPlayer::PlaybackCompleted)) == 0) { - return 0; - } - - return mMediaPlayer->getDuration(); -} - -qint64 QAndroidMediaPlayerControl::position() const -{ - if (mCurrentMediaStatus == QMediaPlayer::EndOfMedia) - return duration(); - - if ((mState & (AndroidMediaPlayer::Prepared - | AndroidMediaPlayer::Started - | AndroidMediaPlayer::Paused - | AndroidMediaPlayer::PlaybackCompleted))) { - return mMediaPlayer->getCurrentPosition(); - } - - return (mPendingPosition == -1) ? 0 : mPendingPosition; -} - -void QAndroidMediaPlayerControl::setPosition(qint64 position) -{ - if (!mSeekable) - return; - - const int seekPosition = (position > INT_MAX) ? INT_MAX : position; - - if (seekPosition == this->position()) - return; - - StateChangeNotifier notifier(this); - - if (mCurrentMediaStatus == QMediaPlayer::EndOfMedia) - setMediaStatus(QMediaPlayer::LoadedMedia); - - if ((mState & (AndroidMediaPlayer::Prepared - | AndroidMediaPlayer::Started - | AndroidMediaPlayer::Paused - | AndroidMediaPlayer::PlaybackCompleted)) == 0) { - mPendingPosition = seekPosition; - } else { - mMediaPlayer->seekTo(seekPosition); - - if (mPendingPosition != -1) { - mPendingPosition = -1; - } - } - - Q_EMIT positionChanged(seekPosition); -} - -int QAndroidMediaPlayerControl::volume() const -{ - return (mPendingVolume == -1) ? mMediaPlayer->volume() : mPendingVolume; -} - -void QAndroidMediaPlayerControl::setVolume(int volume) -{ - if ((mState & (AndroidMediaPlayer::Idle - | AndroidMediaPlayer::Initialized - | AndroidMediaPlayer::Stopped - | AndroidMediaPlayer::Prepared - | AndroidMediaPlayer::Started - | AndroidMediaPlayer::Paused - | AndroidMediaPlayer::PlaybackCompleted)) == 0) { - if (mPendingVolume != volume) { - mPendingVolume = volume; - Q_EMIT volumeChanged(volume); - } - return; - } - - mMediaPlayer->setVolume(volume); - - if (mPendingVolume != -1) { - mPendingVolume = -1; - return; - } - - Q_EMIT volumeChanged(volume); -} - -bool QAndroidMediaPlayerControl::isMuted() const -{ - return (mPendingMute == -1) ? mMediaPlayer->isMuted() : (mPendingMute == 1); -} - -void QAndroidMediaPlayerControl::setMuted(bool muted) -{ - if ((mState & (AndroidMediaPlayer::Idle - | AndroidMediaPlayer::Initialized - | AndroidMediaPlayer::Stopped - | AndroidMediaPlayer::Prepared - | AndroidMediaPlayer::Started - | AndroidMediaPlayer::Paused - | AndroidMediaPlayer::PlaybackCompleted)) == 0) { - if (mPendingMute != muted) { - mPendingMute = muted; - Q_EMIT mutedChanged(muted); - } - return; - } - - mMediaPlayer->setMuted(muted); - - if (mPendingMute != -1) { - mPendingMute = -1; - return; - } - - Q_EMIT mutedChanged(muted); -} - -void QAndroidMediaPlayerControl::setAudioRole(QAudio::Role role) -{ - mMediaPlayer->setAudioRole(role); -} - -QList<QAudio::Role> QAndroidMediaPlayerControl::supportedAudioRoles() const -{ - return QList<QAudio::Role>() - << QAudio::VoiceCommunicationRole - << QAudio::MusicRole - << QAudio::VideoRole - << QAudio::SonificationRole - << QAudio::AlarmRole - << QAudio::NotificationRole - << QAudio::RingtoneRole - << QAudio::AccessibilityRole - << QAudio::GameRole; -} - -void QAndroidMediaPlayerControl::setCustomAudioRole(const QString &role) -{ - mMediaPlayer->setCustomAudioRole(role); -} - -QStringList QAndroidMediaPlayerControl::supportedCustomAudioRoles() const -{ - return QStringList() - << "CONTENT_TYPE_MOVIE" - << "CONTENT_TYPE_MUSIC" - << "CONTENT_TYPE_SONIFICATION" - << "CONTENT_TYPE_SPEECH" - << "USAGE_ALARM" - << "USAGE_ASSISTANCE_ACCESSIBILITY" - << "USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" - << "USAGE_ASSISTANCE_SONIFICATION" - << "USAGE_ASSISTANT" - << "USAGE_GAME" - << "USAGE_MEDIA" - << "USAGE_NOTIFICATION" - << "USAGE_NOTIFICATION_COMMUNICATION_DELAYED" - << "USAGE_NOTIFICATION_COMMUNICATION_INSTANT" - << "USAGE_NOTIFICATION_COMMUNICATION_REQUEST" - << "USAGE_NOTIFICATION_EVENT" - << "USAGE_NOTIFICATION_RINGTONE" - << "USAGE_VOICE_COMMUNICATION" - << "USAGE_VOICE_COMMUNICATION_SIGNALLING"; -} - -int QAndroidMediaPlayerControl::bufferStatus() const -{ - return mBufferFilled ? 100 : 0; -} - -bool QAndroidMediaPlayerControl::isAudioAvailable() const -{ - return mAudioAvailable; -} - -bool QAndroidMediaPlayerControl::isVideoAvailable() const -{ - return mVideoAvailable; -} - -bool QAndroidMediaPlayerControl::isSeekable() const -{ - return mSeekable; -} - -QMediaTimeRange QAndroidMediaPlayerControl::availablePlaybackRanges() const -{ - return mAvailablePlaybackRange; -} - -void QAndroidMediaPlayerControl::updateAvailablePlaybackRanges() -{ - if (mBuffering) { - const qint64 pos = position(); - const qint64 end = (duration() / 100) * mBufferPercent; - mAvailablePlaybackRange.addInterval(pos, end); - } else if (mSeekable) { - mAvailablePlaybackRange = QMediaTimeRange(0, duration()); - } else { - mAvailablePlaybackRange = QMediaTimeRange(); - } - - Q_EMIT availablePlaybackRangesChanged(mAvailablePlaybackRange); -} - -qreal QAndroidMediaPlayerControl::playbackRate() const -{ - if (mHasPendingPlaybackRate || - (mState & (AndroidMediaPlayer::Initialized - | AndroidMediaPlayer::Prepared - | AndroidMediaPlayer::Started - | AndroidMediaPlayer::Paused - | AndroidMediaPlayer::PlaybackCompleted - | AndroidMediaPlayer::Error)) == 0) { - return mPendingPlaybackRate; - } - - return mMediaPlayer->playbackRate(); -} - -void QAndroidMediaPlayerControl::setPlaybackRate(qreal rate) -{ - if ((mState & (AndroidMediaPlayer::Initialized - | AndroidMediaPlayer::Prepared - | AndroidMediaPlayer::Started - | AndroidMediaPlayer::Paused - | AndroidMediaPlayer::PlaybackCompleted - | AndroidMediaPlayer::Error)) == 0) { - if (mPendingPlaybackRate != rate) { - mPendingPlaybackRate = rate; - mHasPendingPlaybackRate = true; - Q_EMIT playbackRateChanged(rate); - } - return; - } - - bool succeeded = mMediaPlayer->setPlaybackRate(rate); - - if (mHasPendingPlaybackRate) { - mHasPendingPlaybackRate = false; - mPendingPlaybackRate = qreal(1.0); - if (!succeeded) - Q_EMIT playbackRateChanged(playbackRate()); - } else if (succeeded) { - Q_EMIT playbackRateChanged(rate); - } -} - -QUrl QAndroidMediaPlayerControl::media() const -{ - return mMediaContent; -} - -const QIODevice *QAndroidMediaPlayerControl::mediaStream() const -{ - return mMediaStream; -} - -void QAndroidMediaPlayerControl::setMedia(const QUrl &mediaContent, - QIODevice *stream) -{ - StateChangeNotifier notifier(this); - - mReloadingMedia = (mMediaContent == mediaContent) && !mPendingSetMedia; - - if (!mReloadingMedia) { - mMediaContent = mediaContent; - mMediaStream = stream; - } - - // Release the mediaplayer if it's not in in Idle or Uninitialized state - if ((mState & (AndroidMediaPlayer::Idle | AndroidMediaPlayer::Uninitialized)) == 0) - mMediaPlayer->release(); - - if (mediaContent.isNull()) { - setMediaStatus(QMediaPlayer::NoMedia); - } else { - if (mVideoOutput && !mVideoOutput->isReady()) { - // if a video output is set but the video texture is not ready, delay loading the media - // since it can cause problems on some hardware - mPendingSetMedia = true; - return; - } - - if (mVideoSize.isValid() && mVideoOutput) - mVideoOutput->setVideoSize(mVideoSize); - - if ((mMediaPlayer->display() == 0) && mVideoOutput) - mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture()); - mMediaPlayer->setDataSource(mediaContent.request()); - mMediaPlayer->prepareAsync(); - } - - if (!mReloadingMedia) - Q_EMIT mediaChanged(mMediaContent); - - resetBufferingProgress(); - - mReloadingMedia = false; -} - -void QAndroidMediaPlayerControl::setVideoOutput(QAndroidVideoOutput *videoOutput) -{ - if (mVideoOutput) { - mMediaPlayer->setDisplay(0); - mVideoOutput->stop(); - mVideoOutput->reset(); - } - - mVideoOutput = videoOutput; - - if (!mVideoOutput) - return; - - if (mVideoOutput->isReady()) - mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture()); - - connect(videoOutput, SIGNAL(readyChanged(bool)), this, SLOT(onVideoOutputReady(bool))); -} - -void QAndroidMediaPlayerControl::play() -{ - StateChangeNotifier notifier(this); - - // We need to prepare the mediaplayer again. - if ((mState & AndroidMediaPlayer::Stopped) && !mMediaContent.isNull()) { - setMedia(mMediaContent, mMediaStream); - } - - if (!mMediaContent.isNull()) - setState(QMediaPlayer::PlayingState); - - if ((mState & (AndroidMediaPlayer::Prepared - | AndroidMediaPlayer::Started - | AndroidMediaPlayer::Paused - | AndroidMediaPlayer::PlaybackCompleted)) == 0) { - mPendingState = QMediaPlayer::PlayingState; - return; - } - - mMediaPlayer->play(); -} - -void QAndroidMediaPlayerControl::pause() -{ - StateChangeNotifier notifier(this); - - setState(QMediaPlayer::PausedState); - - if ((mState & (AndroidMediaPlayer::Started - | AndroidMediaPlayer::Paused - | AndroidMediaPlayer::PlaybackCompleted)) == 0) { - mPendingState = QMediaPlayer::PausedState; - return; - } - - mMediaPlayer->pause(); -} - -void QAndroidMediaPlayerControl::stop() -{ - StateChangeNotifier notifier(this); - - setState(QMediaPlayer::StoppedState); - - if ((mState & (AndroidMediaPlayer::Prepared - | AndroidMediaPlayer::Started - | AndroidMediaPlayer::Stopped - | AndroidMediaPlayer::Paused - | AndroidMediaPlayer::PlaybackCompleted)) == 0) { - if ((mState & (AndroidMediaPlayer::Idle | AndroidMediaPlayer::Uninitialized | AndroidMediaPlayer::Error)) == 0) - mPendingState = QMediaPlayer::StoppedState; - return; - } - - mMediaPlayer->stop(); -} - -void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra) -{ - StateChangeNotifier notifier(this); - - Q_UNUSED(extra); - switch (what) { - case AndroidMediaPlayer::MEDIA_INFO_UNKNOWN: - break; - case AndroidMediaPlayer::MEDIA_INFO_VIDEO_TRACK_LAGGING: - // IGNORE - break; - case AndroidMediaPlayer::MEDIA_INFO_VIDEO_RENDERING_START: - break; - case AndroidMediaPlayer::MEDIA_INFO_BUFFERING_START: - mPendingState = mCurrentState; - setState(QMediaPlayer::PausedState); - setMediaStatus(QMediaPlayer::StalledMedia); - break; - case AndroidMediaPlayer::MEDIA_INFO_BUFFERING_END: - if (mCurrentState != QMediaPlayer::StoppedState) - flushPendingStates(); - break; - case AndroidMediaPlayer::MEDIA_INFO_BAD_INTERLEAVING: - break; - case AndroidMediaPlayer::MEDIA_INFO_NOT_SEEKABLE: - setSeekable(false); - break; - case AndroidMediaPlayer::MEDIA_INFO_METADATA_UPDATE: - Q_EMIT metaDataUpdated(); - break; - } -} - -void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra) -{ - StateChangeNotifier notifier(this); - - QString errorString; - QMediaPlayer::Error error = QMediaPlayer::ResourceError; - - switch (what) { - case AndroidMediaPlayer::MEDIA_ERROR_UNKNOWN: - errorString = QLatin1String("Error:"); - break; - case AndroidMediaPlayer::MEDIA_ERROR_SERVER_DIED: - errorString = QLatin1String("Error: Server died"); - error = QMediaPlayer::ServiceMissingError; - break; - case AndroidMediaPlayer::MEDIA_ERROR_INVALID_STATE: - errorString = QLatin1String("Error: Invalid state"); - error = QMediaPlayer::ServiceMissingError; - break; - } - - switch (extra) { - case AndroidMediaPlayer::MEDIA_ERROR_IO: // Network OR file error - errorString += QLatin1String(" (I/O operation failed)"); - error = QMediaPlayer::NetworkError; - setMediaStatus(QMediaPlayer::InvalidMedia); - break; - case AndroidMediaPlayer::MEDIA_ERROR_MALFORMED: - errorString += QLatin1String(" (Malformed bitstream)"); - error = QMediaPlayer::FormatError; - setMediaStatus(QMediaPlayer::InvalidMedia); - break; - case AndroidMediaPlayer::MEDIA_ERROR_UNSUPPORTED: - errorString += QLatin1String(" (Unsupported media)"); - error = QMediaPlayer::FormatError; - setMediaStatus(QMediaPlayer::InvalidMedia); - break; - case AndroidMediaPlayer::MEDIA_ERROR_TIMED_OUT: - errorString += QLatin1String(" (Timed out)"); - break; - case AndroidMediaPlayer::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK: - errorString += QLatin1String(" (Unable to start progressive playback')"); - error = QMediaPlayer::FormatError; - setMediaStatus(QMediaPlayer::InvalidMedia); - break; - case AndroidMediaPlayer::MEDIA_ERROR_BAD_THINGS_ARE_GOING_TO_HAPPEN: - errorString += QLatin1String(" (Unknown error/Insufficient resources)"); - error = QMediaPlayer::ServiceMissingError; - break; - } - - Q_EMIT QMediaPlayerControl::error(error, errorString); -} - -void QAndroidMediaPlayerControl::onBufferingChanged(qint32 percent) -{ - StateChangeNotifier notifier(this); - - mBuffering = percent != 100; - mBufferPercent = percent; - - updateAvailablePlaybackRanges(); - - if (mCurrentState != QMediaPlayer::StoppedState) - setMediaStatus(mBuffering ? QMediaPlayer::BufferingMedia : QMediaPlayer::BufferedMedia); -} - -void QAndroidMediaPlayerControl::onVideoSizeChanged(qint32 width, qint32 height) -{ - QSize newSize(width, height); - - if (width == 0 || height == 0 || newSize == mVideoSize) - return; - - setVideoAvailable(true); - mVideoSize = newSize; - - if (mVideoOutput) - mVideoOutput->setVideoSize(mVideoSize); -} - -void QAndroidMediaPlayerControl::onStateChanged(qint32 state) -{ - // If reloading, don't report state changes unless the new state is Prepared or Error. - if ((mState & AndroidMediaPlayer::Stopped) - && (state & (AndroidMediaPlayer::Prepared | AndroidMediaPlayer::Error | AndroidMediaPlayer::Uninitialized)) == 0) { - return; - } - - StateChangeNotifier notifier(this); - - mState = state; - switch (mState) { - case AndroidMediaPlayer::Idle: - break; - case AndroidMediaPlayer::Initialized: - break; - case AndroidMediaPlayer::Preparing: - if (!mReloadingMedia) - setMediaStatus(QMediaPlayer::LoadingMedia); - break; - case AndroidMediaPlayer::Prepared: - setMediaStatus(QMediaPlayer::LoadedMedia); - if (mBuffering) { - setMediaStatus(mBufferPercent == 100 ? QMediaPlayer::BufferedMedia - : QMediaPlayer::BufferingMedia); - } else { - onBufferingChanged(100); - } - Q_EMIT metaDataUpdated(); - setAudioAvailable(true); - flushPendingStates(); - break; - case AndroidMediaPlayer::Started: - setState(QMediaPlayer::PlayingState); - if (mBuffering) { - setMediaStatus(mBufferPercent == 100 ? QMediaPlayer::BufferedMedia - : QMediaPlayer::BufferingMedia); - } else { - setMediaStatus(QMediaPlayer::BufferedMedia); - } - Q_EMIT positionChanged(position()); - break; - case AndroidMediaPlayer::Paused: - setState(QMediaPlayer::PausedState); - break; - case AndroidMediaPlayer::Error: - setState(QMediaPlayer::StoppedState); - setMediaStatus(QMediaPlayer::UnknownMediaStatus); - mMediaPlayer->release(); - Q_EMIT positionChanged(0); - break; - case AndroidMediaPlayer::Stopped: - setState(QMediaPlayer::StoppedState); - setMediaStatus(QMediaPlayer::LoadedMedia); - Q_EMIT positionChanged(0); - break; - case AndroidMediaPlayer::PlaybackCompleted: - setState(QMediaPlayer::StoppedState); - setMediaStatus(QMediaPlayer::EndOfMedia); - break; - case AndroidMediaPlayer::Uninitialized: - // reset some properties (unless we reload the same media) - if (!mReloadingMedia) { - resetBufferingProgress(); - mPendingPosition = -1; - mPendingSetMedia = false; - mPendingState = -1; - - Q_EMIT durationChanged(0); - Q_EMIT positionChanged(0); - - setAudioAvailable(false); - setVideoAvailable(false); - setSeekable(true); - } - break; - default: - break; - } - - if ((mState & (AndroidMediaPlayer::Stopped | AndroidMediaPlayer::Uninitialized)) != 0) { - mMediaPlayer->setDisplay(0); - if (mVideoOutput) { - mVideoOutput->stop(); - mVideoOutput->reset(); - } - } -} - -void QAndroidMediaPlayerControl::onVideoOutputReady(bool ready) -{ - if ((mMediaPlayer->display() == 0) && mVideoOutput && ready) - mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture()); - - flushPendingStates(); -} - -void QAndroidMediaPlayerControl::setState(QMediaPlayer::State state) -{ - if (mCurrentState == state) - return; - - if (mCurrentState == QMediaPlayer::StoppedState && state == QMediaPlayer::PausedState) - return; - - mCurrentState = state; -} - -void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status) -{ - if (mCurrentMediaStatus == status) - return; - - mCurrentMediaStatus = status; - - if (status == QMediaPlayer::NoMedia || status == QMediaPlayer::InvalidMedia) - Q_EMIT durationChanged(0); - - if (status == QMediaPlayer::EndOfMedia) - Q_EMIT positionChanged(position()); - - updateBufferStatus(); -} - -void QAndroidMediaPlayerControl::setSeekable(bool seekable) -{ - if (mSeekable == seekable) - return; - - mSeekable = seekable; - Q_EMIT seekableChanged(mSeekable); -} - -void QAndroidMediaPlayerControl::setAudioAvailable(bool available) -{ - if (mAudioAvailable == available) - return; - - mAudioAvailable = available; - Q_EMIT audioAvailableChanged(mAudioAvailable); -} - -void QAndroidMediaPlayerControl::setVideoAvailable(bool available) -{ - if (mVideoAvailable == available) - return; - - if (!available) - mVideoSize = QSize(); - - mVideoAvailable = available; - Q_EMIT videoAvailableChanged(mVideoAvailable); -} - -void QAndroidMediaPlayerControl::resetBufferingProgress() -{ - mBuffering = false; - mBufferPercent = 0; - mAvailablePlaybackRange = QMediaTimeRange(); -} - -void QAndroidMediaPlayerControl::flushPendingStates() -{ - if (mPendingSetMedia) { - setMedia(mMediaContent, 0); - mPendingSetMedia = false; - return; - } - - const int newState = mPendingState; - mPendingState = -1; - - if (mPendingPosition != -1) - setPosition(mPendingPosition); - if (mPendingVolume != -1) - setVolume(mPendingVolume); - if (mPendingMute != -1) - setMuted((mPendingMute == 1)); - if (mHasPendingPlaybackRate) - setPlaybackRate(mPendingPlaybackRate); - - switch (newState) { - case QMediaPlayer::PlayingState: - play(); - break; - case QMediaPlayer::PausedState: - pause(); - break; - case QMediaPlayer::StoppedState: - stop(); - break; - default: - break; - } -} - -void QAndroidMediaPlayerControl::updateBufferStatus() -{ - bool bufferFilled = (mCurrentMediaStatus == QMediaPlayer::BufferedMedia - || mCurrentMediaStatus == QMediaPlayer::BufferingMedia); - - if (mBufferFilled != bufferFilled) { - mBufferFilled = bufferFilled; - Q_EMIT bufferStatusChanged(bufferStatus()); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h deleted file mode 100644 index 84fdefb15..000000000 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDMEDIAPLAYERCONTROL_H -#define QANDROIDMEDIAPLAYERCONTROL_H - -#include <qglobal.h> -#include <QMediaPlayerControl> -#include <qsize.h> - -QT_BEGIN_NAMESPACE - -class AndroidMediaPlayer; -class QAndroidVideoOutput; - -class QAndroidMediaPlayerControl : public QMediaPlayerControl -{ - Q_OBJECT -public: - explicit QAndroidMediaPlayerControl(QObject *parent = 0); - ~QAndroidMediaPlayerControl() override; - - QMediaPlayer::State state() const override; - QMediaPlayer::MediaStatus mediaStatus() const override; - qint64 duration() const override; - qint64 position() const override; - int volume() const override; - bool isMuted() const override; - int bufferStatus() const override; - bool isAudioAvailable() const override; - bool isVideoAvailable() const override; - bool isSeekable() const override; - QMediaTimeRange availablePlaybackRanges() const override; - qreal playbackRate() const override; - void setPlaybackRate(qreal rate) override; - QUrl media() const override; - const QIODevice *mediaStream() const override; - void setMedia(const QUrl &mediaContent, QIODevice *stream) override; - - void setAudioRole(QAudio::Role role) override; - QList<QAudio::Role> supportedAudioRoles() const override; - void setCustomAudioRole(const QString &role) override; - QStringList supportedCustomAudioRoles() const override; - - void setVideoOutput(QAndroidVideoOutput *videoOutput); - -Q_SIGNALS: - void metaDataUpdated(); - -public Q_SLOTS: - void setPosition(qint64 position) override; - void play() override; - void pause() override; - void stop() override; - void setVolume(int volume) override; - void setMuted(bool muted) override; - -private Q_SLOTS: - void onVideoOutputReady(bool ready); - void onError(qint32 what, qint32 extra); - void onInfo(qint32 what, qint32 extra); - void onBufferingChanged(qint32 percent); - void onVideoSizeChanged(qint32 width, qint32 height); - void onStateChanged(qint32 state); - -private: - AndroidMediaPlayer *mMediaPlayer; - QMediaPlayer::State mCurrentState; - QMediaPlayer::MediaStatus mCurrentMediaStatus; - QUrl mMediaContent; - QIODevice *mMediaStream; - QAndroidVideoOutput *mVideoOutput; - bool mSeekable; - int mBufferPercent; - bool mBufferFilled; - bool mAudioAvailable; - bool mVideoAvailable; - QSize mVideoSize; - bool mBuffering; - QMediaTimeRange mAvailablePlaybackRange; - int mState; - int mPendingState; - qint64 mPendingPosition; - bool mPendingSetMedia; - int mPendingVolume; - int mPendingMute; - bool mReloadingMedia; - int mActiveStateChangeNotifiers; - qreal mPendingPlaybackRate; - bool mHasPendingPlaybackRate; // we need this because the rate can theoretically be negative - - void setState(QMediaPlayer::State state); - void setMediaStatus(QMediaPlayer::MediaStatus status); - void setSeekable(bool seekable); - void setAudioAvailable(bool available); - void setVideoAvailable(bool available); - void updateAvailablePlaybackRanges(); - void resetBufferingProgress(); - void flushPendingStates(); - void updateBufferStatus(); - - friend class StateChangeNotifier; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDMEDIAPLAYERCONTROL_H diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayervideorenderercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaplayervideorenderercontrol.cpp deleted file mode 100644 index 5252d60ad..000000000 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayervideorenderercontrol.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidmediaplayervideorenderercontrol.h" - -#include "qandroidmediaplayercontrol.h" -#include "qandroidvideooutput.h" -#include <qabstractvideosurface.h> - -QT_BEGIN_NAMESPACE - -QAndroidMediaPlayerVideoRendererControl::QAndroidMediaPlayerVideoRendererControl(QAndroidMediaPlayerControl *mediaPlayer, QObject *parent) - : QVideoRendererControl(parent) - , m_mediaPlayerControl(mediaPlayer) - , m_surface(0) - , m_textureOutput(new QAndroidTextureVideoOutput(this)) -{ - m_mediaPlayerControl->setVideoOutput(m_textureOutput); -} - -QAndroidMediaPlayerVideoRendererControl::~QAndroidMediaPlayerVideoRendererControl() -{ - m_mediaPlayerControl->setVideoOutput(0); -} - -QAbstractVideoSurface *QAndroidMediaPlayerVideoRendererControl::surface() const -{ - return m_surface; -} - -void QAndroidMediaPlayerVideoRendererControl::setSurface(QAbstractVideoSurface *surface) -{ - if (m_surface == surface) - return; - - m_surface = surface; - m_textureOutput->setSurface(m_surface); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayervideorenderercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmediaplayervideorenderercontrol.h deleted file mode 100644 index ef213cc57..000000000 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayervideorenderercontrol.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDMEDIAPLAYERVIDEORENDERERCONTROL_H -#define QANDROIDMEDIAPLAYERVIDEORENDERERCONTROL_H - -#include <qvideorenderercontrol.h> - -QT_BEGIN_NAMESPACE - -class QAndroidMediaPlayerControl; -class QAndroidTextureVideoOutput; - -class QAndroidMediaPlayerVideoRendererControl : public QVideoRendererControl -{ - Q_OBJECT -public: - QAndroidMediaPlayerVideoRendererControl(QAndroidMediaPlayerControl *mediaPlayer, QObject *parent = 0); - ~QAndroidMediaPlayerVideoRendererControl() override; - - QAbstractVideoSurface *surface() const override; - void setSurface(QAbstractVideoSurface *surface) override; - -private: - QAndroidMediaPlayerControl *m_mediaPlayerControl; - QAbstractVideoSurface *m_surface; - QAndroidTextureVideoOutput *m_textureOutput; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDMEDIAPLAYERVIDEORENDERERCONTROL_H diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp deleted file mode 100644 index 084df5554..000000000 --- a/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidmediaservice.h" - -#include "qandroidmediaplayercontrol.h" -#include "qandroidmetadatareadercontrol.h" -#include "qandroidmediaplayervideorenderercontrol.h" - -QT_BEGIN_NAMESPACE - -QAndroidMediaService::QAndroidMediaService(QObject *parent) - : QMediaService(parent) - , mAudioRoleControl(nullptr) - , mCustomAudioRoleControl(nullptr) - , mVideoRendererControl(0) -{ - mMediaControl = new QAndroidMediaPlayerControl; - mMetadataControl = new QAndroidMetaDataReaderControl; - connect(mMediaControl, SIGNAL(mediaChanged(QUrl)), - mMetadataControl, SLOT(onMediaChanged(QUrl))); - connect(mMediaControl, SIGNAL(metaDataUpdated()), - mMetadataControl, SLOT(onUpdateMetaData())); -} - -QAndroidMediaService::~QAndroidMediaService() -{ - delete mVideoRendererControl; - delete mMetadataControl; - delete mMediaControl; -} - -QObject *QAndroidMediaService::requestControl(const char *name) -{ - if (qstrcmp(name, QMediaPlayerControl_iid) == 0) - return mMediaControl; - - if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) - return mMetadataControl; - - if (qstrcmp(name, QVideoRendererControl_iid) == 0) { - if (!mVideoRendererControl) { - mVideoRendererControl = new QAndroidMediaPlayerVideoRendererControl(mMediaControl); - return mVideoRendererControl; - } - } - - return 0; -} - -void QAndroidMediaService::releaseControl(QObject *control) -{ - if (control == mVideoRendererControl) { - delete mVideoRendererControl; - mVideoRendererControl = 0; - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaservice.h b/src/plugins/android/src/mediaplayer/qandroidmediaservice.h deleted file mode 100644 index 8a1da12cb..000000000 --- a/src/plugins/android/src/mediaplayer/qandroidmediaservice.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDMEDIASERVICE_H -#define QANDROIDMEDIASERVICE_H - -#include <QMediaService> - -QT_BEGIN_NAMESPACE - -class QAndroidMediaPlayerControl; -class QAndroidMetaDataReaderControl; -class QAndroidAudioRoleControl; -class QAndroidCustomAudioRoleControl; -class QAndroidMediaPlayerVideoRendererControl; - -class QAndroidMediaService : public QMediaService -{ - Q_OBJECT -public: - explicit QAndroidMediaService(QObject *parent = 0); - ~QAndroidMediaService() override; - - QObject *requestControl(const char *name) override; - void releaseControl(QObject *control) override; - -private: - QAndroidMediaPlayerControl *mMediaControl; - QAndroidMetaDataReaderControl *mMetadataControl; - QAndroidAudioRoleControl *mAudioRoleControl; - QAndroidCustomAudioRoleControl *mCustomAudioRoleControl; - QAndroidMediaPlayerVideoRendererControl *mVideoRendererControl; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDMEDIASERVICE_H diff --git a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp deleted file mode 100644 index 3bfb2f61b..000000000 --- a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidmetadatareadercontrol.h" - -#include "androidmediametadataretriever.h" -#include <QtMultimedia/qmediametadata.h> -#include <qsize.h> -#include <QDate> -#include <QtCore/qlist.h> -#include <QtConcurrent/qtconcurrentrun.h> - -QT_BEGIN_NAMESPACE - -// Genre name ordered by ID -// see: http://id3.org/id3v2.3.0#Appendix_A_-_Genre_List_from_ID3v1 -static const char* qt_ID3GenreNames[] = -{ - "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", - "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", - "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", - "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", - "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", - "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", - "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", - "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", - "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", - "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", - "Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", - "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", - "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", - "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", - "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", - "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A capella", - "Euro-House", "Dance Hall" -}; - -typedef QList<QAndroidMetaDataReaderControl *> AndroidMetaDataReaders; -Q_GLOBAL_STATIC(AndroidMetaDataReaders, g_metaDataReaders) -Q_GLOBAL_STATIC(QMutex, g_metaDataReadersMtx) - -QAndroidMetaDataReaderControl::QAndroidMetaDataReaderControl(QObject *parent) - : QMetaDataReaderControl(parent) - , m_available(false) -{ -} - -QAndroidMetaDataReaderControl::~QAndroidMetaDataReaderControl() -{ - QMutexLocker l(g_metaDataReadersMtx()); - const int idx = g_metaDataReaders->indexOf(this); - if (idx != -1) - g_metaDataReaders->remove(idx); -} - -bool QAndroidMetaDataReaderControl::isMetaDataAvailable() const -{ - const QMutexLocker l(&m_mtx); - return m_available && !m_metadata.isEmpty(); -} - -QVariant QAndroidMetaDataReaderControl::metaData(const QString &key) const -{ - const QMutexLocker l(&m_mtx); - return m_metadata.value(key); -} - -QStringList QAndroidMetaDataReaderControl::availableMetaData() const -{ - const QMutexLocker l(&m_mtx); - return m_metadata.keys(); -} - -void QAndroidMetaDataReaderControl::onMediaChanged(const QUrl &media) -{ - const QMutexLocker l(&m_mtx); - m_metadata.clear(); - m_mediaContent = media; -} - -void QAndroidMetaDataReaderControl::onUpdateMetaData() -{ - { - const QMutexLocker l(g_metaDataReadersMtx()); - if (!g_metaDataReaders->contains(this)) - g_metaDataReaders->append(this); - } - - const QMutexLocker ml(&m_mtx); - if (m_mediaContent.isNull()) - return; - - const QUrl &url = m_mediaContent.request().url(); - QtConcurrent::run(&extractMetadata, this, url); -} - -void QAndroidMetaDataReaderControl::updateData(const QVariantMap &metadata, const QUrl &url) -{ - const QMutexLocker l(&m_mtx); - - if (m_mediaContent.request().url() != url) - return; - - const bool oldAvailable = m_available; - m_metadata = metadata; - m_available = !m_metadata.isEmpty(); - - if (m_available != oldAvailable) - Q_EMIT metaDataAvailableChanged(m_available); - - Q_EMIT metaDataChanged(); -} - -void QAndroidMetaDataReaderControl::extractMetadata(QAndroidMetaDataReaderControl *caller, - const QUrl &url) -{ - QVariantMap metadata; - - if (!url.isEmpty()) { - AndroidMediaMetadataRetriever retriever; - if (!retriever.setDataSource(url)) - return; - - QString mimeType = retriever.extractMetadata(AndroidMediaMetadataRetriever::MimeType); - if (!mimeType.isNull()) - metadata.insert(QMediaMetaData::MediaType, mimeType); - - bool isVideo = !retriever.extractMetadata(AndroidMediaMetadataRetriever::HasVideo).isNull() - || mimeType.startsWith(QStringLiteral("video")); - - QString string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Album); - if (!string.isNull()) - metadata.insert(QMediaMetaData::AlbumTitle, string); - - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::AlbumArtist); - if (!string.isNull()) - metadata.insert(QMediaMetaData::AlbumArtist, string); - - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Artist); - if (!string.isNull()) { - metadata.insert(isVideo ? QMediaMetaData::LeadPerformer - : QMediaMetaData::ContributingArtist, - string.split('/', Qt::SkipEmptyParts)); - } - - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Author); - if (!string.isNull()) - metadata.insert(QMediaMetaData::Author, string.split('/', Qt::SkipEmptyParts)); - - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Bitrate); - if (!string.isNull()) { - metadata.insert(isVideo ? QMediaMetaData::VideoBitRate - : QMediaMetaData::AudioBitRate, - string.toInt()); - } - - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::CDTrackNumber); - if (!string.isNull()) - metadata.insert(QMediaMetaData::TrackNumber, string.toInt()); - - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Composer); - if (!string.isNull()) - metadata.insert(QMediaMetaData::Composer, string.split('/', Qt::SkipEmptyParts)); - - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Date); - if (!string.isNull()) - metadata.insert(QMediaMetaData::Date, QDateTime::fromString(string, QStringLiteral("yyyyMMddTHHmmss.zzzZ")).date()); - - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Duration); - if (!string.isNull()) - metadata.insert(QMediaMetaData::Duration, string.toLongLong()); - - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Genre); - if (!string.isNull()) { - // The genre can be returned as an ID3v2 id, get the name for it in that case - if (string.startsWith('(') && string.endsWith(')')) { - bool ok = false; - const int genreId = QStringView{string}.mid(1, string.length() - 2).toInt(&ok); - if (ok && genreId >= 0 && genreId <= 125) - string = QLatin1String(qt_ID3GenreNames[genreId]); - } - metadata.insert(QMediaMetaData::Genre, string); - } - - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Title); - if (!string.isNull()) - metadata.insert(QMediaMetaData::Title, string); - - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::VideoHeight); - if (!string.isNull()) { - const int height = string.toInt(); - const int width = retriever.extractMetadata(AndroidMediaMetadataRetriever::VideoWidth).toInt(); - metadata.insert(QMediaMetaData::Resolution, QSize(width, height)); - } - - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Writer); - if (!string.isNull()) - metadata.insert(QMediaMetaData::Writer, string.split('/', Qt::SkipEmptyParts)); - - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Year); - if (!string.isNull()) - metadata.insert(QMediaMetaData::Year, string.toInt()); - } - - const QMutexLocker lock(g_metaDataReadersMtx()); - if (!g_metaDataReaders->contains(caller)) - return; - - caller->updateData(metadata, url); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h deleted file mode 100644 index 18aa9fda6..000000000 --- a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDMETADATAREADERCONTROL_H -#define QANDROIDMETADATAREADERCONTROL_H - -#include <QMetaDataReaderControl> -#include <QUrl.h> -#include <QMutex> - -QT_BEGIN_NAMESPACE - -class AndroidMediaMetadataRetriever; - -class QAndroidMetaDataReaderControl : public QMetaDataReaderControl -{ - Q_OBJECT -public: - explicit QAndroidMetaDataReaderControl(QObject *parent = 0); - ~QAndroidMetaDataReaderControl() override; - - bool isMetaDataAvailable() const override; - - QVariant metaData(const QString &key) const override; - QStringList availableMetaData() const override; - -public Q_SLOTS: - void onMediaChanged(const QUrl &media); - void onUpdateMetaData(); - -private: - void updateData(const QVariantMap &metadata, const QUrl &url); - static void extractMetadata(QAndroidMetaDataReaderControl *caller, const QUrl &url); - - mutable QMutex m_mtx; - QUrl m_mediaContent; - bool m_available; - QVariantMap m_metadata; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDMETADATAREADERCONTROL_H diff --git a/src/plugins/android/src/qandroidmediaserviceplugin.cpp b/src/plugins/android/src/qandroidmediaserviceplugin.cpp deleted file mode 100644 index 99af8b3d4..000000000 --- a/src/plugins/android/src/qandroidmediaserviceplugin.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidmediaserviceplugin.h" - -#include "qandroidmediaservice.h" -#include "qandroidcaptureservice.h" -#include "qandroidaudioinputselectorcontrol.h" -#include "qandroidcamerasession.h" -#include "androidmediaplayer.h" -#include "androidsurfacetexture.h" -#include "androidcamera.h" -#include "androidmultimediautils.h" -#include "androidmediarecorder.h" -#include "androidsurfaceview.h" -#include "qandroidglobal.h" - -QT_BEGIN_NAMESPACE - -Q_LOGGING_CATEGORY(qtAndroidMediaPlugin, "qt.multimedia.plugins.android") - -QAndroidMediaServicePlugin::QAndroidMediaServicePlugin() -{ -} - -QAndroidMediaServicePlugin::~QAndroidMediaServicePlugin() -{ -} - -QMediaService *QAndroidMediaServicePlugin::create(const QString &key) -{ - if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) - return new QAndroidMediaService; - - if (key == QLatin1String(Q_MEDIASERVICE_CAMERA) - || key == QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE)) { - return new QAndroidCaptureService(key); - } - - qCWarning(qtAndroidMediaPlugin) << "Android service plugin: unsupported key:" << key; - return 0; -} - -void QAndroidMediaServicePlugin::release(QMediaService *service) -{ - delete service; -} - -QByteArray QAndroidMediaServicePlugin::defaultDevice(const QByteArray &service) const -{ - if (service == Q_MEDIASERVICE_CAMERA && !QAndroidCameraSession::availableCameras().isEmpty()) - return QAndroidCameraSession::availableCameras().first().name; - - return QByteArray(); -} - -QList<QByteArray> QAndroidMediaServicePlugin::devices(const QByteArray &service) const -{ - if (service == Q_MEDIASERVICE_CAMERA) { - QList<QByteArray> devices; - const QList<AndroidCameraInfo> &cameras = QAndroidCameraSession::availableCameras(); - for (int i = 0; i < cameras.count(); ++i) - devices.append(cameras.at(i).name); - return devices; - } - - if (service == Q_MEDIASERVICE_AUDIOSOURCE) - return QAndroidAudioInputSelectorControl::availableDevices(); - - return QList<QByteArray>(); -} - -QString QAndroidMediaServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) -{ - if (service == Q_MEDIASERVICE_CAMERA) { - const QList<AndroidCameraInfo> &cameras = QAndroidCameraSession::availableCameras(); - for (int i = 0; i < cameras.count(); ++i) { - const AndroidCameraInfo &info = cameras.at(i); - if (info.name == device) - return info.description; - } - } - - if (service == Q_MEDIASERVICE_AUDIOSOURCE) - return QAndroidAudioInputSelectorControl::availableDeviceDescription(device); - - return QString(); -} - -QT_END_NAMESPACE - -Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/) -{ - static bool initialized = false; - if (initialized) - return JNI_VERSION_1_6; - initialized = true; - - QT_USE_NAMESPACE - typedef union { - JNIEnv *nativeEnvironment; - void *venv; - } UnionJNIEnvToVoid; - - UnionJNIEnvToVoid uenv; - uenv.venv = NULL; - - if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_6) != JNI_OK) - return JNI_ERR; - - JNIEnv *jniEnv = uenv.nativeEnvironment; - - if (!AndroidMediaPlayer::initJNI(jniEnv) || - !AndroidCamera::initJNI(jniEnv) || - !AndroidMediaRecorder::initJNI(jniEnv) || - !AndroidSurfaceHolder::initJNI(jniEnv)) { - return JNI_ERR; - } - - AndroidSurfaceTexture::initJNI(jniEnv); - - return JNI_VERSION_1_6; -} diff --git a/src/plugins/android/src/qandroidmediaserviceplugin.h b/src/plugins/android/src/qandroidmediaserviceplugin.h deleted file mode 100644 index 7320042d2..000000000 --- a/src/plugins/android/src/qandroidmediaserviceplugin.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDMEDIASERVICEPLUGIN_H -#define QANDROIDMEDIASERVICEPLUGIN_H - -#include <QMediaServiceProviderPlugin> - -QT_BEGIN_NAMESPACE - -class QAndroidMediaServicePlugin - : public QMediaServiceProviderPlugin - , public QMediaServiceSupportedDevicesInterface -{ - Q_OBJECT - Q_INTERFACES(QMediaServiceSupportedDevicesInterface) - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" - FILE "android_mediaservice.json") - -public: - QAndroidMediaServicePlugin(); - ~QAndroidMediaServicePlugin(); - - QMediaService* create(QString const& key) override; - void release(QMediaService *service) override; - - QByteArray defaultDevice(const QByteArray &service) const override; - QList<QByteArray> devices(const QByteArray &service) const override; - QString deviceDescription(const QByteArray &service, const QByteArray &device) override; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDMEDIASERVICEPLUGIN_H diff --git a/src/plugins/android/src/src.pro b/src/plugins/android/src/src.pro deleted file mode 100644 index 5e47a7d09..000000000 --- a/src/plugins/android/src/src.pro +++ /dev/null @@ -1,20 +0,0 @@ -TARGET = qtmedia_android - -QT += opengl multimedia-private core-private network - -HEADERS += \ - qandroidmediaserviceplugin.h - -SOURCES += \ - qandroidmediaserviceplugin.cpp - -include (wrappers/jni/jni.pri) -include (common/common.pri) -include (mediaplayer/mediaplayer.pri) -include (mediacapture/mediacapture.pri) - -OTHER_FILES += android_mediaservice.json - -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = QAndroidMediaServicePlugin -load(qt_plugin) diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp deleted file mode 100644 index 33e819d78..000000000 --- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp +++ /dev/null @@ -1,1712 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Ruslan Baratov -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidcamera.h" -#include "androidsurfacetexture.h" -#include "androidsurfaceview.h" -#include "qandroidmultimediautils.h" -#include "qandroidglobal.h" - -#include <qstringlist.h> -#include <qdebug.h> -#include <QtCore/private/qjnihelpers_p.h> -#include <QtCore/qthread.h> -#include <QtCore/qreadwritelock.h> -#include <QtCore/qmutex.h> -#include <QtMultimedia/private/qmemoryvideobuffer_p.h> - -#include <mutex> - -QT_BEGIN_NAMESPACE - -static const char QtCameraListenerClassName[] = "org/qtproject/qt/android/multimedia/QtCameraListener"; - -typedef QHash<int, AndroidCamera *> CameraMap; -Q_GLOBAL_STATIC(CameraMap, cameras) -Q_GLOBAL_STATIC(QReadWriteLock, rwLock) - -static inline bool exceptionCheckAndClear(JNIEnv *env) -{ - if (Q_UNLIKELY(env->ExceptionCheck())) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif // QT_DEBUG - env->ExceptionClear(); - return true; - } - - return false; -} - -static QRect areaToRect(jobject areaObj) -{ - QJNIObjectPrivate area(areaObj); - QJNIObjectPrivate rect = area.getObjectField("rect", "Landroid/graphics/Rect;"); - - return QRect(rect.getField<jint>("left"), - rect.getField<jint>("top"), - rect.callMethod<jint>("width"), - rect.callMethod<jint>("height")); -} - -static QJNIObjectPrivate rectToArea(const QRect &rect) -{ - QJNIObjectPrivate jrect("android/graphics/Rect", - "(IIII)V", - rect.left(), rect.top(), rect.right(), rect.bottom()); - - QJNIObjectPrivate area("android/hardware/Camera$Area", - "(Landroid/graphics/Rect;I)V", - jrect.object(), 500); - - return area; -} - -// native method for QtCameraLisener.java -static void notifyAutoFocusComplete(JNIEnv* , jobject, int id, jboolean success) -{ - QReadLocker locker(rwLock); - const auto it = cameras->constFind(id); - if (Q_UNLIKELY(it == cameras->cend())) - return; - - Q_EMIT (*it)->autoFocusComplete(success); -} - -static void notifyPictureExposed(JNIEnv* , jobject, int id) -{ - QReadLocker locker(rwLock); - const auto it = cameras->constFind(id); - if (Q_UNLIKELY(it == cameras->cend())) - return; - - Q_EMIT (*it)->pictureExposed(); -} - -static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data) -{ - QReadLocker locker(rwLock); - const auto it = cameras->constFind(id); - if (Q_UNLIKELY(it == cameras->cend())) - return; - - const int arrayLength = env->GetArrayLength(data); - QByteArray bytes(arrayLength, Qt::Uninitialized); - env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data()); - Q_EMIT (*it)->pictureCaptured(bytes); -} - -static void notifyNewPreviewFrame(JNIEnv *env, jobject, int id, jbyteArray data, - int width, int height, int format, int bpl) -{ - QReadLocker locker(rwLock); - const auto it = cameras->constFind(id); - if (Q_UNLIKELY(it == cameras->cend())) - return; - - const int arrayLength = env->GetArrayLength(data); - if (arrayLength == 0) - return; - - QByteArray bytes(arrayLength, Qt::Uninitialized); - env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data()); - - QVideoFrame frame(new QMemoryVideoBuffer(bytes, bpl), - QSize(width, height), - qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat(format))); - - Q_EMIT (*it)->newPreviewFrame(frame); -} - -static void notifyFrameAvailable(JNIEnv *, jobject, int id) -{ - QReadLocker locker(rwLock); - const auto it = cameras->constFind(id); - if (Q_UNLIKELY(it == cameras->cend())) - return; - - (*it)->fetchLastPreviewFrame(); -} - -class AndroidCameraPrivate : public QObject -{ - Q_OBJECT -public: - AndroidCameraPrivate(); - ~AndroidCameraPrivate(); - - Q_INVOKABLE bool init(int cameraId); - - Q_INVOKABLE void release(); - Q_INVOKABLE bool lock(); - Q_INVOKABLE bool unlock(); - Q_INVOKABLE bool reconnect(); - - Q_INVOKABLE AndroidCamera::CameraFacing getFacing(); - Q_INVOKABLE int getNativeOrientation(); - - Q_INVOKABLE QSize getPreferredPreviewSizeForVideo(); - Q_INVOKABLE QList<QSize> getSupportedPreviewSizes(); - - Q_INVOKABLE QList<AndroidCamera::FpsRange> getSupportedPreviewFpsRange(); - - Q_INVOKABLE AndroidCamera::FpsRange getPreviewFpsRange(); - Q_INVOKABLE void setPreviewFpsRange(int min, int max); - - Q_INVOKABLE AndroidCamera::ImageFormat getPreviewFormat(); - Q_INVOKABLE void setPreviewFormat(AndroidCamera::ImageFormat fmt); - Q_INVOKABLE QList<AndroidCamera::ImageFormat> getSupportedPreviewFormats(); - - Q_INVOKABLE QSize previewSize() const { return m_previewSize; } - Q_INVOKABLE QSize getPreviewSize(); - Q_INVOKABLE void updatePreviewSize(); - Q_INVOKABLE bool setPreviewTexture(void *surfaceTexture); - Q_INVOKABLE bool setPreviewDisplay(void *surfaceHolder); - Q_INVOKABLE void setDisplayOrientation(int degrees); - - Q_INVOKABLE bool isZoomSupported(); - Q_INVOKABLE int getMaxZoom(); - Q_INVOKABLE QList<int> getZoomRatios(); - Q_INVOKABLE int getZoom(); - Q_INVOKABLE void setZoom(int value); - - Q_INVOKABLE QString getFlashMode(); - Q_INVOKABLE void setFlashMode(const QString &value); - - Q_INVOKABLE QString getFocusMode(); - Q_INVOKABLE void setFocusMode(const QString &value); - - Q_INVOKABLE int getMaxNumFocusAreas(); - Q_INVOKABLE QList<QRect> getFocusAreas(); - Q_INVOKABLE void setFocusAreas(const QList<QRect> &areas); - - Q_INVOKABLE void autoFocus(); - Q_INVOKABLE void cancelAutoFocus(); - - Q_INVOKABLE bool isAutoExposureLockSupported(); - Q_INVOKABLE bool getAutoExposureLock(); - Q_INVOKABLE void setAutoExposureLock(bool toggle); - - Q_INVOKABLE bool isAutoWhiteBalanceLockSupported(); - Q_INVOKABLE bool getAutoWhiteBalanceLock(); - Q_INVOKABLE void setAutoWhiteBalanceLock(bool toggle); - - Q_INVOKABLE int getExposureCompensation(); - Q_INVOKABLE void setExposureCompensation(int value); - Q_INVOKABLE float getExposureCompensationStep(); - Q_INVOKABLE int getMinExposureCompensation(); - Q_INVOKABLE int getMaxExposureCompensation(); - - Q_INVOKABLE QString getSceneMode(); - Q_INVOKABLE void setSceneMode(const QString &value); - - Q_INVOKABLE QString getWhiteBalance(); - Q_INVOKABLE void setWhiteBalance(const QString &value); - - Q_INVOKABLE void updateRotation(); - - Q_INVOKABLE QList<QSize> getSupportedPictureSizes(); - Q_INVOKABLE void setPictureSize(const QSize &size); - Q_INVOKABLE void setJpegQuality(int quality); - - Q_INVOKABLE void startPreview(); - Q_INVOKABLE void stopPreview(); - - Q_INVOKABLE void takePicture(); - - Q_INVOKABLE void setupPreviewFrameCallback(); - Q_INVOKABLE void notifyNewFrames(bool notify); - Q_INVOKABLE void fetchLastPreviewFrame(); - - Q_INVOKABLE void applyParameters(); - - Q_INVOKABLE QStringList callParametersStringListMethod(const QByteArray &methodName); - - int m_cameraId; - QRecursiveMutex m_parametersMutex; - QSize m_previewSize; - int m_rotation; - QJNIObjectPrivate m_info; - QJNIObjectPrivate m_parameters; - QJNIObjectPrivate m_camera; - QJNIObjectPrivate m_cameraListener; - -Q_SIGNALS: - void previewSizeChanged(); - void previewStarted(); - void previewFailedToStart(); - void previewStopped(); - - void autoFocusStarted(); - - void whiteBalanceChanged(); - - void takePictureFailed(); - - void lastPreviewFrameFetched(const QVideoFrame &frame); -}; - -AndroidCamera::AndroidCamera(AndroidCameraPrivate *d, QThread *worker) - : QObject(), - d_ptr(d), - m_worker(worker) - -{ - qRegisterMetaType<QList<int> >(); - qRegisterMetaType<QList<QSize> >(); - qRegisterMetaType<QList<QRect> >(); - qRegisterMetaType<ImageFormat>(); - - connect(d, &AndroidCameraPrivate::previewSizeChanged, this, &AndroidCamera::previewSizeChanged); - connect(d, &AndroidCameraPrivate::previewStarted, this, &AndroidCamera::previewStarted); - connect(d, &AndroidCameraPrivate::previewFailedToStart, this, &AndroidCamera::previewFailedToStart); - connect(d, &AndroidCameraPrivate::previewStopped, this, &AndroidCamera::previewStopped); - connect(d, &AndroidCameraPrivate::autoFocusStarted, this, &AndroidCamera::autoFocusStarted); - connect(d, &AndroidCameraPrivate::whiteBalanceChanged, this, &AndroidCamera::whiteBalanceChanged); - connect(d, &AndroidCameraPrivate::takePictureFailed, this, &AndroidCamera::takePictureFailed); - connect(d, &AndroidCameraPrivate::lastPreviewFrameFetched, this, &AndroidCamera::lastPreviewFrameFetched); -} - -AndroidCamera::~AndroidCamera() -{ - Q_D(AndroidCamera); - if (d->m_camera.isValid()) { - release(); - QWriteLocker locker(rwLock); - cameras->remove(cameraId()); - } - - m_worker->exit(); - m_worker->wait(5000); -} - -AndroidCamera *AndroidCamera::open(int cameraId) -{ - if (!qt_androidRequestCameraPermission()) - return nullptr; - - AndroidCameraPrivate *d = new AndroidCameraPrivate(); - QThread *worker = new QThread; - worker->start(); - d->moveToThread(worker); - connect(worker, &QThread::finished, d, &AndroidCameraPrivate::deleteLater); - bool ok = true; - QMetaObject::invokeMethod(d, "init", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok), Q_ARG(int, cameraId)); - if (!ok) { - worker->quit(); - worker->wait(5000); - delete worker; - return 0; - } - - AndroidCamera *q = new AndroidCamera(d, worker); - QWriteLocker locker(rwLock); - cameras->insert(cameraId, q); - - return q; -} - -int AndroidCamera::cameraId() const -{ - Q_D(const AndroidCamera); - return d->m_cameraId; -} - -bool AndroidCamera::lock() -{ - Q_D(AndroidCamera); - bool ok = true; - QMetaObject::invokeMethod(d, "lock", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok)); - return ok; -} - -bool AndroidCamera::unlock() -{ - Q_D(AndroidCamera); - bool ok = true; - QMetaObject::invokeMethod(d, "unlock", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok)); - return ok; -} - -bool AndroidCamera::reconnect() -{ - Q_D(AndroidCamera); - bool ok = true; - QMetaObject::invokeMethod(d, "reconnect", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok)); - return ok; -} - -void AndroidCamera::release() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "release", Qt::BlockingQueuedConnection); -} - -AndroidCamera::CameraFacing AndroidCamera::getFacing() -{ - Q_D(AndroidCamera); - return d->getFacing(); -} - -int AndroidCamera::getNativeOrientation() -{ - Q_D(AndroidCamera); - return d->getNativeOrientation(); -} - -QSize AndroidCamera::getPreferredPreviewSizeForVideo() -{ - Q_D(AndroidCamera); - return d->getPreferredPreviewSizeForVideo(); -} - -QList<QSize> AndroidCamera::getSupportedPreviewSizes() -{ - Q_D(AndroidCamera); - return d->getSupportedPreviewSizes(); -} - -QList<AndroidCamera::FpsRange> AndroidCamera::getSupportedPreviewFpsRange() -{ - Q_D(AndroidCamera); - return d->getSupportedPreviewFpsRange(); -} - -AndroidCamera::FpsRange AndroidCamera::getPreviewFpsRange() -{ - Q_D(AndroidCamera); - return d->getPreviewFpsRange(); -} - -void AndroidCamera::setPreviewFpsRange(FpsRange range) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setPreviewFpsRange", Q_ARG(int, range.min), Q_ARG(int, range.max)); -} - -AndroidCamera::ImageFormat AndroidCamera::getPreviewFormat() -{ - Q_D(AndroidCamera); - return d->getPreviewFormat(); -} - -void AndroidCamera::setPreviewFormat(ImageFormat fmt) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setPreviewFormat", Q_ARG(AndroidCamera::ImageFormat, fmt)); -} - -QList<AndroidCamera::ImageFormat> AndroidCamera::getSupportedPreviewFormats() -{ - Q_D(AndroidCamera); - return d->getSupportedPreviewFormats(); -} - -QSize AndroidCamera::previewSize() const -{ - Q_D(const AndroidCamera); - return d->m_previewSize; -} - -QSize AndroidCamera::actualPreviewSize() -{ - Q_D(AndroidCamera); - return d->getPreviewSize(); -} - -void AndroidCamera::setPreviewSize(const QSize &size) -{ - Q_D(AndroidCamera); - d->m_parametersMutex.lock(); - bool areParametersValid = d->m_parameters.isValid(); - d->m_parametersMutex.unlock(); - if (!areParametersValid) - return; - - d->m_previewSize = size; - QMetaObject::invokeMethod(d, "updatePreviewSize"); -} - -bool AndroidCamera::setPreviewTexture(AndroidSurfaceTexture *surfaceTexture) -{ - Q_D(AndroidCamera); - bool ok = true; - QMetaObject::invokeMethod(d, - "setPreviewTexture", - Qt::BlockingQueuedConnection, - Q_RETURN_ARG(bool, ok), - Q_ARG(void *, surfaceTexture ? surfaceTexture->surfaceTexture() : 0)); - return ok; -} - -bool AndroidCamera::setPreviewDisplay(AndroidSurfaceHolder *surfaceHolder) -{ - Q_D(AndroidCamera); - bool ok = true; - QMetaObject::invokeMethod(d, - "setPreviewDisplay", - Qt::BlockingQueuedConnection, - Q_RETURN_ARG(bool, ok), - Q_ARG(void *, surfaceHolder ? surfaceHolder->surfaceHolder() : 0)); - return ok; -} - -void AndroidCamera::setDisplayOrientation(int degrees) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setDisplayOrientation", Qt::QueuedConnection, Q_ARG(int, degrees)); -} - -bool AndroidCamera::isZoomSupported() -{ - Q_D(AndroidCamera); - return d->isZoomSupported(); -} - -int AndroidCamera::getMaxZoom() -{ - Q_D(AndroidCamera); - return d->getMaxZoom(); -} - -QList<int> AndroidCamera::getZoomRatios() -{ - Q_D(AndroidCamera); - return d->getZoomRatios(); -} - -int AndroidCamera::getZoom() -{ - Q_D(AndroidCamera); - return d->getZoom(); -} - -void AndroidCamera::setZoom(int value) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setZoom", Q_ARG(int, value)); -} - -QStringList AndroidCamera::getSupportedFlashModes() -{ - Q_D(AndroidCamera); - return d->callParametersStringListMethod("getSupportedFlashModes"); -} - -QString AndroidCamera::getFlashMode() -{ - Q_D(AndroidCamera); - return d->getFlashMode(); -} - -void AndroidCamera::setFlashMode(const QString &value) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setFlashMode", Q_ARG(QString, value)); -} - -QStringList AndroidCamera::getSupportedFocusModes() -{ - Q_D(AndroidCamera); - return d->callParametersStringListMethod("getSupportedFocusModes"); -} - -QString AndroidCamera::getFocusMode() -{ - Q_D(AndroidCamera); - return d->getFocusMode(); -} - -void AndroidCamera::setFocusMode(const QString &value) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setFocusMode", Q_ARG(QString, value)); -} - -int AndroidCamera::getMaxNumFocusAreas() -{ - Q_D(AndroidCamera); - return d->getMaxNumFocusAreas(); -} - -QList<QRect> AndroidCamera::getFocusAreas() -{ - Q_D(AndroidCamera); - return d->getFocusAreas(); -} - -void AndroidCamera::setFocusAreas(const QList<QRect> &areas) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setFocusAreas", Q_ARG(QList<QRect>, areas)); -} - -void AndroidCamera::autoFocus() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "autoFocus"); -} - -void AndroidCamera::cancelAutoFocus() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "cancelAutoFocus", Qt::QueuedConnection); -} - -bool AndroidCamera::isAutoExposureLockSupported() -{ - Q_D(AndroidCamera); - return d->isAutoExposureLockSupported(); -} - -bool AndroidCamera::getAutoExposureLock() -{ - Q_D(AndroidCamera); - return d->getAutoExposureLock(); -} - -void AndroidCamera::setAutoExposureLock(bool toggle) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setAutoExposureLock", Q_ARG(bool, toggle)); -} - -bool AndroidCamera::isAutoWhiteBalanceLockSupported() -{ - Q_D(AndroidCamera); - return d->isAutoWhiteBalanceLockSupported(); -} - -bool AndroidCamera::getAutoWhiteBalanceLock() -{ - Q_D(AndroidCamera); - return d->getAutoWhiteBalanceLock(); -} - -void AndroidCamera::setAutoWhiteBalanceLock(bool toggle) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setAutoWhiteBalanceLock", Q_ARG(bool, toggle)); -} - -int AndroidCamera::getExposureCompensation() -{ - Q_D(AndroidCamera); - return d->getExposureCompensation(); -} - -void AndroidCamera::setExposureCompensation(int value) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setExposureCompensation", Q_ARG(int, value)); -} - -float AndroidCamera::getExposureCompensationStep() -{ - Q_D(AndroidCamera); - return d->getExposureCompensationStep(); -} - -int AndroidCamera::getMinExposureCompensation() -{ - Q_D(AndroidCamera); - return d->getMinExposureCompensation(); -} - -int AndroidCamera::getMaxExposureCompensation() -{ - Q_D(AndroidCamera); - return d->getMaxExposureCompensation(); -} - -QStringList AndroidCamera::getSupportedSceneModes() -{ - Q_D(AndroidCamera); - return d->callParametersStringListMethod("getSupportedSceneModes"); -} - -QString AndroidCamera::getSceneMode() -{ - Q_D(AndroidCamera); - return d->getSceneMode(); -} - -void AndroidCamera::setSceneMode(const QString &value) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setSceneMode", Q_ARG(QString, value)); -} - -QStringList AndroidCamera::getSupportedWhiteBalance() -{ - Q_D(AndroidCamera); - return d->callParametersStringListMethod("getSupportedWhiteBalance"); -} - -QString AndroidCamera::getWhiteBalance() -{ - Q_D(AndroidCamera); - return d->getWhiteBalance(); -} - -void AndroidCamera::setWhiteBalance(const QString &value) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setWhiteBalance", Q_ARG(QString, value)); -} - -void AndroidCamera::setRotation(int rotation) -{ - Q_D(AndroidCamera); - //We need to do it here and not in worker class because we cache rotation - d->m_parametersMutex.lock(); - bool areParametersValid = d->m_parameters.isValid(); - d->m_parametersMutex.unlock(); - if (!areParametersValid) - return; - - d->m_rotation = rotation; - QMetaObject::invokeMethod(d, "updateRotation"); -} - -int AndroidCamera::getRotation() const -{ - Q_D(const AndroidCamera); - return d->m_rotation; -} - -QList<QSize> AndroidCamera::getSupportedPictureSizes() -{ - Q_D(AndroidCamera); - return d->getSupportedPictureSizes(); -} - -void AndroidCamera::setPictureSize(const QSize &size) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setPictureSize", Q_ARG(QSize, size)); -} - -void AndroidCamera::setJpegQuality(int quality) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setJpegQuality", Q_ARG(int, quality)); -} - -void AndroidCamera::takePicture() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "takePicture", Qt::BlockingQueuedConnection); -} - -void AndroidCamera::setupPreviewFrameCallback() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setupPreviewFrameCallback"); -} - -void AndroidCamera::notifyNewFrames(bool notify) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "notifyNewFrames", Q_ARG(bool, notify)); -} - -void AndroidCamera::fetchLastPreviewFrame() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "fetchLastPreviewFrame"); -} - -QJNIObjectPrivate AndroidCamera::getCameraObject() -{ - Q_D(AndroidCamera); - return d->m_camera; -} - -int AndroidCamera::getNumberOfCameras() -{ - if (!qt_androidRequestCameraPermission()) - return 0; - - return QJNIObjectPrivate::callStaticMethod<jint>("android/hardware/Camera", - "getNumberOfCameras"); -} - -void AndroidCamera::getCameraInfo(int id, AndroidCameraInfo *info) -{ - Q_ASSERT(info); - - QJNIObjectPrivate cameraInfo("android/hardware/Camera$CameraInfo"); - QJNIObjectPrivate::callStaticMethod<void>("android/hardware/Camera", - "getCameraInfo", - "(ILandroid/hardware/Camera$CameraInfo;)V", - id, cameraInfo.object()); - - AndroidCamera::CameraFacing facing = AndroidCamera::CameraFacing(cameraInfo.getField<jint>("facing")); - // The orientation provided by Android is counter-clockwise, we need it clockwise - info->orientation = (360 - cameraInfo.getField<jint>("orientation")) % 360; - - switch (facing) { - case AndroidCamera::CameraFacingBack: - info->name = QByteArray("back"); - info->description = QStringLiteral("Rear-facing camera"); - info->position = QCamera::BackFace; - break; - case AndroidCamera::CameraFacingFront: - info->name = QByteArray("front"); - info->description = QStringLiteral("Front-facing camera"); - info->position = QCamera::FrontFace; - break; - default: - break; - } -} - -void AndroidCamera::startPreview() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "startPreview"); -} - -void AndroidCamera::stopPreview() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "stopPreview"); -} - -void AndroidCamera::stopPreviewSynchronous() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "stopPreview", Qt::BlockingQueuedConnection); -} - -AndroidCameraPrivate::AndroidCameraPrivate() - : QObject() -{ -} - -AndroidCameraPrivate::~AndroidCameraPrivate() -{ -} - -static qint32 s_activeCameras = 0; - -bool AndroidCameraPrivate::init(int cameraId) -{ - m_cameraId = cameraId; - QJNIEnvironmentPrivate env; - - const bool opened = s_activeCameras & (1 << cameraId); - if (opened) - return false; - - m_camera = QJNIObjectPrivate::callStaticObjectMethod("android/hardware/Camera", - "open", - "(I)Landroid/hardware/Camera;", - cameraId); - if (exceptionCheckAndClear(env) || !m_camera.isValid()) - return false; - - m_cameraListener = QJNIObjectPrivate(QtCameraListenerClassName, "(I)V", m_cameraId); - m_info = QJNIObjectPrivate("android/hardware/Camera$CameraInfo"); - m_camera.callStaticMethod<void>("android/hardware/Camera", - "getCameraInfo", - "(ILandroid/hardware/Camera$CameraInfo;)V", - cameraId, - m_info.object()); - - QJNIObjectPrivate params = m_camera.callObjectMethod("getParameters", - "()Landroid/hardware/Camera$Parameters;"); - m_parameters = QJNIObjectPrivate(params); - s_activeCameras |= 1 << cameraId; - - return true; -} - -void AndroidCameraPrivate::release() -{ - m_previewSize = QSize(); - m_parametersMutex.lock(); - m_parameters = QJNIObjectPrivate(); - m_parametersMutex.unlock(); - if (m_camera.isValid()) { - m_camera.callMethod<void>("release"); - s_activeCameras &= ~(1 << m_cameraId); - } -} - -bool AndroidCameraPrivate::lock() -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("lock"); - return !exceptionCheckAndClear(env); -} - -bool AndroidCameraPrivate::unlock() -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("unlock"); - return !exceptionCheckAndClear(env); -} - -bool AndroidCameraPrivate::reconnect() -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("reconnect"); - return !exceptionCheckAndClear(env); -} - -AndroidCamera::CameraFacing AndroidCameraPrivate::getFacing() -{ - return AndroidCamera::CameraFacing(m_info.getField<jint>("facing")); -} - -int AndroidCameraPrivate::getNativeOrientation() -{ - return m_info.getField<jint>("orientation"); -} - -QSize AndroidCameraPrivate::getPreferredPreviewSizeForVideo() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return QSize(); - - QJNIObjectPrivate size = m_parameters.callObjectMethod("getPreferredPreviewSizeForVideo", - "()Landroid/hardware/Camera$Size;"); - - if (!size.isValid()) - return QSize(); - - return QSize(size.getField<jint>("width"), size.getField<jint>("height")); -} - -QList<QSize> AndroidCameraPrivate::getSupportedPreviewSizes() -{ - QList<QSize> list; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (m_parameters.isValid()) { - QJNIObjectPrivate sizeList = m_parameters.callObjectMethod("getSupportedPreviewSizes", - "()Ljava/util/List;"); - int count = sizeList.callMethod<jint>("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate size = sizeList.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - list.append(QSize(size.getField<jint>("width"), size.getField<jint>("height"))); - } - - std::sort(list.begin(), list.end(), qt_sizeLessThan); - } - - return list; -} - -QList<AndroidCamera::FpsRange> AndroidCameraPrivate::getSupportedPreviewFpsRange() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QJNIEnvironmentPrivate env; - - QList<AndroidCamera::FpsRange> rangeList; - - if (m_parameters.isValid()) { - QJNIObjectPrivate rangeListNative = m_parameters.callObjectMethod("getSupportedPreviewFpsRange", - "()Ljava/util/List;"); - int count = rangeListNative.callMethod<jint>("size"); - - rangeList.reserve(count); - - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate range = rangeListNative.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - - jintArray jRange = static_cast<jintArray>(range.object()); - jint* rangeArray = env->GetIntArrayElements(jRange, 0); - - AndroidCamera::FpsRange fpsRange; - - fpsRange.min = rangeArray[0]; - fpsRange.max = rangeArray[1]; - - env->ReleaseIntArrayElements(jRange, rangeArray, 0); - - rangeList << fpsRange; - } - } - - return rangeList; -} - -AndroidCamera::FpsRange AndroidCameraPrivate::getPreviewFpsRange() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QJNIEnvironmentPrivate env; - - AndroidCamera::FpsRange range; - - if (!m_parameters.isValid()) - return range; - - jintArray jRangeArray = env->NewIntArray(2); - m_parameters.callMethod<void>("getPreviewFpsRange", "([I)V", jRangeArray); - - jint* jRangeElements = env->GetIntArrayElements(jRangeArray, 0); - - range.min = jRangeElements[0]; - range.max = jRangeElements[1]; - - env->ReleaseIntArrayElements(jRangeArray, jRangeElements, 0); - env->DeleteLocalRef(jRangeArray); - - return range; -} - -void AndroidCameraPrivate::setPreviewFpsRange(int min, int max) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - QJNIEnvironmentPrivate env; - m_parameters.callMethod<void>("setPreviewFpsRange", "(II)V", min, max); - exceptionCheckAndClear(env); -} - -AndroidCamera::ImageFormat AndroidCameraPrivate::getPreviewFormat() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return AndroidCamera::UnknownImageFormat; - - return AndroidCamera::ImageFormat(m_parameters.callMethod<jint>("getPreviewFormat")); -} - -void AndroidCameraPrivate::setPreviewFormat(AndroidCamera::ImageFormat fmt) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setPreviewFormat", "(I)V", jint(fmt)); - applyParameters(); -} - -QList<AndroidCamera::ImageFormat> AndroidCameraPrivate::getSupportedPreviewFormats() -{ - QList<AndroidCamera::ImageFormat> list; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (m_parameters.isValid()) { - QJNIObjectPrivate formatList = m_parameters.callObjectMethod("getSupportedPreviewFormats", - "()Ljava/util/List;"); - int count = formatList.callMethod<jint>("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate format = formatList.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - list.append(AndroidCamera::ImageFormat(format.callMethod<jint>("intValue"))); - } - } - - return list; -} - -QSize AndroidCameraPrivate::getPreviewSize() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return QSize(); - - QJNIObjectPrivate size = m_parameters.callObjectMethod("getPreviewSize", - "()Landroid/hardware/Camera$Size;"); - - if (!size.isValid()) - return QSize(); - - return QSize(size.getField<jint>("width"), size.getField<jint>("height")); -} - -void AndroidCameraPrivate::updatePreviewSize() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (m_previewSize.isValid()) { - m_parameters.callMethod<void>("setPreviewSize", "(II)V", m_previewSize.width(), m_previewSize.height()); - applyParameters(); - } - - emit previewSizeChanged(); -} - -bool AndroidCameraPrivate::setPreviewTexture(void *surfaceTexture) -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("setPreviewTexture", - "(Landroid/graphics/SurfaceTexture;)V", - static_cast<jobject>(surfaceTexture)); - return !exceptionCheckAndClear(env); -} - -bool AndroidCameraPrivate::setPreviewDisplay(void *surfaceHolder) -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("setPreviewDisplay", - "(Landroid/view/SurfaceHolder;)V", - static_cast<jobject>(surfaceHolder)); - return !exceptionCheckAndClear(env); -} - -void AndroidCameraPrivate::setDisplayOrientation(int degrees) -{ - m_camera.callMethod<void>("setDisplayOrientation", "(I)V", degrees); -} - -bool AndroidCameraPrivate::isZoomSupported() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod<jboolean>("isZoomSupported"); -} - -int AndroidCameraPrivate::getMaxZoom() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jint>("getMaxZoom"); -} - -QList<int> AndroidCameraPrivate::getZoomRatios() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QList<int> ratios; - - if (m_parameters.isValid()) { - QJNIObjectPrivate ratioList = m_parameters.callObjectMethod("getZoomRatios", - "()Ljava/util/List;"); - int count = ratioList.callMethod<jint>("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate zoomRatio = ratioList.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - - ratios.append(zoomRatio.callMethod<jint>("intValue")); - } - } - - return ratios; -} - -int AndroidCameraPrivate::getZoom() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jint>("getZoom"); -} - -void AndroidCameraPrivate::setZoom(int value) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setZoom", "(I)V", value); - applyParameters(); -} - -QString AndroidCameraPrivate::getFlashMode() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QString value; - - if (m_parameters.isValid()) { - QJNIObjectPrivate flashMode = m_parameters.callObjectMethod("getFlashMode", - "()Ljava/lang/String;"); - if (flashMode.isValid()) - value = flashMode.toString(); - } - - return value; -} - -void AndroidCameraPrivate::setFlashMode(const QString &value) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setFlashMode", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(value).object()); - applyParameters(); -} - -QString AndroidCameraPrivate::getFocusMode() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QString value; - - if (m_parameters.isValid()) { - QJNIObjectPrivate focusMode = m_parameters.callObjectMethod("getFocusMode", - "()Ljava/lang/String;"); - if (focusMode.isValid()) - value = focusMode.toString(); - } - - return value; -} - -void AndroidCameraPrivate::setFocusMode(const QString &value) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setFocusMode", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(value).object()); - applyParameters(); -} - -int AndroidCameraPrivate::getMaxNumFocusAreas() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return 0; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jint>("getMaxNumFocusAreas"); -} - -QList<QRect> AndroidCameraPrivate::getFocusAreas() -{ - QList<QRect> areas; - - if (QtAndroidPrivate::androidSdkVersion() < 14) - return areas; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (m_parameters.isValid()) { - QJNIObjectPrivate list = m_parameters.callObjectMethod("getFocusAreas", - "()Ljava/util/List;"); - - if (list.isValid()) { - int count = list.callMethod<jint>("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate area = list.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - - areas.append(areaToRect(area.object())); - } - } - } - - return areas; -} - -void AndroidCameraPrivate::setFocusAreas(const QList<QRect> &areas) -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - QJNIObjectPrivate list; - - if (!areas.isEmpty()) { - QJNIEnvironmentPrivate env; - QJNIObjectPrivate arrayList("java/util/ArrayList", "(I)V", areas.size()); - for (int i = 0; i < areas.size(); ++i) { - arrayList.callMethod<jboolean>("add", - "(Ljava/lang/Object;)Z", - rectToArea(areas.at(i)).object()); - exceptionCheckAndClear(env); - } - list = arrayList; - } - - m_parameters.callMethod<void>("setFocusAreas", "(Ljava/util/List;)V", list.object()); - - applyParameters(); -} - -void AndroidCameraPrivate::autoFocus() -{ - QJNIEnvironmentPrivate env; - - m_camera.callMethod<void>("autoFocus", - "(Landroid/hardware/Camera$AutoFocusCallback;)V", - m_cameraListener.object()); - - if (!exceptionCheckAndClear(env)) - emit autoFocusStarted(); -} - -void AndroidCameraPrivate::cancelAutoFocus() -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("cancelAutoFocus"); - exceptionCheckAndClear(env); -} - -bool AndroidCameraPrivate::isAutoExposureLockSupported() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return false; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod<jboolean>("isAutoExposureLockSupported"); -} - -bool AndroidCameraPrivate::getAutoExposureLock() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return false; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod<jboolean>("getAutoExposureLock"); -} - -void AndroidCameraPrivate::setAutoExposureLock(bool toggle) -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setAutoExposureLock", "(Z)V", toggle); - applyParameters(); -} - -bool AndroidCameraPrivate::isAutoWhiteBalanceLockSupported() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return false; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod<jboolean>("isAutoWhiteBalanceLockSupported"); -} - -bool AndroidCameraPrivate::getAutoWhiteBalanceLock() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return false; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod<jboolean>("getAutoWhiteBalanceLock"); -} - -void AndroidCameraPrivate::setAutoWhiteBalanceLock(bool toggle) -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setAutoWhiteBalanceLock", "(Z)V", toggle); - applyParameters(); -} - -int AndroidCameraPrivate::getExposureCompensation() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jint>("getExposureCompensation"); -} - -void AndroidCameraPrivate::setExposureCompensation(int value) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setExposureCompensation", "(I)V", value); - applyParameters(); -} - -float AndroidCameraPrivate::getExposureCompensationStep() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jfloat>("getExposureCompensationStep"); -} - -int AndroidCameraPrivate::getMinExposureCompensation() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jint>("getMinExposureCompensation"); -} - -int AndroidCameraPrivate::getMaxExposureCompensation() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jint>("getMaxExposureCompensation"); -} - -QString AndroidCameraPrivate::getSceneMode() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QString value; - - if (m_parameters.isValid()) { - QJNIObjectPrivate sceneMode = m_parameters.callObjectMethod("getSceneMode", - "()Ljava/lang/String;"); - if (sceneMode.isValid()) - value = sceneMode.toString(); - } - - return value; -} - -void AndroidCameraPrivate::setSceneMode(const QString &value) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setSceneMode", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(value).object()); - applyParameters(); -} - -QString AndroidCameraPrivate::getWhiteBalance() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QString value; - - if (m_parameters.isValid()) { - QJNIObjectPrivate wb = m_parameters.callObjectMethod("getWhiteBalance", - "()Ljava/lang/String;"); - if (wb.isValid()) - value = wb.toString(); - } - - return value; -} - -void AndroidCameraPrivate::setWhiteBalance(const QString &value) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setWhiteBalance", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(value).object()); - applyParameters(); - - emit whiteBalanceChanged(); -} - -void AndroidCameraPrivate::updateRotation() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - m_parameters.callMethod<void>("setRotation", "(I)V", m_rotation); - applyParameters(); -} - -QList<QSize> AndroidCameraPrivate::getSupportedPictureSizes() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QList<QSize> list; - - if (m_parameters.isValid()) { - QJNIObjectPrivate sizeList = m_parameters.callObjectMethod("getSupportedPictureSizes", - "()Ljava/util/List;"); - int count = sizeList.callMethod<jint>("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate size = sizeList.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - list.append(QSize(size.getField<jint>("width"), size.getField<jint>("height"))); - } - - std::sort(list.begin(), list.end(), qt_sizeLessThan); - } - - return list; -} - -void AndroidCameraPrivate::setPictureSize(const QSize &size) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setPictureSize", "(II)V", size.width(), size.height()); - applyParameters(); -} - -void AndroidCameraPrivate::setJpegQuality(int quality) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setJpegQuality", "(I)V", quality); - applyParameters(); -} - -void AndroidCameraPrivate::startPreview() -{ - QJNIEnvironmentPrivate env; - - setupPreviewFrameCallback(); - m_camera.callMethod<void>("startPreview"); - - if (exceptionCheckAndClear(env)) - emit previewFailedToStart(); - else - emit previewStarted(); -} - -void AndroidCameraPrivate::stopPreview() -{ - QJNIEnvironmentPrivate env; - - // cancel any pending new frame notification - m_cameraListener.callMethod<void>("notifyWhenFrameAvailable", "(Z)V", false); - - m_camera.callMethod<void>("stopPreview"); - - exceptionCheckAndClear(env); - emit previewStopped(); -} - -void AndroidCameraPrivate::takePicture() -{ - QJNIEnvironmentPrivate env; - - // We must clear the preview callback before calling takePicture(), otherwise the call will - // block and the camera server will be frozen until the next device restart... - // That problem only happens on some devices and on the emulator - m_cameraListener.callMethod<void>("clearPreviewCallback", "(Landroid/hardware/Camera;)V", m_camera.object()); - - m_camera.callMethod<void>("takePicture", "(Landroid/hardware/Camera$ShutterCallback;" - "Landroid/hardware/Camera$PictureCallback;" - "Landroid/hardware/Camera$PictureCallback;)V", - m_cameraListener.object(), - jobject(0), - m_cameraListener.object()); - - if (exceptionCheckAndClear(env)) - emit takePictureFailed(); -} - -void AndroidCameraPrivate::setupPreviewFrameCallback() -{ - m_cameraListener.callMethod<void>("setupPreviewCallback", "(Landroid/hardware/Camera;)V", m_camera.object()); -} - -void AndroidCameraPrivate::notifyNewFrames(bool notify) -{ - m_cameraListener.callMethod<void>("notifyNewFrames", "(Z)V", notify); -} - -void AndroidCameraPrivate::fetchLastPreviewFrame() -{ - QJNIEnvironmentPrivate env; - QJNIObjectPrivate data = m_cameraListener.callObjectMethod("lastPreviewBuffer", "()[B"); - - if (!data.isValid()) { - // If there's no buffer received yet, retry when the next one arrives - m_cameraListener.callMethod<void>("notifyWhenFrameAvailable", "(Z)V", true); - return; - } - - const int arrayLength = env->GetArrayLength(static_cast<jbyteArray>(data.object())); - if (arrayLength == 0) - return; - - QByteArray bytes(arrayLength, Qt::Uninitialized); - env->GetByteArrayRegion(static_cast<jbyteArray>(data.object()), - 0, - arrayLength, - reinterpret_cast<jbyte *>(bytes.data())); - - const int width = m_cameraListener.callMethod<jint>("previewWidth"); - const int height = m_cameraListener.callMethod<jint>("previewHeight"); - const int format = m_cameraListener.callMethod<jint>("previewFormat"); - const int bpl = m_cameraListener.callMethod<jint>("previewBytesPerLine"); - - QVideoFrame frame(new QMemoryVideoBuffer(bytes, bpl), - QSize(width, height), - qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat(format))); - - emit lastPreviewFrameFetched(frame); -} - -void AndroidCameraPrivate::applyParameters() -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("setParameters", - "(Landroid/hardware/Camera$Parameters;)V", - m_parameters.object()); - exceptionCheckAndClear(env); -} - -QStringList AndroidCameraPrivate::callParametersStringListMethod(const QByteArray &methodName) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QStringList stringList; - - if (m_parameters.isValid()) { - QJNIObjectPrivate list = m_parameters.callObjectMethod(methodName.constData(), - "()Ljava/util/List;"); - - if (list.isValid()) { - int count = list.callMethod<jint>("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate string = list.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - stringList.append(string.toString()); - } - } - } - - return stringList; -} - -bool AndroidCamera::initJNI(JNIEnv *env) -{ - jclass clazz = QJNIEnvironmentPrivate::findClass(QtCameraListenerClassName, - env); - - static const JNINativeMethod methods[] = { - {"notifyAutoFocusComplete", "(IZ)V", (void *)notifyAutoFocusComplete}, - {"notifyPictureExposed", "(I)V", (void *)notifyPictureExposed}, - {"notifyPictureCaptured", "(I[B)V", (void *)notifyPictureCaptured}, - {"notifyNewPreviewFrame", "(I[BIIII)V", (void *)notifyNewPreviewFrame}, - {"notifyFrameAvailable", "(I)V", (void *)notifyFrameAvailable} - }; - - if (clazz && env->RegisterNatives(clazz, - methods, - sizeof(methods) / sizeof(methods[0])) != JNI_OK) { - return false; - } - - return true; -} - -QT_END_NAMESPACE - -#include "androidcamera.moc" diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.h b/src/plugins/android/src/wrappers/jni/androidcamera.h deleted file mode 100644 index 5ae141f01..000000000 --- a/src/plugins/android/src/wrappers/jni/androidcamera.h +++ /dev/null @@ -1,237 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Ruslan Baratov -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDCAMERA_H -#define ANDROIDCAMERA_H - -#include <qobject.h> -#include <QtCore/private/qjni_p.h> -#include <qsize.h> -#include <qrect.h> -#include <QtMultimedia/qcamera.h> - -QT_BEGIN_NAMESPACE - -class QThread; - -class AndroidCameraPrivate; -class AndroidSurfaceTexture; -class AndroidSurfaceHolder; - -struct AndroidCameraInfo -{ - QByteArray name; - QString description; - QCamera::Position position; - int orientation; -}; -Q_DECLARE_TYPEINFO(AndroidCameraInfo, Q_MOVABLE_TYPE); - -class AndroidCamera : public QObject -{ - Q_OBJECT - Q_ENUMS(CameraFacing) - Q_ENUMS(ImageFormat) -public: - enum CameraFacing { - CameraFacingBack = 0, - CameraFacingFront = 1 - }; - - enum ImageFormat { // same values as in android.graphics.ImageFormat Java class - UnknownImageFormat = 0, - RGB565 = 4, - NV16 = 16, - NV21 = 17, - YUY2 = 20, - JPEG = 256, - YV12 = 842094169 - }; - - // http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getSupportedPreviewFpsRange%28%29 - // "The values are multiplied by 1000 and represented in integers" - struct FpsRange { - int min; - int max; - - FpsRange(): min(0), max(0) {} - - qreal getMinReal() const { return min / 1000.0; } - qreal getMaxReal() const { return max / 1000.0; } - - static FpsRange makeFromQReal(qreal min, qreal max) - { - FpsRange range; - range.min = static_cast<int>(min * 1000.0); - range.max = static_cast<int>(max * 1000.0); - return range; - } - }; - - ~AndroidCamera(); - - static AndroidCamera *open(int cameraId); - - int cameraId() const; - - bool lock(); - bool unlock(); - bool reconnect(); - void release(); - - CameraFacing getFacing(); - int getNativeOrientation(); - - QSize getPreferredPreviewSizeForVideo(); - QList<QSize> getSupportedPreviewSizes(); - - QList<FpsRange> getSupportedPreviewFpsRange(); - - FpsRange getPreviewFpsRange(); - void setPreviewFpsRange(FpsRange); - - ImageFormat getPreviewFormat(); - void setPreviewFormat(ImageFormat fmt); - QList<ImageFormat> getSupportedPreviewFormats(); - - QSize previewSize() const; - QSize actualPreviewSize(); - void setPreviewSize(const QSize &size); - bool setPreviewTexture(AndroidSurfaceTexture *surfaceTexture); - bool setPreviewDisplay(AndroidSurfaceHolder *surfaceHolder); - void setDisplayOrientation(int degrees); - - bool isZoomSupported(); - int getMaxZoom(); - QList<int> getZoomRatios(); - int getZoom(); - void setZoom(int value); - - QStringList getSupportedFlashModes(); - QString getFlashMode(); - void setFlashMode(const QString &value); - - QStringList getSupportedFocusModes(); - QString getFocusMode(); - void setFocusMode(const QString &value); - - int getMaxNumFocusAreas(); - QList<QRect> getFocusAreas(); - void setFocusAreas(const QList<QRect> &areas); - - void autoFocus(); - void cancelAutoFocus(); - - bool isAutoExposureLockSupported(); - bool getAutoExposureLock(); - void setAutoExposureLock(bool toggle); - - bool isAutoWhiteBalanceLockSupported(); - bool getAutoWhiteBalanceLock(); - void setAutoWhiteBalanceLock(bool toggle); - - int getExposureCompensation(); - void setExposureCompensation(int value); - float getExposureCompensationStep(); - int getMinExposureCompensation(); - int getMaxExposureCompensation(); - - QStringList getSupportedSceneModes(); - QString getSceneMode(); - void setSceneMode(const QString &value); - - QStringList getSupportedWhiteBalance(); - QString getWhiteBalance(); - void setWhiteBalance(const QString &value); - - void setRotation(int rotation); - int getRotation() const; - - QList<QSize> getSupportedPictureSizes(); - void setPictureSize(const QSize &size); - void setJpegQuality(int quality); - - void startPreview(); - void stopPreview(); - void stopPreviewSynchronous(); - - void takePicture(); - - void setupPreviewFrameCallback(); - void notifyNewFrames(bool notify); - void fetchLastPreviewFrame(); - QJNIObjectPrivate getCameraObject(); - - static int getNumberOfCameras(); - static void getCameraInfo(int id, AndroidCameraInfo *info); - static bool requestCameraPermission(); - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void previewSizeChanged(); - void previewStarted(); - void previewFailedToStart(); - void previewStopped(); - - void autoFocusStarted(); - void autoFocusComplete(bool success); - - void whiteBalanceChanged(); - - void takePictureFailed(); - void pictureExposed(); - void pictureCaptured(const QByteArray &data); - void lastPreviewFrameFetched(const QVideoFrame &frame); - void newPreviewFrame(const QVideoFrame &frame); - -private: - AndroidCamera(AndroidCameraPrivate *d, QThread *worker); - - Q_DECLARE_PRIVATE(AndroidCamera) - AndroidCameraPrivate *d_ptr; - QScopedPointer<QThread> m_worker; -}; - -Q_DECLARE_METATYPE(AndroidCamera::ImageFormat) - -QT_END_NAMESPACE - -#endif // ANDROIDCAMERA_H diff --git a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp deleted file mode 100644 index ce6144167..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidmediametadataretriever.h" - -#include <QtCore/private/qjnihelpers_p.h> -#include <QtCore/private/qjni_p.h> -#include <QtCore/QUrl> -#include <qdebug.h> - -QT_BEGIN_NAMESPACE - -static bool exceptionCheckAndClear(JNIEnv *env) -{ - if (Q_UNLIKELY(env->ExceptionCheck())) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif // QT_DEBUG - env->ExceptionClear(); - return true; - } - - return false; -} - -AndroidMediaMetadataRetriever::AndroidMediaMetadataRetriever() -{ - m_metadataRetriever = QJNIObjectPrivate("android/media/MediaMetadataRetriever"); -} - -AndroidMediaMetadataRetriever::~AndroidMediaMetadataRetriever() -{ - release(); -} - -QString AndroidMediaMetadataRetriever::extractMetadata(MetadataKey key) -{ - QString value; - - QJNIObjectPrivate metadata = m_metadataRetriever.callObjectMethod("extractMetadata", - "(I)Ljava/lang/String;", - jint(key)); - if (metadata.isValid()) - value = metadata.toString(); - - return value; -} - -void AndroidMediaMetadataRetriever::release() -{ - if (!m_metadataRetriever.isValid()) - return; - - m_metadataRetriever.callMethod<void>("release"); -} - -bool AndroidMediaMetadataRetriever::setDataSource(const QUrl &url) -{ - if (!m_metadataRetriever.isValid()) - return false; - - QJNIEnvironmentPrivate env; - - if (url.isLocalFile()) { // also includes qrc files (copied to a temp file by QMediaPlayer) - QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.path()); - QJNIObjectPrivate fileInputStream("java/io/FileInputStream", - "(Ljava/lang/String;)V", - string.object()); - - if (exceptionCheckAndClear(env)) - return false; - - QJNIObjectPrivate fd = fileInputStream.callObjectMethod("getFD", - "()Ljava/io/FileDescriptor;"); - if (exceptionCheckAndClear(env)) { - fileInputStream.callMethod<void>("close"); - exceptionCheckAndClear(env); - return false; - } - - m_metadataRetriever.callMethod<void>("setDataSource", - "(Ljava/io/FileDescriptor;)V", - fd.object()); - - bool ok = !exceptionCheckAndClear(env); - - fileInputStream.callMethod<void>("close"); - exceptionCheckAndClear(env); - - if (!ok) - return false; - } else if (url.scheme() == QLatin1String("assets")) { - QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.path().mid(1)); // remove first '/' - QJNIObjectPrivate activity(QtAndroidPrivate::activity()); - QJNIObjectPrivate assetManager = activity.callObjectMethod("getAssets", - "()Landroid/content/res/AssetManager;"); - QJNIObjectPrivate assetFd = assetManager.callObjectMethod("openFd", - "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;", - string.object()); - if (exceptionCheckAndClear(env)) - return false; - - QJNIObjectPrivate fd = assetFd.callObjectMethod("getFileDescriptor", - "()Ljava/io/FileDescriptor;"); - if (exceptionCheckAndClear(env)) { - assetFd.callMethod<void>("close"); - exceptionCheckAndClear(env); - return false; - } - - m_metadataRetriever.callMethod<void>("setDataSource", - "(Ljava/io/FileDescriptor;JJ)V", - fd.object(), - assetFd.callMethod<jlong>("getStartOffset"), - assetFd.callMethod<jlong>("getLength")); - - bool ok = !exceptionCheckAndClear(env); - - assetFd.callMethod<void>("close"); - exceptionCheckAndClear(env); - - if (!ok) - return false; - } else if (QtAndroidPrivate::androidSdkVersion() >= 14) { - // On API levels >= 14, only setDataSource(String, Map<String, String>) accepts remote media - QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.toString(QUrl::FullyEncoded)); - QJNIObjectPrivate hash("java/util/HashMap"); - - m_metadataRetriever.callMethod<void>("setDataSource", - "(Ljava/lang/String;Ljava/util/Map;)V", - string.object(), - hash.object()); - if (exceptionCheckAndClear(env)) - return false; - } else { - // While on API levels < 14, only setDataSource(Context, Uri) is available and works for - // remote media... - QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.toString(QUrl::FullyEncoded)); - QJNIObjectPrivate uri = m_metadataRetriever.callStaticObjectMethod("android/net/Uri", - "parse", - "(Ljava/lang/String;)Landroid/net/Uri;", - string.object()); - if (exceptionCheckAndClear(env)) - return false; - - m_metadataRetriever.callMethod<void>("setDataSource", - "(Landroid/content/Context;Landroid/net/Uri;)V", - QtAndroidPrivate::activity(), - uri.object()); - if (exceptionCheckAndClear(env)) - return false; - } - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h deleted file mode 100644 index 1e141813d..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDMEDIAMETADATARETRIEVER_H -#define ANDROIDMEDIAMETADATARETRIEVER_H - -#include <QtCore/private/qjni_p.h> - -QT_BEGIN_NAMESPACE - -class AndroidMediaMetadataRetriever -{ -public: - enum MetadataKey { - Album = 1, - AlbumArtist = 13, - Artist = 2, - Author = 3, - Bitrate = 20, - CDTrackNumber = 0, - Compilation = 15, - Composer = 4, - Date = 5, - DiscNumber = 14, - Duration = 9, - Genre = 6, - HasAudio = 16, - HasVideo = 17, - Location = 23, - MimeType = 12, - NumTracks = 10, - Title = 7, - VideoHeight = 19, - VideoWidth = 18, - VideoRotation = 24, - Writer = 11, - Year = 8 - }; - - AndroidMediaMetadataRetriever(); - ~AndroidMediaMetadataRetriever(); - - QString extractMetadata(MetadataKey key); - bool setDataSource(const QUrl &url); - -private: - void release(); - QJNIObjectPrivate m_metadataRetriever; -}; - -QT_END_NAMESPACE - -#endif // ANDROIDMEDIAMETADATARETRIEVER_H diff --git a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp deleted file mode 100644 index c94695de4..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp +++ /dev/null @@ -1,435 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidmediaplayer.h" - -#include <QString> -#include <QtCore/private/qjni_p.h> -#include <QtCore/private/qjnihelpers_p.h> -#include "androidsurfacetexture.h" -#include <QList> -#include <QReadWriteLock> - -static const char QtAndroidMediaPlayerClassName[] = "org/qtproject/qt/android/multimedia/QtAndroidMediaPlayer"; -typedef QList<AndroidMediaPlayer *> MediaPlayerList; -Q_GLOBAL_STATIC(MediaPlayerList, mediaPlayers) -Q_GLOBAL_STATIC(QReadWriteLock, rwLock) - -QT_BEGIN_NAMESPACE - -AndroidMediaPlayer::AndroidMediaPlayer() - : QObject() -{ - QWriteLocker locker(rwLock); - auto context = QtAndroidPrivate::activity() ? QtAndroidPrivate::activity() : QtAndroidPrivate::service(); - const jlong id = reinterpret_cast<jlong>(this); - mMediaPlayer = QJNIObjectPrivate(QtAndroidMediaPlayerClassName, - "(Landroid/content/Context;J)V", - context, - id); - mediaPlayers->append(this); -} - -AndroidMediaPlayer::~AndroidMediaPlayer() -{ - QWriteLocker locker(rwLock); - const int i = mediaPlayers->indexOf(this); - Q_ASSERT(i != -1); - mediaPlayers->remove(i); -} - -void AndroidMediaPlayer::release() -{ - mMediaPlayer.callMethod<void>("release"); -} - -void AndroidMediaPlayer::reset() -{ - mMediaPlayer.callMethod<void>("reset"); -} - -int AndroidMediaPlayer::getCurrentPosition() -{ - return mMediaPlayer.callMethod<jint>("getCurrentPosition"); -} - -int AndroidMediaPlayer::getDuration() -{ - return mMediaPlayer.callMethod<jint>("getDuration"); -} - -bool AndroidMediaPlayer::isPlaying() -{ - return mMediaPlayer.callMethod<jboolean>("isPlaying"); -} - -int AndroidMediaPlayer::volume() -{ - return mMediaPlayer.callMethod<jint>("getVolume"); -} - -bool AndroidMediaPlayer::isMuted() -{ - return mMediaPlayer.callMethod<jboolean>("isMuted"); -} - -qreal AndroidMediaPlayer::playbackRate() -{ - qreal rate(1.0); - - if (QtAndroidPrivate::androidSdkVersion() < 23) - return rate; - - QJNIObjectPrivate player = mMediaPlayer.callObjectMethod("getMediaPlayerHandle", "()Landroid/media/MediaPlayer;"); - if (player.isValid()) { - QJNIObjectPrivate playbackParams = player.callObjectMethod("getPlaybackParams", "()Landroid/media/PlaybackParams;"); - if (playbackParams.isValid()) { - const qreal speed = playbackParams.callMethod<jfloat>("getSpeed", "()F"); - QJNIEnvironmentPrivate env; - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif // QT_DEBUG - env->ExceptionClear(); - } else { - rate = speed; - } - } - } - - return rate; -} - -jobject AndroidMediaPlayer::display() -{ - return mMediaPlayer.callObjectMethod("display", "()Landroid/view/SurfaceHolder;").object(); -} - -void AndroidMediaPlayer::play() -{ - mMediaPlayer.callMethod<void>("start"); -} - -void AndroidMediaPlayer::pause() -{ - mMediaPlayer.callMethod<void>("pause"); -} - -void AndroidMediaPlayer::stop() -{ - mMediaPlayer.callMethod<void>("stop"); -} - -void AndroidMediaPlayer::seekTo(qint32 msec) -{ - mMediaPlayer.callMethod<void>("seekTo", "(I)V", jint(msec)); -} - -void AndroidMediaPlayer::setMuted(bool mute) -{ - mMediaPlayer.callMethod<void>("mute", "(Z)V", jboolean(mute)); -} - -void AndroidMediaPlayer::setDataSource(const QNetworkRequest &request) -{ - QJNIObjectPrivate string = QJNIObjectPrivate::fromString(request.url().toString(QUrl::FullyEncoded)); - - mMediaPlayer.callMethod<void>("initHeaders", "()V"); - for (auto &header : request.rawHeaderList()) { - auto value = request.rawHeader(header); - mMediaPlayer.callMethod<void>("setHeader", "(Ljava/lang/String;Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(header).object(), QJNIObjectPrivate::fromString(value).object()); - } - - mMediaPlayer.callMethod<void>("setDataSource", "(Ljava/lang/String;)V", string.object()); -} - -void AndroidMediaPlayer::prepareAsync() -{ - mMediaPlayer.callMethod<void>("prepareAsync"); -} - -void AndroidMediaPlayer::setVolume(int volume) -{ - mMediaPlayer.callMethod<void>("setVolume", "(I)V", jint(volume)); -} - -bool AndroidMediaPlayer::setPlaybackRate(qreal rate) -{ - if (QtAndroidPrivate::androidSdkVersion() < 23) { - qWarning("Setting the playback rate on a media player requires Android 6.0 (API level 23) or later"); - return false; - } - - QJNIEnvironmentPrivate env; - - QJNIObjectPrivate player = mMediaPlayer.callObjectMethod("getMediaPlayerHandle", "()Landroid/media/MediaPlayer;"); - if (player.isValid()) { - QJNIObjectPrivate playbackParams = player.callObjectMethod("getPlaybackParams", "()Landroid/media/PlaybackParams;"); - if (playbackParams.isValid()) { - playbackParams.callObjectMethod("setSpeed", "(F)Landroid/media/PlaybackParams;", jfloat(rate)); - // pitch can only be > 0 - if (!qFuzzyIsNull(rate)) - playbackParams.callObjectMethod("setPitch", "(F)Landroid/media/PlaybackParams;", jfloat(qAbs(rate))); - player.callMethod<void>("setPlaybackParams", "(Landroid/media/PlaybackParams;)V", playbackParams.object()); - if (Q_UNLIKELY(env->ExceptionCheck())) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif // QT_DEBUG - env->ExceptionClear(); - qWarning() << "Invalid playback rate" << rate; - return false; - } else { - return true; - } - } - } - - return false; -} - -void AndroidMediaPlayer::setDisplay(AndroidSurfaceTexture *surfaceTexture) -{ - mMediaPlayer.callMethod<void>("setDisplay", - "(Landroid/view/SurfaceHolder;)V", - surfaceTexture ? surfaceTexture->surfaceHolder() : 0); -} - -void AndroidMediaPlayer::setAudioRole(QAudio::Role role) -{ - QString str; - switch (role) { - case QAudio::MusicRole: - str = QLatin1String("CONTENT_TYPE_MUSIC"); - break; - case QAudio::VideoRole: - str = QLatin1String("CONTENT_TYPE_MOVIE"); - break; - case QAudio::VoiceCommunicationRole: - str = QLatin1String("USAGE_VOICE_COMMUNICATION"); - break; - case QAudio::AlarmRole: - str = QLatin1String("USAGE_ALARM"); - break; - case QAudio::NotificationRole: - str = QLatin1String("USAGE_NOTIFICATION"); - break; - case QAudio::RingtoneRole: - str = QLatin1String("USAGE_NOTIFICATION_RINGTONE"); - break; - case QAudio::AccessibilityRole: - str = QLatin1String("USAGE_ASSISTANCE_ACCESSIBILITY"); - break; - case QAudio::SonificationRole: - str = QLatin1String("CONTENT_TYPE_SONIFICATION"); - break; - case QAudio::GameRole: - str = QLatin1String("USAGE_GAME"); - break; - default: - break; - } - - setCustomAudioRole(str); -} - -void AndroidMediaPlayer::setCustomAudioRole(const QString &role) -{ - QStringList roles = role.split(",", Qt::SkipEmptyParts); - - int type = 0; // CONTENT_TYPE_UNKNOWN - int usage = 0; // USAGE_UNKNOWN - for (int i = 0; i < qMin(2, roles.size()); ++i) { - auto r = roles[i]; - if (r == QLatin1String("CONTENT_TYPE_MOVIE")) - type = 3; - else if (r == QLatin1String("CONTENT_TYPE_MUSIC")) - type = 2; - else if (r == QLatin1String("CONTENT_TYPE_SONIFICATION")) - type = 4; - else if (r == QLatin1String("CONTENT_TYPE_SPEECH")) - type = 1; - else if (r == QLatin1String("USAGE_ALARM")) - usage = 4; - else if (r == QLatin1String("USAGE_ASSISTANCE_ACCESSIBILITY")) - usage = 11; - else if (r == QLatin1String("USAGE_ASSISTANCE_NAVIGATION_GUIDANCE")) - usage = 12; - else if (r == QLatin1String("USAGE_ASSISTANCE_SONIFICATION")) - usage = 13; - else if (r == QLatin1String("USAGE_ASSISTANT")) - usage = 16; - else if (r == QLatin1String("USAGE_GAME")) - usage = 14; - else if (r == QLatin1String("USAGE_MEDIA")) - usage = 1; - else if (r == QLatin1String("USAGE_NOTIFICATION")) - usage = 5; - else if (r == QLatin1String("USAGE_NOTIFICATION_COMMUNICATION_DELAYED")) - usage = 9; - else if (r == QLatin1String("USAGE_NOTIFICATION_COMMUNICATION_INSTANT")) - usage = 8; - else if (r == QLatin1String("USAGE_NOTIFICATION_COMMUNICATION_REQUEST")) - usage = 7; - else if (r == QLatin1String("USAGE_NOTIFICATION_EVENT")) - usage = 10; - else if (r == QLatin1String("USAGE_NOTIFICATION_RINGTONE")) - usage = 6; - else if (r == QLatin1String("USAGE_VOICE_COMMUNICATION")) - usage = 2; - else if (r == QLatin1String("USAGE_VOICE_COMMUNICATION_SIGNALLING")) - usage = 3; - } - - mMediaPlayer.callMethod<void>("setAudioAttributes", "(II)V", jint(type), jint(usage)); -} - -static void onErrorNative(JNIEnv *env, jobject thiz, jint what, jint extra, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->error(what, extra); -} - -static void onBufferingUpdateNative(JNIEnv *env, jobject thiz, jint percent, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->bufferingChanged(percent); -} - -static void onProgressUpdateNative(JNIEnv *env, jobject thiz, jint progress, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->progressChanged(progress); -} - -static void onDurationChangedNative(JNIEnv *env, jobject thiz, jint duration, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->durationChanged(duration); -} - -static void onInfoNative(JNIEnv *env, jobject thiz, jint what, jint extra, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->info(what, extra); -} - -static void onStateChangedNative(JNIEnv *env, jobject thiz, jint state, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->stateChanged(state); -} - -static void onVideoSizeChangedNative(JNIEnv *env, - jobject thiz, - jint width, - jint height, - jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->videoSizeChanged(width, height); -} - -bool AndroidMediaPlayer::initJNI(JNIEnv *env) -{ - jclass clazz = QJNIEnvironmentPrivate::findClass(QtAndroidMediaPlayerClassName, - env); - - static const JNINativeMethod methods[] = { - {"onErrorNative", "(IIJ)V", reinterpret_cast<void *>(onErrorNative)}, - {"onBufferingUpdateNative", "(IJ)V", reinterpret_cast<void *>(onBufferingUpdateNative)}, - {"onProgressUpdateNative", "(IJ)V", reinterpret_cast<void *>(onProgressUpdateNative)}, - {"onDurationChangedNative", "(IJ)V", reinterpret_cast<void *>(onDurationChangedNative)}, - {"onInfoNative", "(IIJ)V", reinterpret_cast<void *>(onInfoNative)}, - {"onVideoSizeChangedNative", "(IIJ)V", reinterpret_cast<void *>(onVideoSizeChangedNative)}, - {"onStateChangedNative", "(IJ)V", reinterpret_cast<void *>(onStateChangedNative)} - }; - - if (clazz && env->RegisterNatives(clazz, - methods, - sizeof(methods) / sizeof(methods[0])) != JNI_OK) { - return false; - } - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidmediaplayer.h b/src/plugins/android/src/wrappers/jni/androidmediaplayer.h deleted file mode 100644 index 37c7456f7..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmediaplayer.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDMEDIAPLAYER_H -#define ANDROIDMEDIAPLAYER_H - -#include <QObject> -#include <QNetworkRequest> -#include <QtCore/private/qjni_p.h> -#include <QAudio> - -QT_BEGIN_NAMESPACE - -class AndroidSurfaceTexture; - -class AndroidMediaPlayer : public QObject -{ - Q_OBJECT -public: - AndroidMediaPlayer(); - ~AndroidMediaPlayer(); - - enum MediaError - { - // What - MEDIA_ERROR_UNKNOWN = 1, - MEDIA_ERROR_SERVER_DIED = 100, - MEDIA_ERROR_INVALID_STATE = -38, // Undocumented - // Extra - MEDIA_ERROR_IO = -1004, - MEDIA_ERROR_MALFORMED = -1007, - MEDIA_ERROR_UNSUPPORTED = -1010, - MEDIA_ERROR_TIMED_OUT = -110, - MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200, - MEDIA_ERROR_BAD_THINGS_ARE_GOING_TO_HAPPEN = -2147483648 // Undocumented - }; - - enum MediaInfo - { - MEDIA_INFO_UNKNOWN = 1, - MEDIA_INFO_VIDEO_TRACK_LAGGING = 700, - MEDIA_INFO_VIDEO_RENDERING_START = 3, - MEDIA_INFO_BUFFERING_START = 701, - MEDIA_INFO_BUFFERING_END = 702, - MEDIA_INFO_BAD_INTERLEAVING = 800, - MEDIA_INFO_NOT_SEEKABLE = 801, - MEDIA_INFO_METADATA_UPDATE = 802 - }; - - enum MediaPlayerState - { - Uninitialized = 0x1, /* End */ - Idle = 0x2, - Preparing = 0x4, - Prepared = 0x8, - Initialized = 0x10, - Started = 0x20, - Stopped = 0x40, - Paused = 0x80, - PlaybackCompleted = 0x100, - Error = 0x200 - }; - - void release(); - void reset(); - - int getCurrentPosition(); - int getDuration(); - bool isPlaying(); - int volume(); - bool isMuted(); - qreal playbackRate(); - jobject display(); - - void play(); - void pause(); - void stop(); - void seekTo(qint32 msec); - void setMuted(bool mute); - void setDataSource(const QNetworkRequest &request); - void prepareAsync(); - void setVolume(int volume); - bool setPlaybackRate(qreal rate); - void setDisplay(AndroidSurfaceTexture *surfaceTexture); - void setAudioRole(QAudio::Role role); - void setCustomAudioRole(const QString &role); - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void error(qint32 what, qint32 extra); - void bufferingChanged(qint32 percent); - void durationChanged(qint64 duration); - void progressChanged(qint64 progress); - void stateChanged(qint32 state); - void info(qint32 what, qint32 extra); - void videoSizeChanged(qint32 width, qint32 height); - -private: - QJNIObjectPrivate mMediaPlayer; -}; - -QT_END_NAMESPACE - -#endif // ANDROIDMEDIAPLAYER_H diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp deleted file mode 100644 index e5f8846b9..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp +++ /dev/null @@ -1,405 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidmediarecorder.h" - -#include "androidcamera.h" -#include "androidsurfacetexture.h" -#include "androidsurfaceview.h" -#include "qandroidglobal.h" -#include "qandroidmultimediautils.h" -#include <QtCore/private/qjni_p.h> -#include <qmap.h> - -QT_BEGIN_NAMESPACE - -typedef QMap<QString, QJNIObjectPrivate> CamcorderProfiles; -Q_GLOBAL_STATIC(CamcorderProfiles, g_camcorderProfiles) - -static QString profileKey() -{ - return QStringLiteral("%1-%2"); -} - -bool AndroidCamcorderProfile::hasProfile(jint cameraId, Quality quality) -{ - if (g_camcorderProfiles->contains(profileKey().arg(cameraId).arg(quality))) - return true; - - return QJNIObjectPrivate::callStaticMethod<jboolean>("android/media/CamcorderProfile", - "hasProfile", - "(II)Z", - cameraId, - quality); -} - -AndroidCamcorderProfile AndroidCamcorderProfile::get(jint cameraId, Quality quality) -{ - const QString key = profileKey().arg(cameraId).arg(quality); - QMap<QString, QJNIObjectPrivate>::const_iterator it = g_camcorderProfiles->constFind(key); - - if (it != g_camcorderProfiles->constEnd()) - return AndroidCamcorderProfile(*it); - - QJNIObjectPrivate camProfile = QJNIObjectPrivate::callStaticObjectMethod("android/media/CamcorderProfile", - "get", - "(II)Landroid/media/CamcorderProfile;", - cameraId, - quality); - - return AndroidCamcorderProfile((*g_camcorderProfiles)[key] = camProfile); -} - -int AndroidCamcorderProfile::getValue(AndroidCamcorderProfile::Field field) const -{ - switch (field) { - case audioBitRate: - return m_camcorderProfile.getField<jint>("audioBitRate"); - case audioChannels: - return m_camcorderProfile.getField<jint>("audioChannels"); - case audioCodec: - return m_camcorderProfile.getField<jint>("audioCodec"); - case audioSampleRate: - return m_camcorderProfile.getField<jint>("audioSampleRate"); - case duration: - return m_camcorderProfile.getField<jint>("duration"); - case fileFormat: - return m_camcorderProfile.getField<jint>("fileFormat"); - case quality: - return m_camcorderProfile.getField<jint>("quality"); - case videoBitRate: - return m_camcorderProfile.getField<jint>("videoBitRate"); - case videoCodec: - return m_camcorderProfile.getField<jint>("videoCodec"); - case videoFrameHeight: - return m_camcorderProfile.getField<jint>("videoFrameHeight"); - case videoFrameRate: - return m_camcorderProfile.getField<jint>("videoFrameRate"); - case videoFrameWidth: - return m_camcorderProfile.getField<jint>("videoFrameWidth"); - } - - return 0; -} - -AndroidCamcorderProfile::AndroidCamcorderProfile(const QJNIObjectPrivate &camcorderProfile) -{ - m_camcorderProfile = camcorderProfile; -} - -static const char QtMediaRecorderListenerClassName[] = "org/qtproject/qt/android/multimedia/QtMediaRecorderListener"; -typedef QMap<jlong, AndroidMediaRecorder*> MediaRecorderMap; -Q_GLOBAL_STATIC(MediaRecorderMap, mediaRecorders) - -static void notifyError(JNIEnv* , jobject, jlong id, jint what, jint extra) -{ - AndroidMediaRecorder *obj = mediaRecorders->value(id, 0); - if (obj) - emit obj->error(what, extra); -} - -static void notifyInfo(JNIEnv* , jobject, jlong id, jint what, jint extra) -{ - AndroidMediaRecorder *obj = mediaRecorders->value(id, 0); - if (obj) - emit obj->info(what, extra); -} - -AndroidMediaRecorder::AndroidMediaRecorder() - : QObject() - , m_id(reinterpret_cast<jlong>(this)) -{ - m_mediaRecorder = QJNIObjectPrivate("android/media/MediaRecorder"); - if (m_mediaRecorder.isValid()) { - QJNIObjectPrivate listener(QtMediaRecorderListenerClassName, "(J)V", m_id); - m_mediaRecorder.callMethod<void>("setOnErrorListener", - "(Landroid/media/MediaRecorder$OnErrorListener;)V", - listener.object()); - m_mediaRecorder.callMethod<void>("setOnInfoListener", - "(Landroid/media/MediaRecorder$OnInfoListener;)V", - listener.object()); - mediaRecorders->insert(m_id, this); - } -} - -AndroidMediaRecorder::~AndroidMediaRecorder() -{ - mediaRecorders->remove(m_id); -} - -void AndroidMediaRecorder::release() -{ - m_mediaRecorder.callMethod<void>("release"); -} - -bool AndroidMediaRecorder::prepare() -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("prepare"); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - return false; - } - return true; -} - -void AndroidMediaRecorder::reset() -{ - m_mediaRecorder.callMethod<void>("reset"); -} - -bool AndroidMediaRecorder::start() -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("start"); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - return false; - } - return true; -} - -void AndroidMediaRecorder::stop() -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("stop"); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setAudioChannels(int numChannels) -{ - m_mediaRecorder.callMethod<void>("setAudioChannels", "(I)V", numChannels); -} - -void AndroidMediaRecorder::setAudioEncoder(AudioEncoder encoder) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setAudioEncoder", "(I)V", int(encoder)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setAudioEncodingBitRate(int bitRate) -{ - m_mediaRecorder.callMethod<void>("setAudioEncodingBitRate", "(I)V", bitRate); -} - -void AndroidMediaRecorder::setAudioSamplingRate(int samplingRate) -{ - m_mediaRecorder.callMethod<void>("setAudioSamplingRate", "(I)V", samplingRate); -} - -void AndroidMediaRecorder::setAudioSource(AudioSource source) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setAudioSource", "(I)V", int(source)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setCamera(AndroidCamera *camera) -{ - QJNIObjectPrivate cam = camera->getCameraObject(); - m_mediaRecorder.callMethod<void>("setCamera", "(Landroid/hardware/Camera;)V", cam.object()); -} - -void AndroidMediaRecorder::setVideoEncoder(VideoEncoder encoder) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setVideoEncoder", "(I)V", int(encoder)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setVideoEncodingBitRate(int bitRate) -{ - m_mediaRecorder.callMethod<void>("setVideoEncodingBitRate", "(I)V", bitRate); -} - -void AndroidMediaRecorder::setVideoFrameRate(int rate) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setVideoFrameRate", "(I)V", rate); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setVideoSize(const QSize &size) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setVideoSize", "(II)V", size.width(), size.height()); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setVideoSource(VideoSource source) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setVideoSource", "(I)V", int(source)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setOrientationHint(int degrees) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setOrientationHint", "(I)V", degrees); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setOutputFormat(OutputFormat format) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setOutputFormat", "(I)V", int(format)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setOutputFile(const QString &path) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setOutputFile", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(path).object()); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setSurfaceTexture(AndroidSurfaceTexture *texture) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setPreviewDisplay", - "(Landroid/view/Surface;)V", - texture->surface()); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setSurfaceHolder(AndroidSurfaceHolder *holder) -{ - QJNIEnvironmentPrivate env; - QJNIObjectPrivate surfaceHolder(holder->surfaceHolder()); - QJNIObjectPrivate surface = surfaceHolder.callObjectMethod("getSurface", - "()Landroid/view/Surface;"); - if (!surface.isValid()) - return; - - m_mediaRecorder.callMethod<void>("setPreviewDisplay", - "(Landroid/view/Surface;)V", - surface.object()); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -bool AndroidMediaRecorder::initJNI(JNIEnv *env) -{ - jclass clazz = QJNIEnvironmentPrivate::findClass(QtMediaRecorderListenerClassName, - env); - - static const JNINativeMethod methods[] = { - {"notifyError", "(JII)V", (void *)notifyError}, - {"notifyInfo", "(JII)V", (void *)notifyInfo} - }; - - if (clazz && env->RegisterNatives(clazz, - methods, - sizeof(methods) / sizeof(methods[0])) != JNI_OK) { - return false; - } - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h b/src/plugins/android/src/wrappers/jni/androidmediarecorder.h deleted file mode 100644 index e4b3a80ea..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDMEDIARECORDER_H -#define ANDROIDMEDIARECORDER_H - -#include <qobject.h> -#include <QtCore/private/qjni_p.h> -#include <qsize.h> - -QT_BEGIN_NAMESPACE - -class AndroidCamera; -class AndroidSurfaceTexture; -class AndroidSurfaceHolder; - -class AndroidCamcorderProfile -{ -public: - enum Quality { // Needs to match CamcorderProfile - QUALITY_LOW, - QUALITY_HIGH, - QUALITY_QCIF, - QUALITY_CIF, - QUALITY_480P, - QUALITY_720P, - QUALITY_1080P, - QUALITY_QVGA - }; - - enum Field { - audioBitRate, - audioChannels, - audioCodec, - audioSampleRate, - duration, - fileFormat, - quality, - videoBitRate, - videoCodec, - videoFrameHeight, - videoFrameRate, - videoFrameWidth - }; - - static bool hasProfile(jint cameraId, Quality quality); - static AndroidCamcorderProfile get(jint cameraId, Quality quality); - int getValue(Field field) const; - -private: - AndroidCamcorderProfile(const QJNIObjectPrivate &camcorderProfile); - QJNIObjectPrivate m_camcorderProfile; -}; - -class AndroidMediaRecorder : public QObject -{ - Q_OBJECT -public: - enum AudioEncoder { - DefaultAudioEncoder = 0, - AMR_NB_Encoder = 1, - AMR_WB_Encoder = 2, - AAC = 3 - }; - - enum AudioSource { - DefaultAudioSource = 0, - Mic = 1, - VoiceUplink = 2, - VoiceDownlink = 3, - VoiceCall = 4, - Camcorder = 5, - VoiceRecognition = 6 - }; - - enum VideoEncoder { - DefaultVideoEncoder = 0, - H263 = 1, - H264 = 2, - MPEG_4_SP = 3 - }; - - enum VideoSource { - DefaultVideoSource = 0, - Camera = 1 - }; - - enum OutputFormat { - DefaultOutputFormat = 0, - THREE_GPP = 1, - MPEG_4 = 2, - AMR_NB_Format = 3, - AMR_WB_Format = 4 - }; - - AndroidMediaRecorder(); - ~AndroidMediaRecorder(); - - void release(); - bool prepare(); - void reset(); - - bool start(); - void stop(); - - void setAudioChannels(int numChannels); - void setAudioEncoder(AudioEncoder encoder); - void setAudioEncodingBitRate(int bitRate); - void setAudioSamplingRate(int samplingRate); - void setAudioSource(AudioSource source); - - void setCamera(AndroidCamera *camera); - void setVideoEncoder(VideoEncoder encoder); - void setVideoEncodingBitRate(int bitRate); - void setVideoFrameRate(int rate); - void setVideoSize(const QSize &size); - void setVideoSource(VideoSource source); - - void setOrientationHint(int degrees); - - void setOutputFormat(OutputFormat format); - void setOutputFile(const QString &path); - - void setSurfaceTexture(AndroidSurfaceTexture *texture); - void setSurfaceHolder(AndroidSurfaceHolder *holder); - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void error(int what, int extra); - void info(int what, int extra); - -private: - jlong m_id; - QJNIObjectPrivate m_mediaRecorder; -}; - -QT_END_NAMESPACE - -#endif // ANDROIDMEDIARECORDER_H diff --git a/src/plugins/android/src/wrappers/jni/androidmultimediautils.cpp b/src/plugins/android/src/wrappers/jni/androidmultimediautils.cpp deleted file mode 100644 index 19dfbd7d2..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmultimediautils.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidmultimediautils.h" - -#include <QtCore/private/qjni_p.h> - -QT_BEGIN_NAMESPACE - - -void AndroidMultimediaUtils::enableOrientationListener(bool enable) -{ - QJNIObjectPrivate::callStaticMethod<void>("org/qtproject/qt/android/multimedia/QtMultimediaUtils", - "enableOrientationListener", - "(Z)V", - enable); -} - -int AndroidMultimediaUtils::getDeviceOrientation() -{ - return QJNIObjectPrivate::callStaticMethod<jint>("org/qtproject/qt/android/multimedia/QtMultimediaUtils", - "getDeviceOrientation"); -} - -QString AndroidMultimediaUtils::getDefaultMediaDirectory(MediaType type) -{ - QJNIObjectPrivate path = QJNIObjectPrivate::callStaticObjectMethod("org/qtproject/qt/android/multimedia/QtMultimediaUtils", - "getDefaultMediaDirectory", - "(I)Ljava/lang/String;", - jint(type)); - return path.toString(); -} - -void AndroidMultimediaUtils::registerMediaFile(const QString &file) -{ - QJNIObjectPrivate::callStaticMethod<void>("org/qtproject/qt/android/multimedia/QtMultimediaUtils", - "registerMediaFile", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(file).object()); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidmultimediautils.h b/src/plugins/android/src/wrappers/jni/androidmultimediautils.h deleted file mode 100644 index 152d849e4..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmultimediautils.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDMULTIMEDIAUTILS_H -#define ANDROIDMULTIMEDIAUTILS_H - -#include <qobject.h> -#include <QtCore/private/qjni_p.h> - -QT_BEGIN_NAMESPACE - -class AndroidMultimediaUtils -{ -public: - enum MediaType { - Music = 0, - Movies = 1, - DCIM = 2, - Sounds = 3 - }; - - static void enableOrientationListener(bool enable); - static int getDeviceOrientation(); - static QString getDefaultMediaDirectory(MediaType type); - static void registerMediaFile(const QString &file); -}; - -QT_END_NAMESPACE - -#endif // ANDROIDMULTIMEDIAUTILS_H diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp deleted file mode 100644 index d861a355f..000000000 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidsurfacetexture.h" -#include <QtCore/private/qjni_p.h> -#include <QtCore/private/qjnihelpers_p.h> -#include <QtCore/qmutex.h> - -QT_BEGIN_NAMESPACE - -static const char QtSurfaceTextureListenerClassName[] = "org/qtproject/qt/android/multimedia/QtSurfaceTextureListener"; -typedef QList<jlong> SurfaceTextures; -Q_GLOBAL_STATIC(SurfaceTextures, g_surfaceTextures); -Q_GLOBAL_STATIC(QMutex, g_textureMutex); - -// native method for QtSurfaceTexture.java -static void notifyFrameAvailable(JNIEnv* , jobject, jlong id) -{ - const QMutexLocker lock(g_textureMutex()); - const int idx = g_surfaceTextures->indexOf(id); - if (idx == -1) - return; - - AndroidSurfaceTexture *obj = reinterpret_cast<AndroidSurfaceTexture *>(g_surfaceTextures->at(idx)); - if (obj) - Q_EMIT obj->frameAvailable(); -} - -AndroidSurfaceTexture::AndroidSurfaceTexture(quint32 texName) - : QObject() -{ - Q_STATIC_ASSERT(sizeof (jlong) >= sizeof (void *)); - // API level 11 or higher is required - if (QtAndroidPrivate::androidSdkVersion() < 11) { - qWarning("Camera preview and video playback require Android 3.0 (API level 11) or later."); - return; - } - - QJNIEnvironmentPrivate env; - m_surfaceTexture = QJNIObjectPrivate("android/graphics/SurfaceTexture", "(I)V", jint(texName)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif // QT_DEBUG - env->ExceptionClear(); - } - - if (!m_surfaceTexture.isValid()) - return; - - const QMutexLocker lock(g_textureMutex()); - g_surfaceTextures->append(jlong(this)); - QJNIObjectPrivate listener(QtSurfaceTextureListenerClassName, "(J)V", jlong(this)); - setOnFrameAvailableListener(listener); -} - -AndroidSurfaceTexture::~AndroidSurfaceTexture() -{ - if (QtAndroidPrivate::androidSdkVersion() > 13 && m_surface.isValid()) - m_surface.callMethod<void>("release"); - - if (m_surfaceTexture.isValid()) { - release(); - const QMutexLocker lock(g_textureMutex()); - const int idx = g_surfaceTextures->indexOf(jlong(this)); - if (idx != -1) - g_surfaceTextures->remove(idx); - } -} - -QMatrix4x4 AndroidSurfaceTexture::getTransformMatrix() -{ - QMatrix4x4 matrix; - if (!m_surfaceTexture.isValid()) - return matrix; - - QJNIEnvironmentPrivate env; - - jfloatArray array = env->NewFloatArray(16); - m_surfaceTexture.callMethod<void>("getTransformMatrix", "([F)V", array); - env->GetFloatArrayRegion(array, 0, 16, matrix.data()); - env->DeleteLocalRef(array); - - return matrix; -} - -void AndroidSurfaceTexture::release() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return; - - m_surfaceTexture.callMethod<void>("release"); -} - -void AndroidSurfaceTexture::updateTexImage() -{ - if (!m_surfaceTexture.isValid()) - return; - - m_surfaceTexture.callMethod<void>("updateTexImage"); -} - -jobject AndroidSurfaceTexture::surfaceTexture() -{ - return m_surfaceTexture.object(); -} - -jobject AndroidSurfaceTexture::surface() -{ - if (!m_surface.isValid()) { - m_surface = QJNIObjectPrivate("android/view/Surface", - "(Landroid/graphics/SurfaceTexture;)V", - m_surfaceTexture.object()); - } - - return m_surface.object(); -} - -jobject AndroidSurfaceTexture::surfaceHolder() -{ - if (!m_surfaceHolder.isValid()) { - m_surfaceHolder = QJNIObjectPrivate("org/qtproject/qt/android/multimedia/QtSurfaceTextureHolder", - "(Landroid/view/Surface;)V", - surface()); - } - - return m_surfaceHolder.object(); -} - -void AndroidSurfaceTexture::attachToGLContext(quint32 texName) -{ - if (QtAndroidPrivate::androidSdkVersion() < 16 || !m_surfaceTexture.isValid()) - return; - - m_surfaceTexture.callMethod<void>("attachToGLContext", "(I)V", texName); -} - -void AndroidSurfaceTexture::detachFromGLContext() -{ - if (QtAndroidPrivate::androidSdkVersion() < 16 || !m_surfaceTexture.isValid()) - return; - - m_surfaceTexture.callMethod<void>("detachFromGLContext"); -} - -bool AndroidSurfaceTexture::initJNI(JNIEnv *env) -{ - // SurfaceTexture is available since API 11. - if (QtAndroidPrivate::androidSdkVersion() < 11) - return false; - - jclass clazz = QJNIEnvironmentPrivate::findClass(QtSurfaceTextureListenerClassName, - env); - - static const JNINativeMethod methods[] = { - {"notifyFrameAvailable", "(J)V", (void *)notifyFrameAvailable} - }; - - if (clazz && env->RegisterNatives(clazz, - methods, - sizeof(methods) / sizeof(methods[0])) != JNI_OK) { - return false; - } - - return true; -} - -void AndroidSurfaceTexture::setOnFrameAvailableListener(const QJNIObjectPrivate &listener) -{ - m_surfaceTexture.callMethod<void>("setOnFrameAvailableListener", - "(Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;)V", - listener.object()); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h deleted file mode 100644 index 911711774..000000000 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDSURFACETEXTURE_H -#define ANDROIDSURFACETEXTURE_H - -#include <qobject.h> -#include <QtCore/private/qjni_p.h> - -#include <QMatrix4x4> - -QT_BEGIN_NAMESPACE - -class AndroidSurfaceTexture : public QObject -{ - Q_OBJECT -public: - explicit AndroidSurfaceTexture(quint32 texName); - ~AndroidSurfaceTexture(); - - jobject surfaceTexture(); - jobject surface(); - jobject surfaceHolder(); - inline bool isValid() const { return m_surfaceTexture.isValid(); } - - QMatrix4x4 getTransformMatrix(); - void release(); // API level 14 - void updateTexImage(); - - void attachToGLContext(quint32 texName); // API level 16 - void detachFromGLContext(); // API level 16 - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void frameAvailable(); - -private: - void setOnFrameAvailableListener(const QJNIObjectPrivate &listener); - - QJNIObjectPrivate m_surfaceTexture; - QJNIObjectPrivate m_surface; - QJNIObjectPrivate m_surfaceHolder; -}; - -QT_END_NAMESPACE - -#endif // ANDROIDSURFACETEXTURE_H diff --git a/src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp b/src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp deleted file mode 100644 index 65dfe84b9..000000000 --- a/src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidsurfaceview.h" - -#include <QtCore/private/qjnihelpers_p.h> -#include <QtCore/qcoreapplication.h> -#include <QtCore/qdebug.h> -#include <QtCore/qlist.h> -#include <QtCore/qmutex.h> -#include <QtGui/qwindow.h> - -QT_BEGIN_NAMESPACE - -static const char QtSurfaceHolderCallbackClassName[] = "org/qtproject/qt/android/multimedia/QtSurfaceHolderCallback"; -typedef QList<AndroidSurfaceHolder *> SurfaceHolders; -Q_GLOBAL_STATIC(SurfaceHolders, surfaceHolders) -Q_GLOBAL_STATIC(QMutex, shLock) - -AndroidSurfaceHolder::AndroidSurfaceHolder(QJNIObjectPrivate object) - : m_surfaceHolder(object) - , m_surfaceCreated(false) -{ - if (!m_surfaceHolder.isValid()) - return; - - { - QMutexLocker locker(shLock()); - surfaceHolders->append(this); - } - - QJNIObjectPrivate callback(QtSurfaceHolderCallbackClassName, "(J)V", reinterpret_cast<jlong>(this)); - m_surfaceHolder.callMethod<void>("addCallback", - "(Landroid/view/SurfaceHolder$Callback;)V", - callback.object()); -} - -AndroidSurfaceHolder::~AndroidSurfaceHolder() -{ - QMutexLocker locker(shLock()); - const int i = surfaceHolders->indexOf(this); - if (Q_UNLIKELY(i == -1)) - return; - - surfaceHolders->remove(i); -} - -jobject AndroidSurfaceHolder::surfaceHolder() const -{ - return m_surfaceHolder.object(); -} - -bool AndroidSurfaceHolder::isSurfaceCreated() const -{ - QMutexLocker locker(shLock()); - return m_surfaceCreated; -} - -void AndroidSurfaceHolder::handleSurfaceCreated(JNIEnv*, jobject, jlong id) -{ - QMutexLocker locker(shLock()); - const int i = surfaceHolders->indexOf(reinterpret_cast<AndroidSurfaceHolder *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - (*surfaceHolders)[i]->m_surfaceCreated = true; - Q_EMIT (*surfaceHolders)[i]->surfaceCreated(); -} - -void AndroidSurfaceHolder::handleSurfaceDestroyed(JNIEnv*, jobject, jlong id) -{ - QMutexLocker locker(shLock()); - const int i = surfaceHolders->indexOf(reinterpret_cast<AndroidSurfaceHolder *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - (*surfaceHolders)[i]->m_surfaceCreated = false; -} - -bool AndroidSurfaceHolder::initJNI(JNIEnv *env) -{ - jclass clazz = QJNIEnvironmentPrivate::findClass(QtSurfaceHolderCallbackClassName, - env); - - static const JNINativeMethod methods[] = { - {"notifySurfaceCreated", "(J)V", (void *)AndroidSurfaceHolder::handleSurfaceCreated}, - {"notifySurfaceDestroyed", "(J)V", (void *)AndroidSurfaceHolder::handleSurfaceDestroyed} - }; - - if (clazz && env->RegisterNatives(clazz, - methods, - sizeof(methods) / sizeof(methods[0])) != JNI_OK) { - return false; - } - - return true; -} - -AndroidSurfaceView::AndroidSurfaceView() - : m_window(0) - , m_surfaceHolder(0) - , m_pendingVisible(-1) -{ - QtAndroidPrivate::runOnAndroidThreadSync([this] { - m_surfaceView = QJNIObjectPrivate("android/view/SurfaceView", - "(Landroid/content/Context;)V", - QtAndroidPrivate::activity()); - }, QJNIEnvironmentPrivate()); - - Q_ASSERT(m_surfaceView.isValid()); - - QJNIObjectPrivate holder = m_surfaceView.callObjectMethod("getHolder", - "()Landroid/view/SurfaceHolder;"); - if (!holder.isValid()) { - m_surfaceView = QJNIObjectPrivate(); - } else { - m_surfaceHolder = new AndroidSurfaceHolder(holder); - connect(m_surfaceHolder, &AndroidSurfaceHolder::surfaceCreated, - this, &AndroidSurfaceView::surfaceCreated); - { // Lock now to avoid a race with handleSurfaceCreated() - QMutexLocker locker(shLock()); - m_window = QWindow::fromWinId(WId(m_surfaceView.object())); - - if (m_pendingVisible != -1) - m_window->setVisible(m_pendingVisible); - if (m_pendingGeometry.isValid()) - m_window->setGeometry(m_pendingGeometry); - } - } -} - -AndroidSurfaceView::~AndroidSurfaceView() -{ - delete m_surfaceHolder; - delete m_window; -} - -AndroidSurfaceHolder *AndroidSurfaceView::holder() const -{ - return m_surfaceHolder; -} - -void AndroidSurfaceView::setVisible(bool v) -{ - if (m_window) - m_window->setVisible(v); - else - m_pendingVisible = int(v); -} - -void AndroidSurfaceView::setGeometry(int x, int y, int width, int height) -{ - if (m_window) - m_window->setGeometry(x, y, width, height); - else - m_pendingGeometry = QRect(x, y, width, height); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidsurfaceview.h b/src/plugins/android/src/wrappers/jni/androidsurfaceview.h deleted file mode 100644 index ef603061d..000000000 --- a/src/plugins/android/src/wrappers/jni/androidsurfaceview.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDSURFACEVIEW_H -#define ANDROIDSURFACEVIEW_H - -#include <QtCore/private/qjni_p.h> -#include <qrect.h> -#include <QtCore/qrunnable.h> - -QT_BEGIN_NAMESPACE - -class QWindow; - -class AndroidSurfaceHolder : public QObject -{ - Q_OBJECT -public: - ~AndroidSurfaceHolder(); - - jobject surfaceHolder() const; - bool isSurfaceCreated() const; - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void surfaceCreated(); - -private: - AndroidSurfaceHolder(QJNIObjectPrivate object); - - static void handleSurfaceCreated(JNIEnv*, jobject, jlong id); - static void handleSurfaceDestroyed(JNIEnv*, jobject, jlong id); - - QJNIObjectPrivate m_surfaceHolder; - bool m_surfaceCreated; - - friend class AndroidSurfaceView; -}; - -class AndroidSurfaceView : public QObject -{ - Q_OBJECT -public: - AndroidSurfaceView(); - ~AndroidSurfaceView(); - - AndroidSurfaceHolder *holder() const; - - void setVisible(bool v); - void setGeometry(int x, int y, int width, int height); - -Q_SIGNALS: - void surfaceCreated(); - -private: - QJNIObjectPrivate m_surfaceView; - QWindow *m_window; - AndroidSurfaceHolder *m_surfaceHolder; - int m_pendingVisible; - QRect m_pendingGeometry; -}; - -QT_END_NAMESPACE - -#endif // ANDROIDSURFACEVIEW_H diff --git a/src/plugins/android/src/wrappers/jni/jni.pri b/src/plugins/android/src/wrappers/jni/jni.pri deleted file mode 100644 index 930d7e922..000000000 --- a/src/plugins/android/src/wrappers/jni/jni.pri +++ /dev/null @@ -1,21 +0,0 @@ -QT += core-private - -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/androidmediaplayer.h \ - $$PWD/androidsurfacetexture.h \ - $$PWD/androidmediametadataretriever.h \ - $$PWD/androidcamera.h \ - $$PWD/androidmultimediautils.h \ - $$PWD/androidmediarecorder.h \ - $$PWD/androidsurfaceview.h - -SOURCES += \ - $$PWD/androidmediaplayer.cpp \ - $$PWD/androidsurfacetexture.cpp \ - $$PWD/androidmediametadataretriever.cpp \ - $$PWD/androidcamera.cpp \ - $$PWD/androidmultimediautils.cpp \ - $$PWD/androidmediarecorder.cpp \ - $$PWD/androidsurfaceview.cpp diff --git a/src/plugins/avfoundation/CMakeLists.txt b/src/plugins/avfoundation/CMakeLists.txt deleted file mode 100644 index 859f05a6a..000000000 --- a/src/plugins/avfoundation/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Generated from avfoundation.pro. - -add_subdirectory(mediaplayer) -if(NOT TVOS) - add_subdirectory(camera) -endif() diff --git a/src/plugins/avfoundation/avfoundation.pro b/src/plugins/avfoundation/avfoundation.pro deleted file mode 100644 index 1110e196b..000000000 --- a/src/plugins/avfoundation/avfoundation.pro +++ /dev/null @@ -1,4 +0,0 @@ -TEMPLATE = subdirs - -SUBDIRS += mediaplayer -!tvos: SUBDIRS += camera diff --git a/src/plugins/avfoundation/camera/CMakeLists.txt b/src/plugins/avfoundation/camera/CMakeLists.txt deleted file mode 100644 index 1a0eabdb7..000000000 --- a/src/plugins/avfoundation/camera/CMakeLists.txt +++ /dev/null @@ -1,67 +0,0 @@ -# Generated from camera.pro. - -##################################################################### -## AVFServicePlugin Plugin: -##################################################################### - -qt_internal_add_plugin(AVFServicePlugin - OUTPUT_NAME qavfcamera - TYPE mediaservice - SOURCES - avfaudioencodersettingscontrol.h avfaudioencodersettingscontrol.mm - avfaudioinputselectorcontrol.h avfaudioinputselectorcontrol.mm - avfcameracontrol.h avfcameracontrol.mm - avfcameradebug.h - avfcameradevicecontrol.h avfcameradevicecontrol.mm - avfcameraexposurecontrol.h avfcameraexposurecontrol.mm - avfcamerafocuscontrol.h avfcamerafocuscontrol.mm - avfcamerametadatacontrol.h avfcamerametadatacontrol.mm - avfcamerarenderercontrol.h avfcamerarenderercontrol.mm - avfcameraservice.h avfcameraservice.mm - avfcameraserviceplugin.h avfcameraserviceplugin.mm - avfcamerasession.h avfcamerasession.mm - avfcamerautility.h avfcamerautility.mm - avfcamerawindowcontrol.h avfcamerawindowcontrol.mm - avfcapturedestinationcontrol.h avfcapturedestinationcontrol.mm - avfimagecapturecontrol.h avfimagecapturecontrol.mm - avfimageencodercontrol.h avfimageencodercontrol.mm - avfmediacontainercontrol.h avfmediacontainercontrol.mm - avfmediavideoprobecontrol.h avfmediavideoprobecontrol.mm - avfstoragelocation.h avfstoragelocation.mm - avfvideoencodersettingscontrol.h avfvideoencodersettingscontrol.mm - PUBLIC_LIBRARIES - ${FWAudioToolbox} - ${FWCoreAudio} - ${FWCoreFoundation} - ${FWCoreMedia} - ${FWFoundation} - ${FWQuartzCore} - Qt::Core - Qt::Gui - Qt::MultimediaPrivate - Qt::Network - avfoundation -) - -#### Keys ignored in scope 1:.:.:camera.pro:<TRUE>: -# OTHER_FILES = "avfcamera.json" - -## Scopes: -##################################################################### - -qt_internal_extend_target(AVFServicePlugin CONDITION MACOS - SOURCES - avfmediarecordercontrol.h avfmediarecordercontrol.mm - PUBLIC_LIBRARIES - ${FWAppKit} - ${FWAudioUnit} -) - -qt_internal_extend_target(AVFServicePlugin CONDITION IOS - SOURCES - avfmediaassetwriter.h avfmediaassetwriter.mm - avfmediarecordercontrol_ios.h avfmediarecordercontrol_ios.mm - PUBLIC_LIBRARIES - ${FWCoreGraphics} - ${FWCoreVideo} -) diff --git a/src/plugins/avfoundation/camera/avfaudioencodersettingscontrol.h b/src/plugins/avfoundation/camera/avfaudioencodersettingscontrol.h deleted file mode 100644 index 94aa6a8f0..000000000 --- a/src/plugins/avfoundation/camera/avfaudioencodersettingscontrol.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFAUDIOENCODERSETTINGSCONTROL_H -#define AVFAUDIOENCODERSETTINGSCONTROL_H - -#include <qaudioencodersettingscontrol.h> - -@class NSDictionary; -@class AVCaptureAudioDataOutput; - -QT_BEGIN_NAMESPACE - -class AVFCameraService; - -class AVFAudioEncoderSettingsControl : public QAudioEncoderSettingsControl -{ -public: - explicit AVFAudioEncoderSettingsControl(AVFCameraService *service); - - QStringList supportedAudioCodecs() const override; - QString codecDescription(const QString &codecName) const override; - QList<int> supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous = nullptr) const override; - QAudioEncoderSettings audioSettings() const override; - void setAudioSettings(const QAudioEncoderSettings &settings) override; - - NSDictionary *applySettings(); - void unapplySettings(); - -private: - AVFCameraService *m_service; - - QAudioEncoderSettings m_requestedSettings; - QAudioEncoderSettings m_actualSettings; -}; - -QT_END_NAMESPACE - -#endif // AVFAUDIOENCODERSETTINGSCONTROL_H diff --git a/src/plugins/avfoundation/camera/avfaudioencodersettingscontrol.mm b/src/plugins/avfoundation/camera/avfaudioencodersettingscontrol.mm deleted file mode 100644 index 1aeb44ff6..000000000 --- a/src/plugins/avfoundation/camera/avfaudioencodersettingscontrol.mm +++ /dev/null @@ -1,226 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfaudioencodersettingscontrol.h" - -#include "avfcameraservice.h" -#include "avfcamerasession.h" - -#include <AVFoundation/AVFoundation.h> -#include <CoreAudio/CoreAudioTypes.h> - -QT_BEGIN_NAMESPACE - -struct AudioCodecInfo -{ - QString description; - int id; - - AudioCodecInfo() : id(0) { } - AudioCodecInfo(const QString &desc, int i) - : description(desc), id(i) - { } -}; - -typedef QMap<QString, AudioCodecInfo> SupportedAudioCodecs; -Q_GLOBAL_STATIC_WITH_ARGS(QString , defaultCodec, (QLatin1String("aac"))) -Q_GLOBAL_STATIC(SupportedAudioCodecs, supportedCodecs) - -AVFAudioEncoderSettingsControl::AVFAudioEncoderSettingsControl(AVFCameraService *service) - : QAudioEncoderSettingsControl() - , m_service(service) -{ - if (supportedCodecs->isEmpty()) { - supportedCodecs->insert(QStringLiteral("lpcm"), - AudioCodecInfo(QStringLiteral("Linear PCM"), - kAudioFormatLinearPCM)); - supportedCodecs->insert(QStringLiteral("ulaw"), - AudioCodecInfo(QStringLiteral("PCM Mu-Law 2:1"), - kAudioFormatULaw)); - supportedCodecs->insert(QStringLiteral("alaw"), - AudioCodecInfo(QStringLiteral("PCM A-Law 2:1"), - kAudioFormatALaw)); - supportedCodecs->insert(QStringLiteral("ima4"), - AudioCodecInfo(QStringLiteral("IMA 4:1 ADPCM"), - kAudioFormatAppleIMA4)); - supportedCodecs->insert(QStringLiteral("alac"), - AudioCodecInfo(QStringLiteral("Apple Lossless Audio Codec"), - kAudioFormatAppleLossless)); - supportedCodecs->insert(QStringLiteral("aac"), - AudioCodecInfo(QStringLiteral("MPEG-4 Low Complexity AAC"), - kAudioFormatMPEG4AAC)); - supportedCodecs->insert(QStringLiteral("aach"), - AudioCodecInfo(QStringLiteral("MPEG-4 High Efficiency AAC"), - kAudioFormatMPEG4AAC_HE)); - supportedCodecs->insert(QStringLiteral("aacl"), - AudioCodecInfo(QStringLiteral("MPEG-4 AAC Low Delay"), - kAudioFormatMPEG4AAC_LD)); - supportedCodecs->insert(QStringLiteral("aace"), - AudioCodecInfo(QStringLiteral("MPEG-4 AAC Enhanced Low Delay"), - kAudioFormatMPEG4AAC_ELD)); - supportedCodecs->insert(QStringLiteral("aacf"), - AudioCodecInfo(QStringLiteral("MPEG-4 AAC Enhanced Low Delay with SBR"), - kAudioFormatMPEG4AAC_ELD_SBR)); - supportedCodecs->insert(QStringLiteral("aacp"), - AudioCodecInfo(QStringLiteral("MPEG-4 HE AAC V2"), - kAudioFormatMPEG4AAC_HE_V2)); - supportedCodecs->insert(QStringLiteral("ilbc"), - AudioCodecInfo(QStringLiteral("iLBC"), - kAudioFormatiLBC)); - } -} - -QStringList AVFAudioEncoderSettingsControl::supportedAudioCodecs() const -{ - return supportedCodecs->keys(); -} - -QString AVFAudioEncoderSettingsControl::codecDescription(const QString &codecName) const -{ - return supportedCodecs->value(codecName).description; -} - -QList<int> AVFAudioEncoderSettingsControl::supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const -{ - Q_UNUSED(settings); - - if (continuous) - *continuous = true; - - return QList<int>() << 8000 << 96000; -} - -QAudioEncoderSettings AVFAudioEncoderSettingsControl::audioSettings() const -{ - return m_actualSettings; -} - -void AVFAudioEncoderSettingsControl::setAudioSettings(const QAudioEncoderSettings &settings) -{ - if (m_requestedSettings == settings) - return; - - m_requestedSettings = m_actualSettings = settings; -} - -NSDictionary *AVFAudioEncoderSettingsControl::applySettings() -{ - if (m_service->session()->state() != QCamera::LoadedState && - m_service->session()->state() != QCamera::ActiveState) { - return nil; - } - - NSMutableDictionary *settings = [NSMutableDictionary dictionary]; - - QString codec = m_requestedSettings.codec().isEmpty() ? *defaultCodec : m_requestedSettings.codec(); - if (!supportedCodecs->contains(codec)) { - qWarning("Unsupported codec: '%s'", codec.toLocal8Bit().constData()); - codec = *defaultCodec; - } - [settings setObject:[NSNumber numberWithInt:supportedCodecs->value(codec).id] forKey:AVFormatIDKey]; - m_actualSettings.setCodec(codec); - -#ifdef Q_OS_OSX - if (m_requestedSettings.encodingMode() == QMultimedia::ConstantQualityEncoding) { - int quality; - switch (m_requestedSettings.quality()) { - case QMultimedia::VeryLowQuality: - quality = AVAudioQualityMin; - break; - case QMultimedia::LowQuality: - quality = AVAudioQualityLow; - break; - case QMultimedia::HighQuality: - quality = AVAudioQualityHigh; - break; - case QMultimedia::VeryHighQuality: - quality = AVAudioQualityMax; - break; - case QMultimedia::NormalQuality: - default: - quality = AVAudioQualityMedium; - break; - } - [settings setObject:[NSNumber numberWithInt:quality] forKey:AVEncoderAudioQualityKey]; - - } else -#endif - if (m_requestedSettings.bitRate() > 0){ - [settings setObject:[NSNumber numberWithInt:m_requestedSettings.bitRate()] forKey:AVEncoderBitRateKey]; - } - - int sampleRate = m_requestedSettings.sampleRate(); - int channelCount = m_requestedSettings.channelCount(); - -#ifdef Q_OS_IOS - // Some keys are mandatory only on iOS - if (codec == QLatin1String("lpcm")) { - [settings setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey]; - [settings setObject:[NSNumber numberWithInt:NO] forKey:AVLinearPCMIsBigEndianKey]; - [settings setObject:[NSNumber numberWithInt:NO] forKey:AVLinearPCMIsFloatKey]; - [settings setObject:[NSNumber numberWithInt:NO] forKey:AVLinearPCMIsNonInterleaved]; - } - - if (codec == QLatin1String("alac")) - [settings setObject:[NSNumber numberWithInt:24] forKey:AVEncoderBitDepthHintKey]; - - if (sampleRate <= 0) - sampleRate = codec == QLatin1String("ilbc") ? 8000 : 44100; - if (channelCount <= 0) - channelCount = codec == QLatin1String("ilbc") ? 1 : 2; -#endif - - if (sampleRate > 0) { - [settings setObject:[NSNumber numberWithInt:sampleRate] forKey:AVSampleRateKey]; - m_actualSettings.setSampleRate(sampleRate); - } - if (channelCount > 0) { - [settings setObject:[NSNumber numberWithInt:channelCount] forKey:AVNumberOfChannelsKey]; - m_actualSettings.setChannelCount(channelCount); - } - - return settings; -} - -void AVFAudioEncoderSettingsControl::unapplySettings() -{ - m_actualSettings = m_requestedSettings; -} - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.h b/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.h deleted file mode 100644 index a902a71f9..000000000 --- a/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFAUDIOINPUTSELECTORCONTROL_H -#define AVFAUDIOINPUTSELECTORCONTROL_H - -#include <QtMultimedia/qaudioinputselectorcontrol.h> -#include <QtCore/qstringlist.h> - -#import <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraSession; -class AVFCameraService; - -class AVFAudioInputSelectorControl : public QAudioInputSelectorControl -{ -Q_OBJECT -public: - AVFAudioInputSelectorControl(AVFCameraService *service, QObject *parent = nullptr); - ~AVFAudioInputSelectorControl(); - - QList<QString> availableInputs() const override; - QString inputDescription(const QString &name) const override; - QString defaultInput() const override; - QString activeInput() const override; - -public Q_SLOTS: - void setActiveInput(const QString &name) override; - -public: - //device changed since the last createCaptureDevice() - bool isDirty() const { return m_dirty; } - AVCaptureDevice *createCaptureDevice(); - -private: - QString m_activeInput; - bool m_dirty; - QString m_defaultDevice; - QStringList m_devices; - QMap<QString, QString> m_deviceDescriptions; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.mm b/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.mm deleted file mode 100644 index de29fd970..000000000 --- a/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.mm +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfcameradebug.h" -#include "avfaudioinputselectorcontrol.h" -#include "avfcameraservice.h" - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -AVFAudioInputSelectorControl::AVFAudioInputSelectorControl(AVFCameraService *service, QObject *parent) - : QAudioInputSelectorControl(parent) - , m_dirty(true) -{ - Q_UNUSED(service); - NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio]; - for (AVCaptureDevice *device in videoDevices) { - QString deviceId = QString::fromUtf8([[device uniqueID] UTF8String]); - m_devices << deviceId; - m_deviceDescriptions.insert(deviceId, - QString::fromUtf8([[device localizedName] UTF8String])); - } - - AVCaptureDevice *defaultDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; - if (defaultDevice) { - m_defaultDevice = QString::fromUtf8([defaultDevice.uniqueID UTF8String]); - m_activeInput = m_defaultDevice; - } -} - -AVFAudioInputSelectorControl::~AVFAudioInputSelectorControl() -{ -} - -QList<QString> AVFAudioInputSelectorControl::availableInputs() const -{ - return m_devices; -} - -QString AVFAudioInputSelectorControl::inputDescription(const QString &name) const -{ - return m_deviceDescriptions.value(name); -} - -QString AVFAudioInputSelectorControl::defaultInput() const -{ - return m_defaultDevice; -} - -QString AVFAudioInputSelectorControl::activeInput() const -{ - return m_activeInput; -} - -void AVFAudioInputSelectorControl::setActiveInput(const QString &name) -{ - if (name != m_activeInput) { - m_activeInput = name; - m_dirty = true; - - Q_EMIT activeInputChanged(m_activeInput); - } -} - -AVCaptureDevice *AVFAudioInputSelectorControl::createCaptureDevice() -{ - m_dirty = false; - AVCaptureDevice *device = nullptr; - - if (!m_activeInput.isEmpty()) { - device = [AVCaptureDevice deviceWithUniqueID: - [NSString stringWithUTF8String: - m_activeInput.toUtf8().constData()]]; - } - - if (!device) - device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; - - return device; -} - -#include "moc_avfaudioinputselectorcontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcamera.json b/src/plugins/avfoundation/camera/avfcamera.json deleted file mode 100644 index e4310b62c..000000000 --- a/src/plugins/avfoundation/camera/avfcamera.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["avfoundationcamera"], - "Services": ["org.qt-project.qt.camera"] -} diff --git a/src/plugins/avfoundation/camera/avfcameracontrol.h b/src/plugins/avfoundation/camera/avfcameracontrol.h deleted file mode 100644 index 1792645f7..000000000 --- a/src/plugins/avfoundation/camera/avfcameracontrol.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFCAMERACONTROL_H -#define AVFCAMERACONTROL_H - -#include <QtCore/qobject.h> - -#include <QtMultimedia/qcameracontrol.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraSession; -class AVFCameraService; -@class AVCaptureDeviceFormat; -@class AVCaptureConnection; - -class AVFCameraControl : public QCameraControl -{ -Q_OBJECT -public: - AVFCameraControl(AVFCameraService *service, QObject *parent = nullptr); - ~AVFCameraControl(); - - QCamera::State state() const override; - void setState(QCamera::State state) override; - - QCamera::Status status() const override; - - QCamera::CaptureModes captureMode() const override; - void setCaptureMode(QCamera::CaptureModes) override; - bool isCaptureModeSupported(QCamera::CaptureModes mode) const override; - - bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const override; - - QCamera::LockTypes supportedLocks() const override; - - QCamera::LockStatus lockStatus(QCamera::LockType lock) const override; - - void searchAndLock(QCamera::LockTypes locks) override; - void unlock(QCamera::LockTypes locks) override; - - QList<QCameraViewfinderSettings> supportedViewfinderSettings() const override; - QCameraViewfinderSettings viewfinderSettings() const override; - void setViewfinderSettings(const QCameraViewfinderSettings &settings) override; - - // "Converters": - static QVideoFrame::PixelFormat QtPixelFormatFromCVFormat(unsigned avPixelFormat); - static bool CVPixelFormatFromQtFormat(QVideoFrame::PixelFormat qtFormat, unsigned &conv); - -private: - void setResolution(const QSize &resolution); - void setFramerate(qreal minFPS, qreal maxFPS, bool useActive); - void setPixelFormat(QVideoFrame::PixelFormat newFormat); - AVCaptureDeviceFormat *findBestFormatMatch(const QCameraViewfinderSettings &settings) const; - QList<QVideoFrame::PixelFormat> viewfinderPixelFormats() const; - bool convertPixelFormatIfSupported(QVideoFrame::PixelFormat format, unsigned &avfFormat) const; - bool applySettings(const QCameraViewfinderSettings &settings); - QCameraViewfinderSettings requestedSettings() const; - - AVCaptureConnection *videoConnection() const; - -private Q_SLOTS: - void updateStatus(); - -private: - friend class AVFCameraSession; - AVFCameraSession *m_session; - AVFCameraService *m_service; - QCameraViewfinderSettings m_settings; - - QCamera::State m_state; - QCamera::Status m_lastStatus; - QCamera::CaptureModes m_captureMode; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcameracontrol.mm b/src/plugins/avfoundation/camera/avfcameracontrol.mm deleted file mode 100644 index a6bc91995..000000000 --- a/src/plugins/avfoundation/camera/avfcameracontrol.mm +++ /dev/null @@ -1,530 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfcameradebug.h" -#include "avfcameracontrol.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" -#include "avfcamerautility.h" -#include "avfcamerarenderercontrol.h" -#include "qabstractvideosurface.h" - -QT_USE_NAMESPACE - -AVFCameraControl::AVFCameraControl(AVFCameraService *service, QObject *parent) - : QCameraControl(parent) - , m_session(service->session()) - , m_service(service) - , m_state(QCamera::UnloadedState) - , m_lastStatus(QCamera::UnloadedStatus) - , m_captureMode(QCamera::CaptureStillImage) -{ - Q_UNUSED(service); - connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateStatus())); - connect(this, &AVFCameraControl::captureModeChanged, m_session, &AVFCameraSession::onCaptureModeChanged); -} - -AVFCameraControl::~AVFCameraControl() -{ -} - -QCamera::State AVFCameraControl::state() const -{ - return m_state; -} - -void AVFCameraControl::setState(QCamera::State state) -{ - if (m_state == state) - return; - m_state = state; - m_session->setState(state); - - Q_EMIT stateChanged(m_state); - updateStatus(); -} - -QCamera::Status AVFCameraControl::status() const -{ - static QCamera::Status statusTable[3][3] = { - { QCamera::UnloadedStatus, QCamera::UnloadingStatus, QCamera::StoppingStatus }, //Unloaded state - { QCamera::LoadingStatus, QCamera::LoadedStatus, QCamera::StoppingStatus }, //Loaded state - { QCamera::LoadingStatus, QCamera::StartingStatus, QCamera::ActiveStatus } //ActiveState - }; - - return statusTable[m_state][m_session->state()]; -} - -void AVFCameraControl::updateStatus() -{ - QCamera::Status newStatus = status(); - - if (m_lastStatus != newStatus) { - qDebugCamera() << "Camera status changed: " << m_lastStatus << " -> " << newStatus; - m_lastStatus = newStatus; - Q_EMIT statusChanged(m_lastStatus); - } -} - -QCamera::CaptureModes AVFCameraControl::captureMode() const -{ - return m_captureMode; -} - -void AVFCameraControl::setCaptureMode(QCamera::CaptureModes mode) -{ - if (m_captureMode == mode) - return; - - m_captureMode = mode; - Q_EMIT captureModeChanged(mode); -} - -bool AVFCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const -{ - return true; -} - -bool AVFCameraControl::canChangeProperty(QCameraControl::PropertyChangeType changeType, QCamera::Status status) const -{ - Q_UNUSED(changeType); - Q_UNUSED(status); - - return true; -} - -QCamera::LockTypes AVFCameraControl::supportedLocks() const -{ - return {}; -} - -QCamera::LockStatus AVFCameraControl::lockStatus(QCamera::LockType) const -{ - return QCamera::Unlocked; -} - -void AVFCameraControl::searchAndLock(QCamera::LockTypes locks) -{ - Q_UNUSED(locks); -} - -void AVFCameraControl::unlock(QCamera::LockTypes locks) -{ - Q_UNUSED(locks); -} - - -namespace { - -bool qt_framerates_sane(const QCameraViewfinderSettings &settings) -{ - const qreal minFPS = settings.minimumFrameRate(); - const qreal maxFPS = settings.maximumFrameRate(); - - if (minFPS < 0. || maxFPS < 0.) - return false; - - return !maxFPS || maxFPS >= minFPS; -} - -} - -QList<QCameraViewfinderSettings> AVFCameraControl::supportedViewfinderSettings() const -{ - QList<QCameraViewfinderSettings> supportedSettings; - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - if (!captureDevice) { - qDebugCamera() << Q_FUNC_INFO << "no capture device found"; - return supportedSettings; - } - - QVector<AVFPSRange> framerates; - - QVector<QVideoFrame::PixelFormat> pixelFormats(viewfinderPixelFormats()); - - if (!pixelFormats.size()) - pixelFormats << QVideoFrame::Format_Invalid; // The default value. - - if (!captureDevice.formats || !captureDevice.formats.count) { - qDebugCamera() << Q_FUNC_INFO << "no capture device formats found"; - return supportedSettings; - } - - const QVector<AVCaptureDeviceFormat *> formats(qt_unique_device_formats(captureDevice, - m_service->session()->defaultCodec())); - for (int i = 0; i < formats.size(); ++i) { - AVCaptureDeviceFormat *format = formats[i]; - - const QSize res(qt_device_format_resolution(format)); - if (res.isNull() || !res.isValid()) - continue; - const QSize par(qt_device_format_pixel_aspect_ratio(format)); - if (par.isNull() || !par.isValid()) - continue; - - framerates = qt_device_format_framerates(format); - if (!framerates.size()) - framerates << AVFPSRange(); // The default value. - - for (int i = 0; i < pixelFormats.size(); ++i) { - for (int j = 0; j < framerates.size(); ++j) { - QCameraViewfinderSettings newSet; - newSet.setResolution(res); - newSet.setPixelAspectRatio(par); - newSet.setPixelFormat(pixelFormats[i]); - newSet.setMinimumFrameRate(framerates[j].first); - newSet.setMaximumFrameRate(framerates[j].second); - supportedSettings << newSet; - } - } - } - - return supportedSettings; -} - -QCameraViewfinderSettings AVFCameraControl::viewfinderSettings() const -{ - QCameraViewfinderSettings settings = m_settings; - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - if (!captureDevice) { - qDebugCamera() << Q_FUNC_INFO << "no capture device found"; - return settings; - } - - if (m_service->session()->state() != QCamera::LoadedState && - m_service->session()->state() != QCamera::ActiveState) { - return settings; - } - - if (!captureDevice.activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "no active capture device format"; - return settings; - } - - const QSize res(qt_device_format_resolution(captureDevice.activeFormat)); - const QSize par(qt_device_format_pixel_aspect_ratio(captureDevice.activeFormat)); - if (res.isNull() || !res.isValid() || par.isNull() || !par.isValid()) { - qDebugCamera() << Q_FUNC_INFO << "failed to obtain resolution/pixel aspect ratio"; - return settings; - } - - settings.setResolution(res); - settings.setPixelAspectRatio(par); - - const AVFPSRange fps = qt_current_framerates(captureDevice, videoConnection()); - settings.setMinimumFrameRate(fps.first); - settings.setMaximumFrameRate(fps.second); - - AVCaptureVideoDataOutput *videoOutput = m_service->videoOutput() ? m_service->videoOutput()->videoDataOutput() : nullptr; - if (videoOutput) { - NSObject *obj = [videoOutput.videoSettings objectForKey:(id)kCVPixelBufferPixelFormatTypeKey]; - if (obj && [obj isKindOfClass:[NSNumber class]]) { - NSNumber *nsNum = static_cast<NSNumber *>(obj); - settings.setPixelFormat(QtPixelFormatFromCVFormat([nsNum unsignedIntValue])); - } - } - - return settings; -} - -void AVFCameraControl::setViewfinderSettings(const QCameraViewfinderSettings &settings) -{ - if (m_settings == settings) - return; - - m_settings = settings; -#if defined(Q_OS_IOS) - bool active = m_service->session()->state() == QCamera::ActiveState; - if (active) - [m_service->session()->captureSession() beginConfiguration]; - applySettings(m_settings); - if (active) - [m_service->session()->captureSession() commitConfiguration]; -#else - applySettings(m_settings); -#endif -} - -QVideoFrame::PixelFormat AVFCameraControl::QtPixelFormatFromCVFormat(unsigned avPixelFormat) -{ - // BGRA <-> ARGB "swap" is intentional: - // to work correctly with GL_RGBA, color swap shaders - // (in QSG node renderer etc.). - switch (avPixelFormat) { - case kCVPixelFormatType_32ARGB: - return QVideoFrame::Format_BGRA32; - case kCVPixelFormatType_32BGRA: - return QVideoFrame::Format_ARGB32; - case kCVPixelFormatType_24RGB: - return QVideoFrame::Format_RGB24; - case kCVPixelFormatType_24BGR: - return QVideoFrame::Format_BGR24; - case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: - case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange: - return QVideoFrame::Format_NV12; - case kCVPixelFormatType_422YpCbCr8: - return QVideoFrame::Format_UYVY; - case kCVPixelFormatType_422YpCbCr8_yuvs: - return QVideoFrame::Format_YUYV; - default: - return QVideoFrame::Format_Invalid; - } -} - -bool AVFCameraControl::CVPixelFormatFromQtFormat(QVideoFrame::PixelFormat qtFormat, unsigned &conv) -{ - // BGRA <-> ARGB "swap" is intentional: - // to work correctly with GL_RGBA, color swap shaders - // (in QSG node renderer etc.). - switch (qtFormat) { - case QVideoFrame::Format_ARGB32: - conv = kCVPixelFormatType_32BGRA; - break; - case QVideoFrame::Format_BGRA32: - conv = kCVPixelFormatType_32ARGB; - break; - case QVideoFrame::Format_NV12: - conv = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange; - break; - case QVideoFrame::Format_UYVY: - conv = kCVPixelFormatType_422YpCbCr8; - break; - case QVideoFrame::Format_YUYV: - conv = kCVPixelFormatType_422YpCbCr8_yuvs; - break; - // These two formats below are not supported - // by QSGVideoNodeFactory_RGB, so for now I have to - // disable them. - /* - case QVideoFrame::Format_RGB24: - conv = kCVPixelFormatType_24RGB; - break; - case QVideoFrame::Format_BGR24: - conv = kCVPixelFormatType_24BGR; - break; - */ - default: - return false; - } - - return true; -} - -AVCaptureDeviceFormat *AVFCameraControl::findBestFormatMatch(const QCameraViewfinderSettings &settings) const -{ - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - if (!captureDevice || settings.isNull()) - return nil; - - const QSize &resolution = settings.resolution(); - if (!resolution.isNull() && resolution.isValid()) { - // Either the exact match (including high resolution for images on iOS) - // or a format with a resolution close to the requested one. - return qt_find_best_resolution_match(captureDevice, resolution, - m_service->session()->defaultCodec(), false); - } - - // No resolution requested, what about framerates? - if (!qt_framerates_sane(settings)) { - qDebugCamera() << Q_FUNC_INFO << "invalid framerate requested (min/max):" - << settings.minimumFrameRate() << settings.maximumFrameRate(); - return nil; - } - - const qreal minFPS(settings.minimumFrameRate()); - const qreal maxFPS(settings.maximumFrameRate()); - if (minFPS || maxFPS) - return qt_find_best_framerate_match(captureDevice, - m_service->session()->defaultCodec(), - maxFPS ? maxFPS : minFPS); - // Ignore PAR for the moment (PAR without resolution can - // pick a format with really bad resolution). - // No need to test pixel format, just return settings. - - return nil; -} - -QVector<QVideoFrame::PixelFormat> AVFCameraControl::viewfinderPixelFormats() const -{ - QVector<QVideoFrame::PixelFormat> qtFormats; - - AVCaptureVideoDataOutput *videoOutput = m_service->videoOutput() ? m_service->videoOutput()->videoDataOutput() : nullptr; - if (!videoOutput) { - qDebugCamera() << Q_FUNC_INFO << "no video output found"; - return qtFormats; - } - - NSArray *pixelFormats = [videoOutput availableVideoCVPixelFormatTypes]; - - for (NSObject *obj in pixelFormats) { - if (![obj isKindOfClass:[NSNumber class]]) - continue; - - NSNumber *formatAsNSNumber = static_cast<NSNumber *>(obj); - // It's actually FourCharCode (== UInt32): - const QVideoFrame::PixelFormat qtFormat(QtPixelFormatFromCVFormat([formatAsNSNumber unsignedIntValue])); - if (qtFormat != QVideoFrame::Format_Invalid - && !qtFormats.contains(qtFormat)) { // Can happen, for example, with 8BiPlanar existing in video/full range. - qtFormats << qtFormat; - } - } - - return qtFormats; -} - -bool AVFCameraControl::convertPixelFormatIfSupported(QVideoFrame::PixelFormat qtFormat, - unsigned &avfFormat)const -{ - AVCaptureVideoDataOutput *videoOutput = m_service->videoOutput() ? m_service->videoOutput()->videoDataOutput() : nullptr; - if (!videoOutput) - return false; - - unsigned conv = 0; - if (!CVPixelFormatFromQtFormat(qtFormat, conv)) - return false; - - NSArray *formats = [videoOutput availableVideoCVPixelFormatTypes]; - if (!formats || !formats.count) - return false; - - if (m_service->videoOutput()->surface()) { - const QAbstractVideoSurface *surface = m_service->videoOutput()->surface(); - QAbstractVideoBuffer::HandleType h = m_service->videoOutput()->supportsTextures() - ? QAbstractVideoBuffer::GLTextureHandle - : QAbstractVideoBuffer::NoHandle; - if (!surface->supportedPixelFormats(h).contains(qtFormat)) - return false; - } - - bool found = false; - for (NSObject *obj in formats) { - if (![obj isKindOfClass:[NSNumber class]]) - continue; - - NSNumber *nsNum = static_cast<NSNumber *>(obj); - if ([nsNum unsignedIntValue] == conv) { - avfFormat = conv; - found = true; - } - } - - return found; -} - -bool AVFCameraControl::applySettings(const QCameraViewfinderSettings &settings) -{ - if (m_service->session()->state() != QCamera::LoadedState && - m_service->session()->state() != QCamera::ActiveState) { - return false; - } - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - if (!captureDevice) - return false; - - bool activeFormatChanged = false; - - AVCaptureDeviceFormat *match = findBestFormatMatch(settings); - if (match) { - activeFormatChanged = qt_set_active_format(captureDevice, match, false); - } else { - qDebugCamera() << Q_FUNC_INFO << "matching device format not found"; - // We still can update the pixel format at least. - } - - AVCaptureVideoDataOutput *videoOutput = m_service->videoOutput() ? m_service->videoOutput()->videoDataOutput() : nullptr; - if (videoOutput) { - unsigned avfPixelFormat = 0; - if (!convertPixelFormatIfSupported(settings.pixelFormat(), avfPixelFormat)) { - // If the the pixel format is not specified or invalid, pick the preferred video surface - // format, or if no surface is set, the preferred capture device format - - const QVector<QVideoFrame::PixelFormat> deviceFormats = viewfinderPixelFormats(); - QAbstractVideoSurface *surface = m_service->videoOutput()->surface(); - QVideoFrame::PixelFormat pickedFormat = deviceFormats.first(); - if (surface) { - pickedFormat = QVideoFrame::Format_Invalid; - QAbstractVideoBuffer::HandleType h = m_service->videoOutput()->supportsTextures() - ? QAbstractVideoBuffer::GLTextureHandle - : QAbstractVideoBuffer::NoHandle; - QList<QVideoFrame::PixelFormat> surfaceFormats = surface->supportedPixelFormats(h); - for (int i = 0; i < surfaceFormats.count(); ++i) { - const QVideoFrame::PixelFormat surfaceFormat = surfaceFormats.at(i); - if (deviceFormats.contains(surfaceFormat)) { - pickedFormat = surfaceFormat; - break; - } - } - } - - CVPixelFormatFromQtFormat(pickedFormat, avfPixelFormat); - } - - NSMutableDictionary *videoSettings = [NSMutableDictionary dictionaryWithCapacity:1]; - [videoSettings setObject:[NSNumber numberWithUnsignedInt:avfPixelFormat] - forKey:(id)kCVPixelBufferPixelFormatTypeKey]; - - const AVFConfigurationLock lock(captureDevice); - if (!lock) - qWarning("Failed to set active format (lock failed)"); - - videoOutput.videoSettings = videoSettings; - } - - qt_set_framerate_limits(captureDevice, videoConnection(), settings.minimumFrameRate(), settings.maximumFrameRate()); - - return activeFormatChanged; -} - -QCameraViewfinderSettings AVFCameraControl::requestedSettings() const -{ - return m_settings; -} - -AVCaptureConnection *AVFCameraControl::videoConnection() const -{ - if (!m_service->videoOutput() || !m_service->videoOutput()->videoDataOutput()) - return nil; - - return [m_service->videoOutput()->videoDataOutput() connectionWithMediaType:AVMediaTypeVideo]; -} - -#include "moc_avfcameracontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcameradebug.h b/src/plugins/avfoundation/camera/avfcameradebug.h deleted file mode 100644 index 8838122e0..000000000 --- a/src/plugins/avfoundation/camera/avfcameradebug.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFDEBUG_H -#define AVFDEBUG_H - -#include "qtmultimediaglobal.h" - -#include <QtCore/qdebug.h> - -QT_USE_NAMESPACE - -//#define AVF_DEBUG_CAMERA - -#ifdef AVF_DEBUG_CAMERA -#define qDebugCamera qDebug -#else -#define qDebugCamera QT_NO_QDEBUG_MACRO -#endif - -#endif diff --git a/src/plugins/avfoundation/camera/avfcameradevicecontrol.h b/src/plugins/avfoundation/camera/avfcameradevicecontrol.h deleted file mode 100644 index 0b0d560e8..000000000 --- a/src/plugins/avfoundation/camera/avfcameradevicecontrol.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFCAMERADEVICECONTROL_H -#define AVFCAMERADEVICECONTROL_H - -#include <QtMultimedia/qvideodeviceselectorcontrol.h> -#include <QtCore/qstringlist.h> - -#import <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraSession; -class AVFCameraService; - -class AVFCameraDeviceControl : public QVideoDeviceSelectorControl -{ -Q_OBJECT -public: - AVFCameraDeviceControl(AVFCameraService *service, QObject *parent = nullptr); - ~AVFCameraDeviceControl(); - - int deviceCount() const override; - - QString deviceName(int index) const override; - QString deviceDescription(int index) const override; - QCamera::Position cameraPosition(int index) const override; - int cameraOrientation(int index) const override; - - int defaultDevice() const override; - int selectedDevice() const override; - -public Q_SLOTS: - void setSelectedDevice(int index) override; - -public: - //device changed since the last createCaptureDevice() - bool isDirty() const { return m_dirty; } - AVCaptureDevice *createCaptureDevice(); - -private: - AVFCameraService *m_service; - - int m_selectedDevice; - bool m_dirty; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcameradevicecontrol.mm b/src/plugins/avfoundation/camera/avfcameradevicecontrol.mm deleted file mode 100644 index cf6343754..000000000 --- a/src/plugins/avfoundation/camera/avfcameradevicecontrol.mm +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfcameradebug.h" -#include "avfcameradevicecontrol.h" -#include "avfcameraservice.h" -#include "avfcamerasession.h" - -QT_USE_NAMESPACE - -AVFCameraDeviceControl::AVFCameraDeviceControl(AVFCameraService *service, QObject *parent) - : QVideoDeviceSelectorControl(parent) - , m_service(service) - , m_selectedDevice(0) - , m_dirty(true) -{ - Q_UNUSED(m_service); -} - -AVFCameraDeviceControl::~AVFCameraDeviceControl() -{ -} - -int AVFCameraDeviceControl::deviceCount() const -{ - return AVFCameraSession::availableCameraDevices().count(); -} - -QString AVFCameraDeviceControl::deviceName(int index) const -{ - const QList<AVFCameraInfo> &devices = AVFCameraSession::availableCameraDevices(); - if (index < 0 || index >= devices.count()) - return QString(); - - return QString::fromUtf8(devices.at(index).deviceId); -} - -QString AVFCameraDeviceControl::deviceDescription(int index) const -{ - const QList<AVFCameraInfo> &devices = AVFCameraSession::availableCameraDevices(); - if (index < 0 || index >= devices.count()) - return QString(); - - return devices.at(index).description; -} - -QCamera::Position AVFCameraDeviceControl::cameraPosition(int index) const -{ - const QList<AVFCameraInfo> &devices = AVFCameraSession::availableCameraDevices(); - if (index < 0 || index >= devices.count()) - return QCamera::UnspecifiedPosition; - - return devices.at(index).position; -} - -int AVFCameraDeviceControl::cameraOrientation(int index) const -{ - const QList<AVFCameraInfo> &devices = AVFCameraSession::availableCameraDevices(); - if (index < 0 || index >= devices.count()) - return 0; - - return devices.at(index).orientation; -} - - -int AVFCameraDeviceControl::defaultDevice() const -{ - return AVFCameraSession::defaultCameraIndex(); -} - -int AVFCameraDeviceControl::selectedDevice() const -{ - return m_selectedDevice; -} - -void AVFCameraDeviceControl::setSelectedDevice(int index) -{ - if (index >= 0 && - index < deviceCount() && - index != m_selectedDevice) { - m_dirty = true; - m_selectedDevice = index; - Q_EMIT selectedDeviceChanged(index); - Q_EMIT selectedDeviceChanged(deviceName(index)); - } -} - -AVCaptureDevice *AVFCameraDeviceControl::createCaptureDevice() -{ - m_dirty = false; - AVCaptureDevice *device = nullptr; - - QString deviceId = deviceName(m_selectedDevice); - if (!deviceId.isEmpty()) { - device = [AVCaptureDevice deviceWithUniqueID: - [NSString stringWithUTF8String: - deviceId.toUtf8().constData()]]; - } - - if (!device) - device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; - - return device; -} - -#include "moc_avfcameradevicecontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcameraexposurecontrol.h b/src/plugins/avfoundation/camera/avfcameraexposurecontrol.h deleted file mode 100644 index 6d97bed85..000000000 --- a/src/plugins/avfoundation/camera/avfcameraexposurecontrol.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFCAMERAEXPOSURECONTROL_H -#define AVFCAMERAEXPOSURECONTROL_H - -#include <QtMultimedia/qcameraexposurecontrol.h> -#include <QtMultimedia/qcameraexposure.h> - -#include <QtCore/qglobal.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraSession; -class AVFCameraService; - -class AVFCameraExposureControl : public QCameraExposureControl -{ - Q_OBJECT - -public: - AVFCameraExposureControl(AVFCameraService *service); - - bool isParameterSupported(ExposureParameter parameter) const override; - QVariantList supportedParameterRange(ExposureParameter parameter, - bool *continuous) const override; - - QVariant requestedValue(ExposureParameter parameter) const override; - QVariant actualValue(ExposureParameter parameter) const override; - bool setValue(ExposureParameter parameter, const QVariant &value) override; - - QCameraExposure::FlashModes flashMode() const override; - void setFlashMode(QCameraExposure::FlashModes mode) override; - bool isFlashModeSupported(QCameraExposure::FlashModes mode) const override; - bool isFlashReady() const override; - -private Q_SLOTS: - void cameraStateChanged(QCamera::State newState); - -private: - bool applyFlashSettings(); - - AVFCameraService *m_service; - AVFCameraSession *m_session; - - QVariant m_requestedMode; - QVariant m_requestedCompensation; - QVariant m_requestedShutterSpeed; - QVariant m_requestedISO; - - // Aux. setters: - bool setExposureMode(const QVariant &value); - bool setExposureCompensation(const QVariant &value); - bool setShutterSpeed(const QVariant &value); - bool setISO(const QVariant &value); - - // Set of bits: - QCameraExposure::FlashModes m_supportedModes = QCameraExposure::FlashOff; - // Only one bit set actually: - QCameraExposure::FlashModes m_flashMode = QCameraExposure::FlashOff; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcameraexposurecontrol.mm b/src/plugins/avfoundation/camera/avfcameraexposurecontrol.mm deleted file mode 100644 index 052a88dea..000000000 --- a/src/plugins/avfoundation/camera/avfcameraexposurecontrol.mm +++ /dev/null @@ -1,831 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfcameraexposurecontrol.h" -#include "avfcamerautility.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" -#include "avfcameradebug.h" - -#include <QtCore/qvariant.h> -#include <QtCore/qpointer.h> -#include <QtCore/qdebug.h> -#include <QtCore/qpair.h> - -#include <AVFoundation/AVFoundation.h> - -#include <limits> - -QT_BEGIN_NAMESPACE - -namespace { - -// All these methods to work with exposure/ISO/SS in custom mode do not support macOS. - -#ifdef Q_OS_IOS - -// Misc. helpers to check values/ranges: - -bool qt_check_ISO_conversion(float isoValue) -{ - if (isoValue >= std::numeric_limits<int>::max()) - return false; - if (isoValue <= std::numeric_limits<int>::min()) - return false; - return true; -} - -bool qt_check_ISO_range(AVCaptureDeviceFormat *format) -{ - // Qt is using int for ISO, AVFoundation - float. It looks like the ISO range - // at the moment can be represented by int (it's max - min > 100, etc.). - Q_ASSERT(format); - if (format.maxISO - format.minISO < 1.) { - // ISO is in some strange units? - return false; - } - - return qt_check_ISO_conversion(format.minISO) - && qt_check_ISO_conversion(format.maxISO); -} - -bool qt_check_exposure_duration(AVCaptureDevice *captureDevice, CMTime duration) -{ - Q_ASSERT(captureDevice); - - AVCaptureDeviceFormat *activeFormat = captureDevice.activeFormat; - if (!activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "failed to obtain capture device format"; - return false; - } - - return CMTimeCompare(duration, activeFormat.minExposureDuration) != -1 - && CMTimeCompare(activeFormat.maxExposureDuration, duration) != -1; -} - -bool qt_check_ISO_value(AVCaptureDevice *captureDevice, int newISO) -{ - Q_ASSERT(captureDevice); - - AVCaptureDeviceFormat *activeFormat = captureDevice.activeFormat; - if (!activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "failed to obtain capture device format"; - return false; - } - - return !(newISO < activeFormat.minISO || newISO > activeFormat.maxISO); -} - -bool qt_exposure_duration_equal(AVCaptureDevice *captureDevice, qreal qDuration) -{ - Q_ASSERT(captureDevice); - const CMTime avDuration = CMTimeMakeWithSeconds(qDuration, captureDevice.exposureDuration.timescale); - return !CMTimeCompare(avDuration, captureDevice.exposureDuration); -} - -bool qt_iso_equal(AVCaptureDevice *captureDevice, int iso) -{ - Q_ASSERT(captureDevice); - return qFuzzyCompare(float(iso), captureDevice.ISO); -} - -bool qt_exposure_bias_equal(AVCaptureDevice *captureDevice, qreal bias) -{ - Q_ASSERT(captureDevice); - return qFuzzyCompare(bias, qreal(captureDevice.exposureTargetBias)); -} - -// Converters: - -bool qt_convert_exposure_mode(AVCaptureDevice *captureDevice, QCameraExposure::ExposureMode mode, - AVCaptureExposureMode &avMode) -{ - // Test if mode supported and convert. - Q_ASSERT(captureDevice); - - if (mode == QCameraExposure::ExposureAuto) { - if ([captureDevice isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) { - avMode = AVCaptureExposureModeContinuousAutoExposure; - return true; - } - } - - if (mode == QCameraExposure::ExposureManual) { - if ([captureDevice isExposureModeSupported:AVCaptureExposureModeCustom]) { - avMode = AVCaptureExposureModeCustom; - return true; - } - } - - return false; -} - -// We set ISO/exposure duration with completion handlers, completion handlers try -// to avoid dangling pointers (thus QPointer for QObjects) and not to create -// a reference loop (in case we have ARC). - -void qt_set_exposure_bias(QPointer<AVFCameraService> service, QPointer<AVFCameraExposureControl> control, - AVCaptureDevice *captureDevice, float bias) -{ - Q_ASSERT(captureDevice); - - __block AVCaptureDevice *device = captureDevice; //For ARC. - - void (^completionHandler)(CMTime syncTime) = ^(CMTime) { - // Test that service control is still alive and that - // capture device is our device, if yes - emit actual value changed. - if (service) { - if (control) { - if (service->session() && service->session()->videoCaptureDevice() == device) - Q_EMIT control->actualValueChanged(int(QCameraExposureControl::ExposureCompensation)); - } - } - device = nil; - }; - - [captureDevice setExposureTargetBias:bias completionHandler:completionHandler]; -} - -void qt_set_duration_iso(QPointer<AVFCameraService> service, QPointer<AVFCameraExposureControl> control, - AVCaptureDevice *captureDevice, CMTime duration, float iso) -{ - Q_ASSERT(captureDevice); - - __block AVCaptureDevice *device = captureDevice; //For ARC. - const bool setDuration = CMTimeCompare(duration, AVCaptureExposureDurationCurrent); - const bool setISO = !qFuzzyCompare(iso, AVCaptureISOCurrent); - - void (^completionHandler)(CMTime syncTime) = ^(CMTime) { - // Test that service control is still alive and that - // capture device is our device, if yes - emit actual value changed. - if (service) { - if (control) { - if (service->session() && service->session()->videoCaptureDevice() == device) { - if (setDuration) - Q_EMIT control->actualValueChanged(int(QCameraExposureControl::ShutterSpeed)); - if (setISO) - Q_EMIT control->actualValueChanged(int(QCameraExposureControl::ISO)); - } - } - } - device = nil; - }; - - [captureDevice setExposureModeCustomWithDuration:duration - ISO:iso - completionHandler:completionHandler]; -} - -#endif // defined(Q_OS_IOS) - -} // Unnamed namespace. - -AVFCameraExposureControl::AVFCameraExposureControl(AVFCameraService *service) - : m_service(service), - m_session(nullptr) -{ - Q_ASSERT(service); - m_session = m_service->session(); - Q_ASSERT(m_session); - - connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(cameraStateChanged(QCamera::State))); -} - -bool AVFCameraExposureControl::isParameterSupported(ExposureParameter parameter) const -{ -#ifdef Q_OS_IOS - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) - return false; - - // These are the parameters we have an API to support: - return parameter == QCameraExposureControl::ISO - || parameter == QCameraExposureControl::ShutterSpeed - || parameter == QCameraExposureControl::ExposureCompensation - || parameter == QCameraExposureControl::ExposureMode; -#else - Q_UNUSED(parameter); - return false; -#endif -} - -QVariantList AVFCameraExposureControl::supportedParameterRange(ExposureParameter parameter, - bool *continuous) const -{ - QVariantList parameterRange; -#ifdef Q_OS_IOS - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice || !isParameterSupported(parameter)) { - qDebugCamera() << Q_FUNC_INFO << "parameter not supported"; - return parameterRange; - } - - if (continuous) - *continuous = false; - - AVCaptureDeviceFormat *activeFormat = captureDevice.activeFormat; - - if (parameter == QCameraExposureControl::ISO) { - if (!activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "failed to obtain capture device format"; - return parameterRange; - } - - if (!qt_check_ISO_range(activeFormat)) { - qDebugCamera() << Q_FUNC_INFO << "ISO range can not be represented as int"; - return parameterRange; - } - - parameterRange << QVariant(int(activeFormat.minISO)); - parameterRange << QVariant(int(activeFormat.maxISO)); - if (continuous) - *continuous = true; - } else if (parameter == QCameraExposureControl::ExposureCompensation) { - parameterRange << captureDevice.minExposureTargetBias; - parameterRange << captureDevice.maxExposureTargetBias; - if (continuous) - *continuous = true; - } else if (parameter == QCameraExposureControl::ShutterSpeed) { - if (!activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "failed to obtain capture device format"; - return parameterRange; - } - - // CMTimeGetSeconds returns Float64, test the conversion below, if it's valid? - parameterRange << qreal(CMTimeGetSeconds(activeFormat.minExposureDuration)); - parameterRange << qreal(CMTimeGetSeconds(activeFormat.maxExposureDuration)); - - if (continuous) - *continuous = true; - } else if (parameter == QCameraExposureControl::ExposureMode) { - if ([captureDevice isExposureModeSupported:AVCaptureExposureModeCustom]) - parameterRange << QVariant::fromValue(QCameraExposure::ExposureManual); - - if ([captureDevice isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) - parameterRange << QVariant::fromValue(QCameraExposure::ExposureAuto); - } -#else - Q_UNUSED(parameter); - Q_UNUSED(continuous); -#endif - return parameterRange; -} - -QVariant AVFCameraExposureControl::requestedValue(ExposureParameter parameter) const -{ - if (!isParameterSupported(parameter)) { - qDebugCamera() << Q_FUNC_INFO << "parameter not supported"; - return QVariant(); - } - - if (parameter == QCameraExposureControl::ExposureMode) - return m_requestedMode; - - if (parameter == QCameraExposureControl::ExposureCompensation) - return m_requestedCompensation; - - if (parameter == QCameraExposureControl::ShutterSpeed) - return m_requestedShutterSpeed; - - if (parameter == QCameraExposureControl::ISO) - return m_requestedISO; - - return QVariant(); -} - -QVariant AVFCameraExposureControl::actualValue(ExposureParameter parameter) const -{ -#ifdef Q_OS_IOS - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice || !isParameterSupported(parameter)) { - // Actually, at the moment !captiredevice => !isParameterSupported. - qDebugCamera() << Q_FUNC_INFO << "parameter not supported"; - return QVariant(); - } - - if (parameter == QCameraExposureControl::ExposureMode) { - // This code expects exposureMode to be continuous by default ... - if (captureDevice.exposureMode == AVCaptureExposureModeContinuousAutoExposure) - return QVariant::fromValue(QCameraExposure::ExposureAuto); - return QVariant::fromValue(QCameraExposure::ExposureManual); - } - - if (parameter == QCameraExposureControl::ExposureCompensation) - return captureDevice.exposureTargetBias; - - if (parameter == QCameraExposureControl::ShutterSpeed) - return qreal(CMTimeGetSeconds(captureDevice.exposureDuration)); - - if (parameter == QCameraExposureControl::ISO) { - if (captureDevice.activeFormat && qt_check_ISO_range(captureDevice.activeFormat) - && qt_check_ISO_conversion(captureDevice.ISO)) { - // Can be represented as int ... - return int(captureDevice.ISO); - } else { - qDebugCamera() << Q_FUNC_INFO << "ISO can not be represented as int"; - return QVariant(); - } - } -#else - Q_UNUSED(parameter); -#endif - return QVariant(); -} - -bool AVFCameraExposureControl::setValue(ExposureParameter parameter, const QVariant &value) -{ - if (parameter == QCameraExposureControl::ExposureMode) - return setExposureMode(value); - else if (parameter == QCameraExposureControl::ExposureCompensation) - return setExposureCompensation(value); - else if (parameter == QCameraExposureControl::ShutterSpeed) - return setShutterSpeed(value); - else if (parameter == QCameraExposureControl::ISO) - return setISO(value); - - return false; -} - -bool AVFCameraExposureControl::setExposureMode(const QVariant &value) -{ -#ifdef Q_OS_IOS - if (!value.canConvert<QCameraExposure::ExposureMode>()) { - qDebugCamera() << Q_FUNC_INFO << "invalid exposure mode value," - << "QCameraExposure::ExposureMode expected"; - return false; - } - - const QCameraExposure::ExposureMode qtMode = value.value<QCameraExposure::ExposureMode>(); - if (qtMode != QCameraExposure::ExposureAuto && qtMode != QCameraExposure::ExposureManual) { - qDebugCamera() << Q_FUNC_INFO << "exposure mode not supported"; - return false; - } - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - m_requestedMode = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ExposureMode)); - return true; - } - - AVCaptureExposureMode avMode = AVCaptureExposureModeAutoExpose; - if (!qt_convert_exposure_mode(captureDevice, qtMode, avMode)) { - qDebugCamera() << Q_FUNC_INFO << "exposure mode not supported"; - return false; - } - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock a capture device" - << "for configuration"; - return false; - } - - m_requestedMode = value; - [captureDevice setExposureMode:avMode]; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ExposureMode)); - Q_EMIT actualValueChanged(int(QCameraExposureControl::ExposureMode)); - - return true; -#else - Q_UNUSED(value); - return false; -#endif -} - -bool AVFCameraExposureControl::setExposureCompensation(const QVariant &value) -{ -#ifdef Q_OS_IOS - if (!value.canConvert<qreal>()) { - qDebugCamera() << Q_FUNC_INFO << "invalid exposure compensation" - <<"value, floating point number expected"; - return false; - } - - const qreal bias = value.toReal(); - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - m_requestedCompensation = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ExposureCompensation)); - return true; - } - - if (bias < captureDevice.minExposureTargetBias || bias > captureDevice.maxExposureTargetBias) { - // TODO: mixed fp types! - qDebugCamera() << Q_FUNC_INFO << "exposure compenstation value is" - << "out of range"; - return false; - } - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return false; - } - - qt_set_exposure_bias(m_service, this, captureDevice, bias); - m_requestedCompensation = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ExposureCompensation)); - - return true; -#else - Q_UNUSED(value); - return false; -#endif -} - -bool AVFCameraExposureControl::setShutterSpeed(const QVariant &value) -{ -#ifdef Q_OS_IOS - if (value.isNull()) - return setExposureMode(QVariant::fromValue(QCameraExposure::ExposureAuto)); - - if (!value.canConvert<qreal>()) { - qDebugCamera() << Q_FUNC_INFO << "invalid shutter speed" - << "value, floating point number expected"; - return false; - } - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - m_requestedShutterSpeed = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ShutterSpeed)); - return true; - } - - const CMTime newDuration = CMTimeMakeWithSeconds(value.toReal(), - captureDevice.exposureDuration.timescale); - if (!qt_check_exposure_duration(captureDevice, newDuration)) { - qDebugCamera() << Q_FUNC_INFO << "shutter speed value is out of range"; - return false; - } - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return false; - } - - // Setting the shutter speed (exposure duration in Apple's terms, - // since there is no shutter actually) will also reset - // exposure mode into custom mode. - qt_set_duration_iso(m_service, this, captureDevice, newDuration, AVCaptureISOCurrent); - - m_requestedShutterSpeed = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ShutterSpeed)); - - return true; -#else - Q_UNUSED(value); - return false; -#endif -} - -bool AVFCameraExposureControl::setISO(const QVariant &value) -{ -#ifdef Q_OS_IOS - if (value.isNull()) - return setExposureMode(QVariant::fromValue(QCameraExposure::ExposureAuto)); - - if (!value.canConvert<int>()) { - qDebugCamera() << Q_FUNC_INFO << "invalid ISO value, int expected"; - return false; - } - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - m_requestedISO = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ISO)); - return true; - } - - if (!qt_check_ISO_value(captureDevice, value.toInt())) { - qDebugCamera() << Q_FUNC_INFO << "ISO value is out of range"; - return false; - } - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock a capture device" - << "for configuration"; - return false; - } - - // Setting the ISO will also reset - // exposure mode to the custom mode. - qt_set_duration_iso(m_service, this, captureDevice, AVCaptureExposureDurationCurrent, value.toInt()); - - m_requestedISO = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ISO)); - - return true; -#else - Q_UNUSED(value); - return false; -#endif -} - -void AVFCameraExposureControl::cameraStateChanged(QCamera::State newState) -{ -#ifdef Q_OS_IOS - if (m_session->state() != QCamera::ActiveState) - return; - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - qDebugCamera() << Q_FUNC_INFO << "capture device is nil, but the session" - << "state is 'active'"; - return; - } - - Q_EMIT parameterRangeChanged(int(QCameraExposureControl::ExposureCompensation)); - Q_EMIT parameterRangeChanged(int(QCameraExposureControl::ExposureMode)); - Q_EMIT parameterRangeChanged(int(QCameraExposureControl::ShutterSpeed)); - Q_EMIT parameterRangeChanged(int(QCameraExposureControl::ISO)); - - const AVFConfigurationLock lock(captureDevice); - - CMTime newDuration = AVCaptureExposureDurationCurrent; - bool setCustomMode = false; - - if (!m_requestedShutterSpeed.isNull() - && !qt_exposure_duration_equal(captureDevice, m_requestedShutterSpeed.toReal())) { - newDuration = CMTimeMakeWithSeconds(m_requestedShutterSpeed.toReal(), - captureDevice.exposureDuration.timescale); - if (!qt_check_exposure_duration(captureDevice, newDuration)) { - qDebugCamera() << Q_FUNC_INFO << "requested exposure duration is out of range"; - return; - } - setCustomMode = true; - } - - float newISO = AVCaptureISOCurrent; - if (!m_requestedISO.isNull() && !qt_iso_equal(captureDevice, m_requestedISO.toInt())) { - newISO = m_requestedISO.toInt(); - if (!qt_check_ISO_value(captureDevice, newISO)) { - qDebugCamera() << Q_FUNC_INFO << "requested ISO value is out of range"; - return; - } - setCustomMode = true; - } - - if (!m_requestedCompensation.isNull() - && !qt_exposure_bias_equal(captureDevice, m_requestedCompensation.toReal())) { - // TODO: mixed fpns. - const qreal bias = m_requestedCompensation.toReal(); - if (bias < captureDevice.minExposureTargetBias || bias > captureDevice.maxExposureTargetBias) { - qDebugCamera() << Q_FUNC_INFO << "exposure compenstation value is" - << "out of range"; - return; - } - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - qt_set_exposure_bias(m_service, this, captureDevice, bias); - } - - // Setting shutter speed (exposure duration) or ISO values - // also reset exposure mode into Custom. With this settings - // we ignore any attempts to set exposure mode. - - if (setCustomMode) { - if (!lock) - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - else - qt_set_duration_iso(m_service, this, captureDevice, newDuration, newISO); - return; - } - - if (!m_requestedMode.isNull()) { - QCameraExposure::ExposureMode qtMode = m_requestedMode.value<QCameraExposure::ExposureMode>(); - AVCaptureExposureMode avMode = AVCaptureExposureModeContinuousAutoExposure; - if (!qt_convert_exposure_mode(captureDevice, qtMode, avMode)) { - qDebugCamera() << Q_FUNC_INFO << "requested exposure mode is not supported"; - return; - } - - if (avMode == captureDevice.exposureMode) - return; - - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - [captureDevice setExposureMode:avMode]; - Q_EMIT actualValueChanged(int(QCameraExposureControl::ExposureMode)); - } -#endif - - if (newState == QCamera::UnloadedState) { - m_supportedModes = QCameraExposure::FlashOff; - Q_EMIT flashReady(false); - } else if (newState == QCamera::ActiveState) { - m_supportedModes = QCameraExposure::FlashOff; - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - qDebugCamera() << Q_FUNC_INFO << "no capture device in 'Active' state"; - Q_EMIT flashReady(false); - return; - } - - if (captureDevice.hasFlash) { - if ([captureDevice isFlashModeSupported:AVCaptureFlashModeOn]) - m_supportedModes |= QCameraExposure::FlashOn; - if ([captureDevice isFlashModeSupported:AVCaptureFlashModeAuto]) - m_supportedModes |= QCameraExposure::FlashAuto; - } - - if (captureDevice.hasTorch && [captureDevice isTorchModeSupported:AVCaptureTorchModeOn]) - m_supportedModes |= QCameraExposure::FlashVideoLight; - - Q_EMIT flashReady(applyFlashSettings()); - } -} - - - -QCameraExposure::FlashModes AVFCameraExposureControl::flashMode() const -{ - return m_flashMode; -} - -void AVFCameraExposureControl::setFlashMode(QCameraExposure::FlashModes mode) -{ - if (m_flashMode == mode) - return; - - if (m_session->state() == QCamera::ActiveState && !isFlashModeSupported(mode)) { - qDebugCamera() << Q_FUNC_INFO << "unsupported mode" << mode; - return; - } - - m_flashMode = mode; - - if (m_session->state() != QCamera::ActiveState) - return; - - applyFlashSettings(); -} - -bool AVFCameraExposureControl::isFlashModeSupported(QCameraExposure::FlashModes mode) const -{ - // From what QCameraExposure has, we can support only these: - // FlashAuto = 0x1, - // FlashOff = 0x2, - // FlashOn = 0x4, - // AVCaptureDevice has these flash modes: - // AVCaptureFlashModeAuto - // AVCaptureFlashModeOff - // AVCaptureFlashModeOn - // QCameraExposure also has: - // FlashTorch = 0x20, --> "Constant light source." - // FlashVideoLight = 0x40. --> "Constant light source." - // AVCaptureDevice: - // AVCaptureTorchModeOff (no mapping) - // AVCaptureTorchModeOn --> FlashVideoLight - // AVCaptureTorchModeAuto (no mapping) - - return m_supportedModes & mode; -} - -bool AVFCameraExposureControl::isFlashReady() const -{ - if (m_session->state() != QCamera::ActiveState) - return false; - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) - return false; - - if (!captureDevice.hasFlash && !captureDevice.hasTorch) - return false; - - if (!isFlashModeSupported(m_flashMode)) - return false; - -#ifdef Q_OS_IOS - // AVCaptureDevice's docs: - // "The flash may become unavailable if, for example, - // the device overheats and needs to cool off." - if (m_flashMode != QCameraExposure::FlashVideoLight) - return [captureDevice isFlashAvailable]; - - return [captureDevice isTorchAvailable]; -#endif - - return true; -} - -bool AVFCameraExposureControl::applyFlashSettings() -{ - Q_ASSERT(m_session->requestedState() == QCamera::ActiveState); - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - qDebugCamera() << Q_FUNC_INFO << "no capture device found"; - return false; - } - - if (!isFlashModeSupported(m_flashMode)) { - qDebugCamera() << Q_FUNC_INFO << "unsupported mode" << m_flashMode; - return false; - } - - if (!captureDevice.hasFlash && !captureDevice.hasTorch) { - // FlashOff is the only mode we support. - // Return false - flash is not ready. - return false; - } - - const AVFConfigurationLock lock(captureDevice); - - if (m_flashMode != QCameraExposure::FlashVideoLight) { - if (captureDevice.torchMode != AVCaptureTorchModeOff) { -#ifdef Q_OS_IOS - if (![captureDevice isTorchAvailable]) { - qDebugCamera() << Q_FUNC_INFO << "torch is not available at the moment"; - return false; - } -#endif - captureDevice.torchMode = AVCaptureTorchModeOff; - } -#ifdef Q_OS_IOS - if (![captureDevice isFlashAvailable]) { - // We'd like to switch flash (into some mode), but it's not available: - qDebugCamera() << Q_FUNC_INFO << "flash is not available at the moment"; - return false; - } -#endif - } else { - if (captureDevice.flashMode != AVCaptureFlashModeOff) { -#ifdef Q_OS_IOS - if (![captureDevice isFlashAvailable]) { - qDebugCamera() << Q_FUNC_INFO << "flash is not available at the moment"; - return false; - } -#endif - captureDevice.flashMode = AVCaptureFlashModeOff; - } - -#ifdef Q_OS_IOS - if (![captureDevice isTorchAvailable]) { - qDebugCamera() << Q_FUNC_INFO << "torch is not available at the moment"; - return false; - } -#endif - } - - if (m_flashMode == QCameraExposure::FlashOff) - captureDevice.flashMode = AVCaptureFlashModeOff; - else if (m_flashMode == QCameraExposure::FlashOn) - captureDevice.flashMode = AVCaptureFlashModeOn; - else if (m_flashMode == QCameraExposure::FlashAuto) - captureDevice.flashMode = AVCaptureFlashModeAuto; - else if (m_flashMode == QCameraExposure::FlashVideoLight) - captureDevice.torchMode = AVCaptureTorchModeOn; - - return true; -} - -QT_END_NAMESPACE - -#include "moc_avfcameraexposurecontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcamerafocuscontrol.h b/src/plugins/avfoundation/camera/avfcamerafocuscontrol.h deleted file mode 100644 index 56f4bc54d..000000000 --- a/src/plugins/avfoundation/camera/avfcamerafocuscontrol.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFCAMERAFOCUSCONTROL_H -#define AVFCAMERAFOCUSCONTROL_H - -#include <QtCore/qscopedpointer.h> -#include <QtCore/qglobal.h> - -#include <qcamerafocuscontrol.h> - -#include <AVFoundation/AVFoundation.h> - -@class AVCaptureDevice; - -QT_BEGIN_NAMESPACE - -class AVFCameraService; -class AVFCameraSession; - -class AVFCameraFocusControl : public QCameraFocusControl -{ - Q_OBJECT -public: - explicit AVFCameraFocusControl(AVFCameraService *service); - - QCameraFocus::FocusModes focusMode() const override; - void setFocusMode(QCameraFocus::FocusModes mode) override; - bool isFocusModeSupported(QCameraFocus::FocusModes mode) const override; - - QCameraFocus::FocusPointMode focusPointMode() const override; - void setFocusPointMode(QCameraFocus::FocusPointMode mode) override; - bool isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const override; - QPointF customFocusPoint() const override; - void setCustomFocusPoint(const QPointF &point) override; - - QCameraFocusZoneList focusZones() const override; - - qreal maximumOpticalZoom() const override; - qreal maximumDigitalZoom() const override; - - qreal requestedOpticalZoom() const override; - qreal requestedDigitalZoom() const override; - qreal currentOpticalZoom() const override; - qreal currentDigitalZoom() const override; - - void zoomTo(qreal optical, qreal digital) override; - -private Q_SLOTS: - void cameraStateChanged(); - -private: -#ifdef QOS_IOS - void zoomToRequestedDigital(); -#endif - - AVFCameraSession *m_session; - QCameraFocus::FocusModes m_focusMode; - QCameraFocus::FocusPointMode m_focusPointMode; - QPointF m_customFocusPoint; - QPointF m_actualFocusPoint; - - CGFloat m_maxZoomFactor; - CGFloat m_zoomFactor; - CGFloat m_requestedZoomFactor; -}; - - -QT_END_NAMESPACE - -#endif // AVFCAMERAFOCUSCONTROL_H diff --git a/src/plugins/avfoundation/camera/avfcamerafocuscontrol.mm b/src/plugins/avfoundation/camera/avfcamerafocuscontrol.mm deleted file mode 100644 index 19dfa6dd2..000000000 --- a/src/plugins/avfoundation/camera/avfcamerafocuscontrol.mm +++ /dev/null @@ -1,422 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfcamerafocuscontrol.h" -#include "avfcamerautility.h" -#include "avfcameraservice.h" -#include "avfcamerasession.h" -#include "avfcameradebug.h" - -#include <QtCore/qdebug.h> - -#include <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -namespace { - -bool qt_focus_mode_supported(QCameraFocus::FocusModes mode) -{ - // Check if QCameraFocus::FocusMode has counterpart in AVFoundation. - - // AVFoundation has 'Manual', 'Auto' and 'Continuous', - // where 'Manual' is actually 'Locked' + writable property 'lensPosition'. - // Since Qt does not provide an API to manipulate a lens position, 'Maual' mode - // (at the moment) is not supported. - return mode == QCameraFocus::AutoFocus - || mode == QCameraFocus::ContinuousFocus; -} - -bool qt_focus_point_mode_supported(QCameraFocus::FocusPointMode mode) -{ - return mode == QCameraFocus::FocusPointAuto - || mode == QCameraFocus::FocusPointCustom - || mode == QCameraFocus::FocusPointCenter; -} - -AVCaptureFocusMode avf_focus_mode(QCameraFocus::FocusModes requestedMode) -{ - if (requestedMode == QCameraFocus::AutoFocus) - return AVCaptureFocusModeAutoFocus; - - return AVCaptureFocusModeContinuousAutoFocus; -} - -} - -AVFCameraFocusControl::AVFCameraFocusControl(AVFCameraService *service) - : m_session(service->session()), - m_focusMode(QCameraFocus::ContinuousFocus), - m_focusPointMode(QCameraFocus::FocusPointAuto), - m_customFocusPoint(0.5f, 0.5f), - m_actualFocusPoint(m_customFocusPoint) -{ - Q_ASSERT(m_session); - connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(cameraStateChanged())); -} - -QCameraFocus::FocusModes AVFCameraFocusControl::focusMode() const -{ - return m_focusMode; -} - -void AVFCameraFocusControl::setFocusMode(QCameraFocus::FocusModes mode) -{ - if (m_focusMode == mode) - return; - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - if (qt_focus_mode_supported(mode)) { - m_focusMode = mode; - Q_EMIT focusModeChanged(m_focusMode); - } else { - qDebugCamera() << Q_FUNC_INFO - << "focus mode not supported"; - } - return; - } - - if (isFocusModeSupported(mode)) { - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO - << "failed to lock for configuration"; - return; - } - - captureDevice.focusMode = avf_focus_mode(mode); - m_focusMode = mode; - } else { - qDebugCamera() << Q_FUNC_INFO << "focus mode not supported"; - return; - } - - Q_EMIT focusModeChanged(m_focusMode); -} - -bool AVFCameraFocusControl::isFocusModeSupported(QCameraFocus::FocusModes mode) const -{ - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) - return false; - - if (!qt_focus_mode_supported(mode)) - return false; - - return [captureDevice isFocusModeSupported:avf_focus_mode(mode)]; -} - -QCameraFocus::FocusPointMode AVFCameraFocusControl::focusPointMode() const -{ - return m_focusPointMode; -} - -void AVFCameraFocusControl::setFocusPointMode(QCameraFocus::FocusPointMode mode) -{ - if (m_focusPointMode == mode) - return; - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - if (qt_focus_point_mode_supported(mode)) { - m_focusPointMode = mode; - Q_EMIT focusPointModeChanged(mode); - } - return; - } - - if (isFocusPointModeSupported(mode)) { - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - bool resetPOI = false; - if (mode == QCameraFocus::FocusPointCenter || mode == QCameraFocus::FocusPointAuto) { - if (m_actualFocusPoint != QPointF(0.5, 0.5)) { - m_actualFocusPoint = QPointF(0.5, 0.5); - resetPOI = true; - } - } else if (mode == QCameraFocus::FocusPointCustom) { - if (m_actualFocusPoint != m_customFocusPoint) { - m_actualFocusPoint = m_customFocusPoint; - resetPOI = true; - } - } // else for any other mode in future. - - if (resetPOI) { - const CGPoint focusPOI = CGPointMake(m_actualFocusPoint.x(), m_actualFocusPoint.y()); - [captureDevice setFocusPointOfInterest:focusPOI]; - } - m_focusPointMode = mode; - } else { - qDebugCamera() << Q_FUNC_INFO << "focus point mode is not supported"; - return; - } - - Q_EMIT focusPointModeChanged(mode); -} - -bool AVFCameraFocusControl::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const -{ - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) - return false; - - if (!qt_focus_point_mode_supported(mode)) - return false; - - return [captureDevice isFocusPointOfInterestSupported]; -} - -QPointF AVFCameraFocusControl::customFocusPoint() const -{ - return m_customFocusPoint; -} - -void AVFCameraFocusControl::setCustomFocusPoint(const QPointF &point) -{ - if (m_customFocusPoint == point) - return; - - if (!QRectF(0.f, 0.f, 1.f, 1.f).contains(point)) { - qDebugCamera() << Q_FUNC_INFO << "invalid focus point (out of range)"; - return; - } - - m_customFocusPoint = point; - Q_EMIT customFocusPointChanged(m_customFocusPoint); - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice || m_focusPointMode != QCameraFocus::FocusPointCustom) - return; - - if ([captureDevice isFocusPointOfInterestSupported]) { - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - m_actualFocusPoint = m_customFocusPoint; - const CGPoint focusPOI = CGPointMake(point.x(), point.y()); - [captureDevice setFocusPointOfInterest:focusPOI]; - if (m_focusMode != QCameraFocus::ContinuousFocus) - [captureDevice setFocusMode:AVCaptureFocusModeAutoFocus]; - } else { - qDebugCamera() << Q_FUNC_INFO << "focus point of interest not supported"; - return; - } -} - -QCameraFocusZoneList AVFCameraFocusControl::focusZones() const -{ - // Unsupported. - return QCameraFocusZoneList(); -} - -void AVFCameraFocusControl::cameraStateChanged() -{ - if (m_session->state() != QCamera::ActiveState) - return; - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - qDebugCamera() << Q_FUNC_INFO << "capture device is nil in 'active' state"; - return; - } - - const AVFConfigurationLock lock(captureDevice); - if (m_customFocusPoint != m_actualFocusPoint - && m_focusPointMode == QCameraFocus::FocusPointCustom) { - if (![captureDevice isFocusPointOfInterestSupported]) { - qDebugCamera() << Q_FUNC_INFO - << "focus point of interest not supported"; - return; - } - - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - m_actualFocusPoint = m_customFocusPoint; - const CGPoint focusPOI = CGPointMake(m_customFocusPoint.x(), m_customFocusPoint.y()); - [captureDevice setFocusPointOfInterest:focusPOI]; - } - - if (m_focusMode != QCameraFocus::ContinuousFocus) { - const AVCaptureFocusMode avMode = avf_focus_mode(m_focusMode); - if (captureDevice.focusMode != avMode) { - if (![captureDevice isFocusModeSupported:avMode]) { - qDebugCamera() << Q_FUNC_INFO << "focus mode not supported"; - return; - } - - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - [captureDevice setFocusMode:avMode]; - } - } - -#ifdef Q_OS_IOS - const QCamera::State state = m_session->state(); - if (state != QCamera::ActiveState) { - if (state == QCamera::UnloadedState && m_maxZoomFactor > 1.) { - m_maxZoomFactor = 1.; - Q_EMIT maximumDigitalZoomChanged(1.); - } - return; - } - - if (!captureDevice || !captureDevice.activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "camera state is active, but" - << "video capture device and/or active format is nil"; - return; - } - - if (captureDevice.activeFormat.videoMaxZoomFactor > 1.) { - if (!qFuzzyCompare(m_maxZoomFactor, captureDevice.activeFormat.videoMaxZoomFactor)) { - m_maxZoomFactor = captureDevice.activeFormat.videoMaxZoomFactor; - Q_EMIT maximumDigitalZoomChanged(m_maxZoomFactor); - } - } else if (!qFuzzyCompare(m_maxZoomFactor, CGFloat(1.))) { - m_maxZoomFactor = 1.; - - Q_EMIT maximumDigitalZoomChanged(1.); - } - - zoomToRequestedDigital(); -#endif -} - -qreal AVFCameraFocusControl::maximumOpticalZoom() const -{ - // Not supported. - return 1.; -} - -qreal AVFCameraFocusControl::maximumDigitalZoom() const -{ - return m_maxZoomFactor; -} - -qreal AVFCameraFocusControl::requestedOpticalZoom() const -{ - // Not supported. - return 1; -} - -qreal AVFCameraFocusControl::requestedDigitalZoom() const -{ - return m_requestedZoomFactor; -} - -qreal AVFCameraFocusControl::currentOpticalZoom() const -{ - // Not supported. - return 1.; -} - -qreal AVFCameraFocusControl::currentDigitalZoom() const -{ - return m_zoomFactor; -} - -void AVFCameraFocusControl::zoomTo(qreal optical, qreal digital) -{ - Q_UNUSED(optical); - Q_UNUSED(digital); - -#ifdef QOS_IOS - if (qFuzzyCompare(CGFloat(digital), m_requestedZoomFactor)) - return; - - m_requestedZoomFactor = digital; - Q_EMIT requestedDigitalZoomChanged(digital); - - zoomToRequestedDigital(); -#endif -} - -#ifdef QOS_IOS -void AVFCameraFocusControl::zoomToRequestedDigital() -{ - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice || !captureDevice.activeFormat) - return; - - if (qFuzzyCompare(captureDevice.activeFormat.videoMaxZoomFactor, CGFloat(1.))) - return; - - const CGFloat clampedZoom = qBound(CGFloat(1.), m_requestedZoomFactor, - captureDevice.activeFormat.videoMaxZoomFactor); - const CGFloat deviceZoom = captureDevice.videoZoomFactor; - if (qFuzzyCompare(clampedZoom, deviceZoom)) { - // Nothing to set, but check if a signal must be emitted: - if (!qFuzzyCompare(m_zoomFactor, deviceZoom)) { - m_zoomFactor = deviceZoom; - Q_EMIT currentDigitalZoomChanged(deviceZoom); - } - return; - } - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - captureDevice.videoZoomFactor = clampedZoom; - - if (!qFuzzyCompare(clampedZoom, m_zoomFactor)) { - m_zoomFactor = clampedZoom; - Q_EMIT currentDigitalZoomChanged(clampedZoom); - } -} -#endif - -QT_END_NAMESPACE - -#include "moc_avfcamerafocuscontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcamerametadatacontrol.h b/src/plugins/avfoundation/camera/avfcamerametadatacontrol.h deleted file mode 100644 index fd8659dfd..000000000 --- a/src/plugins/avfoundation/camera/avfcamerametadatacontrol.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFCAMERAMETADATACONTROL_H -#define AVFCAMERAMETADATACONTROL_H - -#include <qmetadatawritercontrol.h> -#include <QtCore/qvariant.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraService; - -class AVFCameraMetaDataControl : public QMetaDataWriterControl -{ - Q_OBJECT -public: - AVFCameraMetaDataControl(AVFCameraService *service, QObject *parent = nullptr); - virtual ~AVFCameraMetaDataControl(); - - bool isMetaDataAvailable() const override; - bool isWritable() const override; - - QVariant metaData(const QString &key) const override; - void setMetaData(const QString &key, const QVariant &value) override; - QStringList availableMetaData() const override; - -private: - QMap<QString, QVariant> m_tags; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcamerametadatacontrol.mm b/src/plugins/avfoundation/camera/avfcamerametadatacontrol.mm deleted file mode 100644 index 95a8a0d79..000000000 --- a/src/plugins/avfoundation/camera/avfcamerametadatacontrol.mm +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfcamerametadatacontrol.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" - -QT_USE_NAMESPACE - -//metadata support is not implemented yet - -AVFCameraMetaDataControl::AVFCameraMetaDataControl(AVFCameraService *service, QObject *parent) - :QMetaDataWriterControl(parent) -{ - Q_UNUSED(service); -} - -AVFCameraMetaDataControl::~AVFCameraMetaDataControl() -{ -} - -bool AVFCameraMetaDataControl::isMetaDataAvailable() const -{ - return !m_tags.isEmpty(); -} - -bool AVFCameraMetaDataControl::isWritable() const -{ - return false; -} - -QVariant AVFCameraMetaDataControl::metaData(const QString &key) const -{ - return m_tags.value(key); -} - -void AVFCameraMetaDataControl::setMetaData(const QString &key, const QVariant &value) -{ - m_tags.insert(key, value); -} - -QStringList AVFCameraMetaDataControl::availableMetaData() const -{ - return m_tags.keys(); -} - -#include "moc_avfcamerametadatacontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcamerarenderercontrol.h b/src/plugins/avfoundation/camera/avfcamerarenderercontrol.h deleted file mode 100644 index 3ef3d07d4..000000000 --- a/src/plugins/avfoundation/camera/avfcamerarenderercontrol.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFCAMERARENDERERCONTROL_H -#define AVFCAMERARENDERERCONTROL_H - -#include <QtMultimedia/qvideorenderercontrol.h> -#include <QtMultimedia/qvideoframe.h> -#include <QtCore/qmutex.h> - -#import <AVFoundation/AVFoundation.h> - -@class AVFCaptureFramesDelegate; - -QT_BEGIN_NAMESPACE - -class AVFCameraSession; -class AVFCameraService; -class AVFCameraRendererControl; - -class AVFCameraRendererControl : public QVideoRendererControl -{ -Q_OBJECT -public: - AVFCameraRendererControl(QObject *parent = nullptr); - ~AVFCameraRendererControl(); - - QAbstractVideoSurface *surface() const override; - void setSurface(QAbstractVideoSurface *surface) override; - - void configureAVCaptureSession(AVFCameraSession *cameraSession); - void syncHandleViewfinderFrame(const QVideoFrame &frame); - - AVCaptureVideoDataOutput *videoDataOutput() const; - - bool supportsTextures() const { return m_supportsTextures; } - -#ifdef Q_OS_IOS - AVFCaptureFramesDelegate *captureDelegate() const; - void resetCaptureDelegate() const; -#endif - -Q_SIGNALS: - void surfaceChanged(QAbstractVideoSurface *surface); - -private Q_SLOTS: - void handleViewfinderFrame(); - void updateCaptureConnection(); - -private: - QAbstractVideoSurface *m_surface; - AVFCaptureFramesDelegate *m_viewfinderFramesDelegate; - AVFCameraSession *m_cameraSession; - AVCaptureVideoDataOutput *m_videoDataOutput; - - bool m_supportsTextures; - bool m_needsHorizontalMirroring; - -#ifdef Q_OS_IOS - CVOpenGLESTextureCacheRef m_textureCache; -#endif - - QVideoFrame m_lastViewfinderFrame; - QMutex m_vfMutex; - dispatch_queue_t m_delegateQueue; - - friend class CVImageVideoBuffer; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcamerarenderercontrol.mm b/src/plugins/avfoundation/camera/avfcamerarenderercontrol.mm deleted file mode 100644 index b77aa21ec..000000000 --- a/src/plugins/avfoundation/camera/avfcamerarenderercontrol.mm +++ /dev/null @@ -1,409 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "private/qabstractvideobuffer_p.h" -#include "avfcamerarenderercontrol.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" -#include "avfcameradebug.h" -#include "avfcameracontrol.h" - -#ifdef Q_OS_IOS -#include <QtGui/qopengl.h> -#endif - -#include <QtMultimedia/qabstractvideosurface.h> -#include <QtMultimedia/qabstractvideobuffer.h> - -#include <QtMultimedia/qvideosurfaceformat.h> - -QT_USE_NAMESPACE - -class CVImageVideoBuffer : public QAbstractVideoBuffer -{ -public: - CVImageVideoBuffer(CVImageBufferRef buffer, AVFCameraRendererControl *renderer) -#ifndef Q_OS_IOS - : QAbstractVideoBuffer(NoHandle) -#else - : QAbstractVideoBuffer(renderer->supportsTextures() - && CVPixelBufferGetPixelFormatType(buffer) == kCVPixelFormatType_32BGRA - ? GLTextureHandle : NoHandle) - , m_texture(nullptr) - , m_renderer(renderer) -#endif - , m_buffer(buffer) - , m_mode(NotMapped) - { -#ifndef Q_OS_IOS - Q_UNUSED(renderer); -#endif // Q_OS_IOS - CVPixelBufferRetain(m_buffer); - } - - ~CVImageVideoBuffer() - { - CVImageVideoBuffer::unmap(); -#ifdef Q_OS_IOS - if (m_texture) - CFRelease(m_texture); -#endif - CVPixelBufferRelease(m_buffer); - } - - MapMode mapMode() const { return m_mode; } - - MapData map(QAbstractVideoBuffer::MapMode mode) - { - MapData mapData; - - // We only support RGBA or NV12 (or Apple's version of NV12), - // they are either 0 planes or 2. - mapData.nPlanes = CVPixelBufferGetPlaneCount(m_buffer); - Q_ASSERT(mapData.nPlanes <= 2); - - if (!mapData.nPlanes) { - mapData.data[0] = map(mode, &mapData.nBytes, &mapData.bytesPerLine[0]); - mapData.nPlanes = mapData.data[0] ? 1 : 0; - return mapData; - } - - // For a bi-planar format we have to set the parameters correctly: - if (mode != QAbstractVideoBuffer::NotMapped && m_mode == QAbstractVideoBuffer::NotMapped) { - CVPixelBufferLockBaseAddress(m_buffer, mode == QAbstractVideoBuffer::ReadOnly - ? kCVPixelBufferLock_ReadOnly - : 0); - - mapData.nBytes = CVPixelBufferGetDataSize(m_buffer); - - // At the moment we handle only bi-planar format. - mapData.bytesPerLine[0] = CVPixelBufferGetBytesPerRowOfPlane(m_buffer, 0); - mapData.bytesPerLine[1] = CVPixelBufferGetBytesPerRowOfPlane(m_buffer, 1); - - mapData.data[0] = static_cast<uchar*>(CVPixelBufferGetBaseAddressOfPlane(m_buffer, 0)); - mapData.data[1] = static_cast<uchar*>(CVPixelBufferGetBaseAddressOfPlane(m_buffer, 1)); - - m_mode = mode; - } - - return mapData; - } - - uchar *map(MapMode mode, qsizetype *numBytes, int *bytesPerLine) - { - if (mode != NotMapped && m_mode == NotMapped) { - CVPixelBufferLockBaseAddress(m_buffer, mode == QAbstractVideoBuffer::ReadOnly - ? kCVPixelBufferLock_ReadOnly - : 0); - if (numBytes) - *numBytes = CVPixelBufferGetDataSize(m_buffer); - - if (bytesPerLine) - *bytesPerLine = CVPixelBufferGetBytesPerRow(m_buffer); - - m_mode = mode; - return static_cast<uchar*>(CVPixelBufferGetBaseAddress(m_buffer)); - } else { - return nullptr; - } - } - - void unmap() - { - if (m_mode != NotMapped) { - CVPixelBufferUnlockBaseAddress(m_buffer, m_mode == QAbstractVideoBuffer::ReadOnly - ? kCVPixelBufferLock_ReadOnly - : 0); - m_mode = NotMapped; - } - } - - QVariant handle() const - { -#ifdef Q_OS_IOS - // Called from the render thread, so there is a current OpenGL context - - if (!m_renderer->m_textureCache) { - CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, - nullptr, - [EAGLContext currentContext], - nullptr, - &m_renderer->m_textureCache); - - if (err != kCVReturnSuccess) - qWarning("Error creating texture cache"); - } - - if (m_renderer->m_textureCache && !m_texture) { - CVOpenGLESTextureCacheFlush(m_renderer->m_textureCache, 0); - - CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, - m_renderer->m_textureCache, - m_buffer, - nullptr, - GL_TEXTURE_2D, - GL_RGBA, - CVPixelBufferGetWidth(m_buffer), - CVPixelBufferGetHeight(m_buffer), - GL_RGBA, - GL_UNSIGNED_BYTE, - 0, - &m_texture); - if (err != kCVReturnSuccess) - qWarning("Error creating texture from buffer"); - } - - if (m_texture) - return CVOpenGLESTextureGetName(m_texture); - else - return 0; -#else - return QVariant(); -#endif - } - -private: -#ifdef Q_OS_IOS - mutable CVOpenGLESTextureRef m_texture; - AVFCameraRendererControl *m_renderer; -#endif - CVImageBufferRef m_buffer; - MapMode m_mode; -}; - - -@interface AVFCaptureFramesDelegate : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate> - -- (AVFCaptureFramesDelegate *) initWithRenderer:(AVFCameraRendererControl*)renderer; - -- (void) captureOutput:(AVCaptureOutput *)captureOutput - didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer - fromConnection:(AVCaptureConnection *)connection; - -@end - -@implementation AVFCaptureFramesDelegate -{ -@private - AVFCameraRendererControl *m_renderer; -} - -- (AVFCaptureFramesDelegate *) initWithRenderer:(AVFCameraRendererControl*)renderer -{ - if (!(self = [super init])) - return nil; - - self->m_renderer = renderer; - return self; -} - -- (void)captureOutput:(AVCaptureOutput *)captureOutput - didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer - fromConnection:(AVCaptureConnection *)connection -{ - Q_UNUSED(connection); - Q_UNUSED(captureOutput); - - // NB: on iOS captureOutput/connection can be nil (when recording a video - - // avfmediaassetwriter). - - CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); - - int width = CVPixelBufferGetWidth(imageBuffer); - int height = CVPixelBufferGetHeight(imageBuffer); - QVideoFrame::PixelFormat format = - AVFCameraControl::QtPixelFormatFromCVFormat(CVPixelBufferGetPixelFormatType(imageBuffer)); - if (format == QVideoFrame::Format_Invalid) - return; - - QVideoFrame frame(new CVImageVideoBuffer(imageBuffer, m_renderer), - QSize(width, height), - format); - - m_renderer->syncHandleViewfinderFrame(frame); -} - -@end - - -AVFCameraRendererControl::AVFCameraRendererControl(QObject *parent) - : QVideoRendererControl(parent) - , m_surface(nullptr) - , m_supportsTextures(false) - , m_needsHorizontalMirroring(false) -#ifdef Q_OS_IOS - , m_textureCache(nullptr) -#endif -{ - m_viewfinderFramesDelegate = [[AVFCaptureFramesDelegate alloc] initWithRenderer:this]; -} - -AVFCameraRendererControl::~AVFCameraRendererControl() -{ - [m_cameraSession->captureSession() removeOutput:m_videoDataOutput]; - [m_viewfinderFramesDelegate release]; - if (m_delegateQueue) - dispatch_release(m_delegateQueue); -#ifdef Q_OS_IOS - if (m_textureCache) - CFRelease(m_textureCache); -#endif -} - -QAbstractVideoSurface *AVFCameraRendererControl::surface() const -{ - return m_surface; -} - -void AVFCameraRendererControl::setSurface(QAbstractVideoSurface *surface) -{ - if (m_surface != surface) { - m_surface = surface; - m_supportsTextures = m_surface - ? !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty() - : false; - Q_EMIT surfaceChanged(surface); - } -} - -void AVFCameraRendererControl::configureAVCaptureSession(AVFCameraSession *cameraSession) -{ - m_cameraSession = cameraSession; - connect(m_cameraSession, SIGNAL(readyToConfigureConnections()), - this, SLOT(updateCaptureConnection())); - - m_needsHorizontalMirroring = false; - - m_videoDataOutput = [[[AVCaptureVideoDataOutput alloc] init] autorelease]; - - // Configure video output - m_delegateQueue = dispatch_queue_create("vf_queue", nullptr); - [m_videoDataOutput - setSampleBufferDelegate:m_viewfinderFramesDelegate - queue:m_delegateQueue]; - - [m_cameraSession->captureSession() addOutput:m_videoDataOutput]; -} - -void AVFCameraRendererControl::updateCaptureConnection() -{ - AVCaptureConnection *connection = [m_videoDataOutput connectionWithMediaType:AVMediaTypeVideo]; - if (connection == nil || !m_cameraSession->videoCaptureDevice()) - return; - - // Frames of front-facing cameras should be mirrored horizontally (it's the default when using - // AVCaptureVideoPreviewLayer but not with AVCaptureVideoDataOutput) - if (connection.isVideoMirroringSupported) - connection.videoMirrored = m_cameraSession->videoCaptureDevice().position == AVCaptureDevicePositionFront; - - // If the connection does't support mirroring, we'll have to do it ourselves - m_needsHorizontalMirroring = !connection.isVideoMirrored - && m_cameraSession->videoCaptureDevice().position == AVCaptureDevicePositionFront; -} - -//can be called from non main thread -void AVFCameraRendererControl::syncHandleViewfinderFrame(const QVideoFrame &frame) -{ - QMutexLocker lock(&m_vfMutex); - if (!m_lastViewfinderFrame.isValid()) { - static QMetaMethod handleViewfinderFrameSlot = metaObject()->method( - metaObject()->indexOfMethod("handleViewfinderFrame()")); - - handleViewfinderFrameSlot.invoke(this, Qt::QueuedConnection); - } - - m_lastViewfinderFrame = frame; - - if (m_cameraSession && m_lastViewfinderFrame.isValid()) - m_cameraSession->onCameraFrameFetched(m_lastViewfinderFrame); -} - -AVCaptureVideoDataOutput *AVFCameraRendererControl::videoDataOutput() const -{ - return m_videoDataOutput; -} - -#ifdef Q_OS_IOS - -AVFCaptureFramesDelegate *AVFCameraRendererControl::captureDelegate() const -{ - return m_viewfinderFramesDelegate; -} - -void AVFCameraRendererControl::resetCaptureDelegate() const -{ - [m_videoDataOutput setSampleBufferDelegate:m_viewfinderFramesDelegate queue:m_delegateQueue]; -} - -#endif - -void AVFCameraRendererControl::handleViewfinderFrame() -{ - QVideoFrame frame; - { - QMutexLocker lock(&m_vfMutex); - frame = m_lastViewfinderFrame; - m_lastViewfinderFrame = QVideoFrame(); - } - - if (m_surface && frame.isValid()) { - if (m_surface->isActive() && (m_surface->surfaceFormat().pixelFormat() != frame.pixelFormat() - || m_surface->surfaceFormat().frameSize() != frame.size())) { - m_surface->stop(); - } - - if (!m_surface->isActive()) { - QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), frame.handleType()); - if (m_needsHorizontalMirroring) - format.setProperty("mirrored", true); - - if (!m_surface->start(format)) { - qWarning() << "Failed to start viewfinder m_surface, format:" << format; - } else { - qDebugCamera() << "Viewfinder started: " << format; - } - } - - if (m_surface->isActive()) - m_surface->present(frame); - } -} - - -#include "moc_avfcamerarenderercontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcameraservice.h b/src/plugins/avfoundation/camera/avfcameraservice.h deleted file mode 100644 index 2c5bfedce..000000000 --- a/src/plugins/avfoundation/camera/avfcameraservice.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFCAMERASERVICE_H -#define AVFCAMERASERVICE_H - -#include <QtCore/qobject.h> -#include <QtCore/qset.h> -#include <qmediaservice.h> - - -QT_BEGIN_NAMESPACE -class QCameraControl; -class QMediaRecorderControl; -class AVFCameraControl; -class AVFCameraMetaDataControl; -class AVFVideoWindowControl; -class AVFVideoWidgetControl; -class AVFCameraRendererControl; -class AVFImageCaptureControl; -class AVFCameraSession; -class AVFCameraDeviceControl; -class AVFAudioInputSelectorControl; -class AVFCameraFocusControl; -class AVFCameraExposureControl; -class AVFImageEncoderControl; -class AVFMediaRecorderControl; -class AVFMediaRecorderControlIOS; -class AVFAudioEncoderSettingsControl; -class AVFVideoEncoderSettingsControl; -class AVFMediaContainerControl; -class AVFCameraWindowControl; - -class AVFCameraService : public QMediaService -{ -Q_OBJECT -public: - AVFCameraService(QObject *parent = nullptr); - ~AVFCameraService(); - - QObject *requestControl(const char *name); - void releaseControl(QObject *control); - - AVFCameraSession *session() const { return m_session; } - AVFCameraControl *cameraControl() const { return m_cameraControl; } - AVFCameraDeviceControl *videoDeviceControl() const { return m_videoDeviceControl; } - AVFAudioInputSelectorControl *audioInputSelectorControl() const { return m_audioInputSelectorControl; } - AVFCameraMetaDataControl *metaDataControl() const { return m_metaDataControl; } - QMediaRecorderControl *recorderControl() const { return m_recorderControl; } - AVFImageCaptureControl *imageCaptureControl() const { return m_imageCaptureControl; } - AVFCameraFocusControl *cameraFocusControl() const { return m_cameraFocusControl; } - AVFCameraExposureControl *cameraExposureControl() const {return m_cameraExposureControl; } - AVFCameraRendererControl *videoOutput() const {return m_videoOutput; } - AVFImageEncoderControl *imageEncoderControl() const {return m_imageEncoderControl; } - AVFAudioEncoderSettingsControl *audioEncoderSettingsControl() const { return m_audioEncoderSettingsControl; } - AVFVideoEncoderSettingsControl *videoEncoderSettingsControl() const {return m_videoEncoderSettingsControl; } - AVFMediaContainerControl *mediaContainerControl() const { return m_mediaContainerControl; } - -private: - AVFCameraSession *m_session; - AVFCameraControl *m_cameraControl; - AVFCameraDeviceControl *m_videoDeviceControl; - AVFAudioInputSelectorControl *m_audioInputSelectorControl; - AVFCameraRendererControl *m_videoOutput; - AVFCameraMetaDataControl *m_metaDataControl; - QMediaRecorderControl *m_recorderControl; - AVFImageCaptureControl *m_imageCaptureControl; - AVFCameraFocusControl *m_cameraFocusControl; - AVFCameraExposureControl *m_cameraExposureControl; - AVFImageEncoderControl *m_imageEncoderControl; - AVFAudioEncoderSettingsControl *m_audioEncoderSettingsControl; - AVFVideoEncoderSettingsControl *m_videoEncoderSettingsControl; - AVFMediaContainerControl *m_mediaContainerControl; - AVFCameraWindowControl *m_captureWindowControl; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcameraservice.mm b/src/plugins/avfoundation/camera/avfcameraservice.mm deleted file mode 100644 index 29ac6b07f..000000000 --- a/src/plugins/avfoundation/camera/avfcameraservice.mm +++ /dev/null @@ -1,225 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qvariant.h> -#include <QtCore/qdebug.h> - -#include "avfcameraservice.h" -#include "avfcameracontrol.h" -#include "avfcamerasession.h" -#include "avfcameradevicecontrol.h" -#include "avfaudioinputselectorcontrol.h" -#include "avfcamerametadatacontrol.h" -#include "avfmediarecordercontrol.h" -#include "avfimagecapturecontrol.h" -#include "avfcamerarenderercontrol.h" -#include "avfmediarecordercontrol.h" -#include "avfimagecapturecontrol.h" -#include "avfmediavideoprobecontrol.h" -#include "avfcamerafocuscontrol.h" -#include "avfcameraexposurecontrol.h" -#include "avfimageencodercontrol.h" -#include "avfaudioencodersettingscontrol.h" -#include "avfvideoencodersettingscontrol.h" -#include "avfmediacontainercontrol.h" -#include "avfcamerawindowcontrol.h" - -#ifdef Q_OS_IOS -#include "avfmediarecordercontrol_ios.h" -#endif - -#include <qmediaplaylist.h> - -QT_USE_NAMESPACE - -AVFCameraService::AVFCameraService(QObject *parent): - QMediaService(parent), - m_videoOutput(nullptr), - m_captureWindowControl(nullptr) -{ - m_session = new AVFCameraSession(this); - m_cameraControl = new AVFCameraControl(this); - m_videoDeviceControl = new AVFCameraDeviceControl(this); - m_audioInputSelectorControl = new AVFAudioInputSelectorControl(this); - - m_metaDataControl = new AVFCameraMetaDataControl(this); -#ifndef Q_OS_IOS - // This will connect a slot to 'captureModeChanged' - // and will break viewfinder by attaching AVCaptureMovieFileOutput - // in this slot. - m_recorderControl = new AVFMediaRecorderControl(this); -#else - m_recorderControl = new AVFMediaRecorderControlIOS(this); -#endif - m_imageCaptureControl = new AVFImageCaptureControl(this); - m_cameraFocusControl = new AVFCameraFocusControl(this); - m_cameraExposureControl = nullptr; -#ifdef Q_OS_IOS - m_cameraExposureControl = new AVFCameraExposureControl(this); -#endif - - m_imageEncoderControl = new AVFImageEncoderControl(this); - m_audioEncoderSettingsControl = new AVFAudioEncoderSettingsControl(this); - m_videoEncoderSettingsControl = new AVFVideoEncoderSettingsControl(this); - m_mediaContainerControl = new AVFMediaContainerControl(this); -} - -AVFCameraService::~AVFCameraService() -{ - m_cameraControl->setState(QCamera::UnloadedState); - -#ifdef Q_OS_IOS - delete m_recorderControl; -#endif - - if (m_captureWindowControl) { - m_session->setCapturePreviewOutput(nullptr); - delete m_captureWindowControl; - m_captureWindowControl = nullptr; - } - - if (m_videoOutput) { - m_session->setVideoOutput(nullptr); - delete m_videoOutput; - m_videoOutput = nullptr; - } - - //delete controls before session, - //so they have a chance to do deinitialization - delete m_imageCaptureControl; - //delete m_recorderControl; - delete m_metaDataControl; - delete m_cameraControl; - delete m_cameraFocusControl; - delete m_cameraExposureControl; - delete m_imageEncoderControl; - delete m_audioEncoderSettingsControl; - delete m_videoEncoderSettingsControl; - delete m_mediaContainerControl; - - delete m_session; -} - -QObject *AVFCameraService::requestControl(const char *name) -{ - if (qstrcmp(name, QCameraControl_iid) == 0) - return m_cameraControl; - - if (qstrcmp(name, QVideoDeviceSelectorControl_iid) == 0) - return m_videoDeviceControl; - - if (qstrcmp(name, QAudioInputSelectorControl_iid) == 0) - return m_audioInputSelectorControl; - - //metadata support is not implemented yet - //if (qstrcmp(name, QMetaDataWriterControl_iid) == 0) - // return m_metaDataControl; - - if (qstrcmp(name, QMediaRecorderControl_iid) == 0) - return m_recorderControl; - - if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) - return m_imageCaptureControl; - - if (qstrcmp(name, QCameraExposureControl_iid) == 0) - return m_cameraExposureControl; - - if (qstrcmp(name, QCameraFocusControl_iid) == 0) - return m_cameraFocusControl; - - if (qstrcmp(name, QImageEncoderControl_iid) == 0) - return m_imageEncoderControl; - - if (qstrcmp(name, QAudioEncoderSettingsControl_iid) == 0) - return m_audioEncoderSettingsControl; - - if (qstrcmp(name, QVideoEncoderSettingsControl_iid) == 0) - return m_videoEncoderSettingsControl; - - if (qstrcmp(name, QMediaContainerControl_iid) == 0) - return m_mediaContainerControl; - - if (qstrcmp(name,QMediaVideoProbeControl_iid) == 0) { - AVFMediaVideoProbeControl *videoProbe = nullptr; - videoProbe = new AVFMediaVideoProbeControl(this); - m_session->addProbe(videoProbe); - return videoProbe; - } - - if (!m_captureWindowControl) { - if (qstrcmp(name, QVideoWindowControl_iid) == 0) { - m_captureWindowControl = new AVFCameraWindowControl(this); - m_session->setCapturePreviewOutput(m_captureWindowControl); - return m_captureWindowControl; - } - } - - if (!m_videoOutput) { - if (qstrcmp(name, QVideoRendererControl_iid) == 0) - m_videoOutput = new AVFCameraRendererControl(this); - - if (m_videoOutput) { - m_session->setVideoOutput(m_videoOutput); - return m_videoOutput; - } - } - - return nullptr; -} - -void AVFCameraService::releaseControl(QObject *control) -{ - AVFMediaVideoProbeControl *videoProbe = qobject_cast<AVFMediaVideoProbeControl *>(control); - if (videoProbe) { - m_session->removeProbe(videoProbe); - delete videoProbe; - } else if (m_videoOutput == control) { - m_session->setVideoOutput(nullptr); - delete m_videoOutput; - m_videoOutput = nullptr; - } - else if (m_captureWindowControl == control) { - m_session->setCapturePreviewOutput(nullptr); - delete m_captureWindowControl; - m_captureWindowControl = nullptr; - } -} - - -#include "moc_avfcameraservice.cpp" diff --git a/src/plugins/avfoundation/camera/avfcameraserviceplugin.h b/src/plugins/avfoundation/camera/avfcameraserviceplugin.h deleted file mode 100644 index 4d3e009da..000000000 --- a/src/plugins/avfoundation/camera/avfcameraserviceplugin.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef AVFSERVICEPLUGIN_H -#define AVFSERVICEPLUGIN_H - -#include <qmediaserviceproviderplugin.h> -#include <QtCore/qmap.h> - -QT_BEGIN_NAMESPACE - -class AVFServicePlugin : public QMediaServiceProviderPlugin, - public QMediaServiceSupportedDevicesInterface -{ - Q_OBJECT - Q_INTERFACES(QMediaServiceSupportedDevicesInterface) - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "avfcamera.json") - -public: - AVFServicePlugin(); - - QMediaService* create(QString const &key) override; - void release(QMediaService *service) override; - - QByteArray defaultDevice(const QByteArray &service) const override; - QList<QByteArray> devices(const QByteArray &service) const override; - QString deviceDescription(const QByteArray &service, const QByteArray &device) override; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcameraserviceplugin.mm b/src/plugins/avfoundation/camera/avfcameraserviceplugin.mm deleted file mode 100644 index a94325e34..000000000 --- a/src/plugins/avfoundation/camera/avfcameraserviceplugin.mm +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qstring.h> -#include <QtCore/qdebug.h> - -#include "avfcameraserviceplugin.h" -#include "avfcameraservice.h" -#include "avfcamerasession.h" - -#include <qmediaserviceproviderplugin.h> - -QT_BEGIN_NAMESPACE - -AVFServicePlugin::AVFServicePlugin() -{ -} - -QMediaService* AVFServicePlugin::create(QString const& key) -{ - if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)) - return new AVFCameraService; - else - qWarning() << "unsupported key:" << key; - - return nullptr; -} - -void AVFServicePlugin::release(QMediaService *service) -{ - delete service; -} - -QByteArray AVFServicePlugin::defaultDevice(const QByteArray &service) const -{ - if (service == Q_MEDIASERVICE_CAMERA) { - int i = AVFCameraSession::defaultCameraIndex(); - if (i != -1) - return AVFCameraSession::availableCameraDevices().at(i).deviceId; - } - - return QByteArray(); -} - -QList<QByteArray> AVFServicePlugin::devices(const QByteArray &service) const -{ - QList<QByteArray> devs; - - if (service == Q_MEDIASERVICE_CAMERA) { - const QList<AVFCameraInfo> &cameras = AVFCameraSession::availableCameraDevices(); - devs.reserve(cameras.size()); - for (const AVFCameraInfo &info : cameras) - devs.append(info.deviceId); - } - - return devs; -} - -QString AVFServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) -{ - if (service == Q_MEDIASERVICE_CAMERA) - return AVFCameraSession::cameraDeviceInfo(device).description; - - return QString(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfcamerasession.h b/src/plugins/avfoundation/camera/avfcamerasession.h deleted file mode 100644 index a449bb806..000000000 --- a/src/plugins/avfoundation/camera/avfcamerasession.h +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFCAMERASESSION_H -#define AVFCAMERASESSION_H - -#include <QtCore/qmutex.h> -#include <QtMultimedia/qcamera.h> -#include <QVideoFrame> - -#import <AVFoundation/AVFoundation.h> - -@class AVFCameraSessionObserver; - -QT_BEGIN_NAMESPACE - -class AVFCameraControl; -class AVFCameraService; -class AVFCameraRendererControl; -class AVFMediaVideoProbeControl; -class AVFCameraWindowControl; - -struct AVFCameraInfo -{ - AVFCameraInfo() : position(QCamera::UnspecifiedPosition), orientation(0) - { } - - QByteArray deviceId; - QString description; - QCamera::Position position; - int orientation; -}; - -class AVFCameraSession : public QObject -{ - Q_OBJECT -public: - AVFCameraSession(AVFCameraService *service, QObject *parent = nullptr); - ~AVFCameraSession(); - - static int defaultCameraIndex(); - static const QList<AVFCameraInfo> &availableCameraDevices(); - static AVFCameraInfo cameraDeviceInfo(const QByteArray &device); - AVFCameraInfo activeCameraInfo() const { return m_activeCameraInfo; } - - void setVideoOutput(AVFCameraRendererControl *output); - void setCapturePreviewOutput(AVFCameraWindowControl *output); - AVCaptureSession *captureSession() const { return m_captureSession; } - AVCaptureDevice *videoCaptureDevice() const; - - QCamera::State state() const; - QCamera::State requestedState() const { return m_state; } - bool isActive() const { return m_active; } - - void addProbe(AVFMediaVideoProbeControl *probe); - void removeProbe(AVFMediaVideoProbeControl *probe); - FourCharCode defaultCodec(); - - AVCaptureDeviceInput *videoInput() const {return m_videoInput;} - -public Q_SLOTS: - void setState(QCamera::State state); - - void processRuntimeError(); - void processSessionStarted(); - void processSessionStopped(); - - void onCaptureModeChanged(QCamera::CaptureModes mode); - - void onCameraFrameFetched(const QVideoFrame &frame); - -Q_SIGNALS: - void readyToConfigureConnections(); - void stateChanged(QCamera::State newState); - void activeChanged(bool); - void newViewfinderFrame(const QVideoFrame &frame); - void error(int error, const QString &errorString); - -private: - static void updateCameraDevices(); - void attachVideoInputDevice(); - bool applyImageEncoderSettings(); - bool applyViewfinderSettings(); - - static int m_defaultCameraIndex; - static QList<AVFCameraInfo> m_cameraDevices; - AVFCameraInfo m_activeCameraInfo; - - AVFCameraService *m_service; - AVFCameraRendererControl *m_videoOutput; - AVFCameraWindowControl *m_capturePreviewWindowOutput; - - QCamera::State m_state; - bool m_active; - - AVCaptureSession *m_captureSession; - AVCaptureDeviceInput *m_videoInput; - AVFCameraSessionObserver *m_observer; - - QSet<AVFMediaVideoProbeControl *> m_videoProbes; - QMutex m_videoProbesMutex; - - FourCharCode m_defaultCodec; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcamerasession.mm b/src/plugins/avfoundation/camera/avfcamerasession.mm deleted file mode 100644 index 4ffa5ad69..000000000 --- a/src/plugins/avfoundation/camera/avfcamerasession.mm +++ /dev/null @@ -1,491 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfcameradebug.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" -#include "avfcameracontrol.h" -#include "avfcamerarenderercontrol.h" -#include "avfcameradevicecontrol.h" -#include "avfaudioinputselectorcontrol.h" -#include "avfmediavideoprobecontrol.h" -#include "avfimageencodercontrol.h" -#include "avfcamerautility.h" -#include "avfcamerawindowcontrol.h" - -#include <CoreFoundation/CoreFoundation.h> -#include <Foundation/Foundation.h> - -#include <QtCore/qdatetime.h> -#include <QtCore/qurl.h> -#include <QtCore/qelapsedtimer.h> - -#include <QtCore/qdebug.h> - -QT_USE_NAMESPACE - -int AVFCameraSession::m_defaultCameraIndex; -QList<AVFCameraInfo> AVFCameraSession::m_cameraDevices; - -@interface AVFCameraSessionObserver : NSObject - -- (AVFCameraSessionObserver *) initWithCameraSession:(AVFCameraSession*)session; -- (void) processRuntimeError:(NSNotification *)notification; -- (void) processSessionStarted:(NSNotification *)notification; -- (void) processSessionStopped:(NSNotification *)notification; - -@end - -@implementation AVFCameraSessionObserver -{ -@private - AVFCameraSession *m_session; - AVCaptureSession *m_captureSession; -} - -- (AVFCameraSessionObserver *) initWithCameraSession:(AVFCameraSession*)session -{ - if (!(self = [super init])) - return nil; - - self->m_session = session; - self->m_captureSession = session->captureSession(); - - [m_captureSession retain]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(processRuntimeError:) - name:AVCaptureSessionRuntimeErrorNotification - object:m_captureSession]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(processSessionStarted:) - name:AVCaptureSessionDidStartRunningNotification - object:m_captureSession]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(processSessionStopped:) - name:AVCaptureSessionDidStopRunningNotification - object:m_captureSession]; - - return self; -} - -- (void) dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self - name:AVCaptureSessionRuntimeErrorNotification - object:m_captureSession]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:AVCaptureSessionDidStartRunningNotification - object:m_captureSession]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:AVCaptureSessionDidStopRunningNotification - object:m_captureSession]; - [m_captureSession release]; - [super dealloc]; -} - -- (void) processRuntimeError:(NSNotification *)notification -{ - Q_UNUSED(notification); - QMetaObject::invokeMethod(m_session, "processRuntimeError", Qt::AutoConnection); -} - -- (void) processSessionStarted:(NSNotification *)notification -{ - Q_UNUSED(notification); - QMetaObject::invokeMethod(m_session, "processSessionStarted", Qt::AutoConnection); -} - -- (void) processSessionStopped:(NSNotification *)notification -{ - Q_UNUSED(notification); - QMetaObject::invokeMethod(m_session, "processSessionStopped", Qt::AutoConnection); -} - -@end - -AVFCameraSession::AVFCameraSession(AVFCameraService *service, QObject *parent) - : QObject(parent) - , m_service(service) - , m_capturePreviewWindowOutput(nullptr) - , m_state(QCamera::UnloadedState) - , m_active(false) - , m_videoInput(nil) - , m_defaultCodec(0) -{ - m_captureSession = [[AVCaptureSession alloc] init]; - m_observer = [[AVFCameraSessionObserver alloc] initWithCameraSession:this]; - - //configuration is commited during transition to Active state - [m_captureSession beginConfiguration]; -} - -AVFCameraSession::~AVFCameraSession() -{ - if (m_capturePreviewWindowOutput) { - m_capturePreviewWindowOutput->setLayer(nil); - } - - if (m_videoInput) { - [m_captureSession removeInput:m_videoInput]; - [m_videoInput release]; - } - - [m_observer release]; - [m_captureSession release]; -} - -int AVFCameraSession::defaultCameraIndex() -{ - updateCameraDevices(); - return m_defaultCameraIndex; -} - -const QList<AVFCameraInfo> &AVFCameraSession::availableCameraDevices() -{ - updateCameraDevices(); - return m_cameraDevices; -} - -AVFCameraInfo AVFCameraSession::cameraDeviceInfo(const QByteArray &device) -{ - updateCameraDevices(); - - for (const AVFCameraInfo &info : qAsConst(m_cameraDevices)) { - if (info.deviceId == device) - return info; - } - - return AVFCameraInfo(); -} - -void AVFCameraSession::updateCameraDevices() -{ -#ifdef Q_OS_IOS - // Cameras can't change dynamically on iOS. Update only once. - if (!m_cameraDevices.isEmpty()) - return; -#else - // On OS X, cameras can be added or removed. Update the list every time, but not more than - // once every 500 ms - static QElapsedTimer timer; - if (timer.isValid() && timer.elapsed() < 500) // ms - return; -#endif - - m_defaultCameraIndex = -1; - m_cameraDevices.clear(); - - AVCaptureDevice *defaultDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; - NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; - for (AVCaptureDevice *device in videoDevices) { - if (defaultDevice && [defaultDevice.uniqueID isEqualToString:device.uniqueID]) - m_defaultCameraIndex = m_cameraDevices.count(); - - AVFCameraInfo info; - info.deviceId = QByteArray([[device uniqueID] UTF8String]); - info.description = QString::fromNSString([device localizedName]); - - // There is no API to get the camera sensor orientation, however, cameras are always - // mounted in landscape on iDevices. - // - Back-facing cameras have the top side of the sensor aligned with the right side of - // the screen when held in portrait ==> 270 degrees clockwise angle - // - Front-facing cameras have the top side of the sensor aligned with the left side of - // the screen when held in portrait ==> 270 degrees clockwise angle - // On OS X, the position will always be unspecified and the sensor orientation unknown. - switch (device.position) { - case AVCaptureDevicePositionBack: - info.position = QCamera::BackFace; - info.orientation = 270; - break; - case AVCaptureDevicePositionFront: - info.position = QCamera::FrontFace; - info.orientation = 270; - break; - default: - info.position = QCamera::UnspecifiedPosition; - info.orientation = 0; - break; - } - - m_cameraDevices.append(info); - } - -#ifndef Q_OS_IOS - timer.restart(); -#endif -} - -void AVFCameraSession::setVideoOutput(AVFCameraRendererControl *output) -{ - m_videoOutput = output; - if (output) - output->configureAVCaptureSession(this); -} - -void AVFCameraSession::setCapturePreviewOutput(AVFCameraWindowControl *output) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << output; -#endif - - if (m_capturePreviewWindowOutput == output) - return; - - if (m_capturePreviewWindowOutput) - m_capturePreviewWindowOutput->setLayer(nil); - - m_capturePreviewWindowOutput = output; - - if (m_capturePreviewWindowOutput) { - AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:m_captureSession]; - m_capturePreviewWindowOutput->setLayer(previewLayer); - if (auto *camera = m_service->cameraControl()) { - m_capturePreviewWindowOutput->setNativeSize(camera->viewfinderSettings().resolution()); - } - } -} - -AVCaptureDevice *AVFCameraSession::videoCaptureDevice() const -{ - if (m_videoInput) - return m_videoInput.device; - - return nullptr; -} - -QCamera::State AVFCameraSession::state() const -{ - if (m_active) - return QCamera::ActiveState; - - return m_state == QCamera::ActiveState ? QCamera::LoadedState : m_state; -} - -void AVFCameraSession::setState(QCamera::State newState) -{ - if (m_state == newState) - return; - - qDebugCamera() << Q_FUNC_INFO << m_state << " -> " << newState; - - QCamera::State oldState = m_state; - m_state = newState; - - //attach video input during Unloaded->Loaded transition - if (oldState == QCamera::UnloadedState) - attachVideoInputDevice(); - - if (m_state == QCamera::ActiveState) { - Q_EMIT readyToConfigureConnections(); - m_defaultCodec = 0; - defaultCodec(); - - bool activeFormatSet = applyImageEncoderSettings() - | applyViewfinderSettings(); - - [m_captureSession commitConfiguration]; - - if (activeFormatSet) { - // According to the doc, the capture device must be locked before - // startRunning to prevent the format we set to be overriden by the - // session preset. - [videoCaptureDevice() lockForConfiguration:nil]; - } - - [m_captureSession startRunning]; - - if (activeFormatSet) - [videoCaptureDevice() unlockForConfiguration]; - } - - if (oldState == QCamera::ActiveState) { - [m_captureSession stopRunning]; - [m_captureSession beginConfiguration]; - } - - Q_EMIT stateChanged(m_state); -} - -void AVFCameraSession::processRuntimeError() -{ - qWarning() << tr("Runtime camera error"); - Q_EMIT error(QCamera::CameraError, tr("Runtime camera error")); -} - -void AVFCameraSession::processSessionStarted() -{ - qDebugCamera() << Q_FUNC_INFO; - if (!m_active) { - m_active = true; - Q_EMIT activeChanged(m_active); - Q_EMIT stateChanged(state()); - } -} - -void AVFCameraSession::processSessionStopped() -{ - qDebugCamera() << Q_FUNC_INFO; - if (m_active) { - m_active = false; - Q_EMIT activeChanged(m_active); - Q_EMIT stateChanged(state()); - } -} - -void AVFCameraSession::onCaptureModeChanged(QCamera::CaptureModes mode) -{ - Q_UNUSED(mode); - - const QCamera::State s = state(); - if (s == QCamera::LoadedState || s == QCamera::ActiveState) { - applyImageEncoderSettings(); - applyViewfinderSettings(); - } -} - -void AVFCameraSession::attachVideoInputDevice() -{ - //Attach video input device: - if (m_service->videoDeviceControl()->isDirty()) { - if (m_videoInput) { - [m_captureSession removeInput:m_videoInput]; - [m_videoInput release]; - m_videoInput = nullptr; - m_activeCameraInfo = AVFCameraInfo(); - } - - AVCaptureDevice *videoDevice = m_service->videoDeviceControl()->createCaptureDevice(); - - NSError *error = nil; - m_videoInput = [AVCaptureDeviceInput - deviceInputWithDevice:videoDevice - error:&error]; - - if (!m_videoInput) { - qWarning() << "Failed to create video device input"; - } else { - if ([m_captureSession canAddInput:m_videoInput]) { - m_activeCameraInfo = m_cameraDevices.at(m_service->videoDeviceControl()->selectedDevice()); - [m_videoInput retain]; - [m_captureSession addInput:m_videoInput]; - } else { - qWarning() << "Failed to connect video device input"; - } - } - } -} - -bool AVFCameraSession::applyImageEncoderSettings() -{ - if (AVFImageEncoderControl *control = m_service->imageEncoderControl()) - return control->applySettings(); - - return false; -} - -bool AVFCameraSession::applyViewfinderSettings() -{ - if (auto *camera = m_service->cameraControl()) { - QCamera::CaptureModes currentMode = m_service->cameraControl()->captureMode(); - QCameraViewfinderSettings vfSettings(camera->requestedSettings()); - // Viewfinder and image capture solutions must be the same, if an image capture - // resolution is set, it takes precedence over the viewfinder resolution. - if (currentMode.testFlag(QCamera::CaptureStillImage)) { - const QSize imageResolution(m_service->imageEncoderControl()->requestedSettings().resolution()); - if (!imageResolution.isNull() && imageResolution.isValid()) - vfSettings.setResolution(imageResolution); - } - - camera->applySettings(vfSettings); - - if (m_capturePreviewWindowOutput) - m_capturePreviewWindowOutput->setNativeSize(camera->viewfinderSettings().resolution()); - - return !vfSettings.isNull(); - } - - return false; -} - -void AVFCameraSession::addProbe(AVFMediaVideoProbeControl *probe) -{ - m_videoProbesMutex.lock(); - if (probe) - m_videoProbes << probe; - m_videoProbesMutex.unlock(); -} - -void AVFCameraSession::removeProbe(AVFMediaVideoProbeControl *probe) -{ - m_videoProbesMutex.lock(); - m_videoProbes.remove(probe); - m_videoProbesMutex.unlock(); -} - -FourCharCode AVFCameraSession::defaultCodec() -{ - if (!m_defaultCodec) { - if (AVCaptureDevice *device = videoCaptureDevice()) { - AVCaptureDeviceFormat *format = device.activeFormat; - if (!format || !format.formatDescription) - return m_defaultCodec; - m_defaultCodec = CMVideoFormatDescriptionGetCodecType(format.formatDescription); - } - } - return m_defaultCodec; -} - -void AVFCameraSession::onCameraFrameFetched(const QVideoFrame &frame) -{ - Q_EMIT newViewfinderFrame(frame); - - m_videoProbesMutex.lock(); - QSet<AVFMediaVideoProbeControl *>::const_iterator i = m_videoProbes.constBegin(); - while (i != m_videoProbes.constEnd()) { - (*i)->newFrameProbed(frame); - ++i; - } - m_videoProbesMutex.unlock(); -} - -#include "moc_avfcamerasession.cpp" diff --git a/src/plugins/avfoundation/camera/avfcamerautility.h b/src/plugins/avfoundation/camera/avfcamerautility.h deleted file mode 100644 index 2e8bf39b4..000000000 --- a/src/plugins/avfoundation/camera/avfcamerautility.h +++ /dev/null @@ -1,179 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFCAMERAUTILITY_H -#define AVFCAMERAUTILITY_H - -#include <QtCore/qglobal.h> -#include <QtCore/qdebug.h> -#include <QtCore/qlist.h> -#include <QtCore/qpair.h> -#include <QtCore/qsize.h> - -#include <AVFoundation/AVFoundation.h> - -// In case we have SDK below 10.7/7.0: -@class AVCaptureDeviceFormat; - -QT_BEGIN_NAMESPACE - -class AVFConfigurationLock -{ -public: - explicit AVFConfigurationLock(AVCaptureDevice *captureDevice) - : m_captureDevice(captureDevice), - m_locked(false) - { - Q_ASSERT(m_captureDevice); - NSError *error = nil; - m_locked = [m_captureDevice lockForConfiguration:&error]; - } - - ~AVFConfigurationLock() - { - if (m_locked) - [m_captureDevice unlockForConfiguration]; - } - - operator bool() const - { - return m_locked; - } - -private: - Q_DISABLE_COPY(AVFConfigurationLock) - - AVCaptureDevice *m_captureDevice; - bool m_locked; -}; - -struct AVFObjectDeleter { - static void cleanup(NSObject *obj) - { - if (obj) - [obj release]; - } -}; - -template<class T> -class AVFScopedPointer : public QScopedPointer<NSObject, AVFObjectDeleter> -{ -public: - AVFScopedPointer() {} - explicit AVFScopedPointer(T *ptr) : QScopedPointer(ptr) {} - operator T*() const - { - // Quite handy operator to enable Obj-C messages: [ptr someMethod]; - return data(); - } - - T *data() const - { - return static_cast<T *>(QScopedPointer::data()); - } - - T *take() - { - return static_cast<T *>(QScopedPointer::take()); - } -}; - -template<> -class AVFScopedPointer<dispatch_queue_t> -{ -public: - AVFScopedPointer() : m_queue(nullptr) {} - explicit AVFScopedPointer(dispatch_queue_t q) : m_queue(q) {} - - ~AVFScopedPointer() - { - if (m_queue) - dispatch_release(m_queue); - } - - operator dispatch_queue_t() const - { - // Quite handy operator to enable Obj-C messages: [ptr someMethod]; - return m_queue; - } - - dispatch_queue_t data() const - { - return m_queue; - } - - void reset(dispatch_queue_t q = nullptr) - { - if (m_queue) - dispatch_release(m_queue); - m_queue = q; - } - -private: - dispatch_queue_t m_queue; - - Q_DISABLE_COPY(AVFScopedPointer) -}; - -typedef QPair<qreal, qreal> AVFPSRange; -AVFPSRange qt_connection_framerates(AVCaptureConnection *videoConnection); - -QList<AVCaptureDeviceFormat *> qt_unique_device_formats(AVCaptureDevice *captureDevice, - FourCharCode preferredFormat); -QSize qt_device_format_resolution(AVCaptureDeviceFormat *format); -QSize qt_device_format_high_resolution(AVCaptureDeviceFormat *format); -QSize qt_device_format_pixel_aspect_ratio(AVCaptureDeviceFormat *format); -QList<AVFPSRange> qt_device_format_framerates(AVCaptureDeviceFormat *format); -AVCaptureDeviceFormat *qt_find_best_resolution_match(AVCaptureDevice *captureDevice, const QSize &res, - FourCharCode preferredFormat, bool stillImage = true); -AVCaptureDeviceFormat *qt_find_best_framerate_match(AVCaptureDevice *captureDevice, - FourCharCode preferredFormat, - Float64 fps); -AVFrameRateRange *qt_find_supported_framerate_range(AVCaptureDeviceFormat *format, Float64 fps); - -bool qt_formats_are_equal(AVCaptureDeviceFormat *f1, AVCaptureDeviceFormat *f2); -bool qt_set_active_format(AVCaptureDevice *captureDevice, AVCaptureDeviceFormat *format, bool preserveFps); - -AVFPSRange qt_current_framerates(AVCaptureDevice *captureDevice, AVCaptureConnection *videoConnection); -void qt_set_framerate_limits(AVCaptureDevice *captureDevice, AVCaptureConnection *videoConnection, - qreal minFPS, qreal maxFPS); - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcamerautility.mm b/src/plugins/avfoundation/camera/avfcamerautility.mm deleted file mode 100644 index 25ccc4b01..000000000 --- a/src/plugins/avfoundation/camera/avfcamerautility.mm +++ /dev/null @@ -1,575 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfcamerautility.h" -#include "avfcameradebug.h" - -#include <QtCore/qvector.h> -#include <QtCore/qpair.h> -#include <private/qmultimediautils_p.h> - -#include <functional> -#include <algorithm> -#include <limits> -#include <tuple> - -QT_BEGIN_NAMESPACE - -AVFPSRange qt_connection_framerates(AVCaptureConnection *videoConnection) -{ - Q_ASSERT(videoConnection); - - AVFPSRange newRange; - // "The value in the videoMinFrameDuration is equivalent to the reciprocal - // of the maximum framerate, the value in the videoMaxFrameDuration is equivalent - // to the reciprocal of the minimum framerate." - if (videoConnection.supportsVideoMinFrameDuration) { - const CMTime cmMin = videoConnection.videoMinFrameDuration; - if (CMTimeCompare(cmMin, kCMTimeInvalid)) { // Has some non-default value: - if (const Float64 minSeconds = CMTimeGetSeconds(cmMin)) - newRange.second = 1. / minSeconds; - } - } - - if (videoConnection.supportsVideoMaxFrameDuration) { - const CMTime cmMax = videoConnection.videoMaxFrameDuration; - if (CMTimeCompare(cmMax, kCMTimeInvalid)) { - if (const Float64 maxSeconds = CMTimeGetSeconds(cmMax)) - newRange.first = 1. / maxSeconds; - } - } - - return newRange; -} - -namespace { - -inline bool qt_area_sane(const QSize &size) -{ - return !size.isNull() && size.isValid() - && std::numeric_limits<int>::max() / size.width() >= size.height(); -} - -template <template <typename...> class Comp> // std::less or std::greater (or std::equal_to) -struct ByResolution -{ - bool operator() (AVCaptureDeviceFormat *f1, AVCaptureDeviceFormat *f2)const - { - Q_ASSERT(f1 && f2); - const QSize r1(qt_device_format_resolution(f1)); - const QSize r2(qt_device_format_resolution(f2)); - // use std::tuple for lexicograpical sorting: - const Comp<std::tuple<int, int>> op = {}; - return op(std::make_tuple(r1.width(), r1.height()), - std::make_tuple(r2.width(), r2.height())); - } -}; - -struct FormatHasNoFPSRange : std::unary_function<AVCaptureDeviceFormat *, bool> -{ - bool operator() (AVCaptureDeviceFormat *format) - { - Q_ASSERT(format); - return !format.videoSupportedFrameRateRanges || !format.videoSupportedFrameRateRanges.count; - } -}; - -Float64 qt_find_min_framerate_distance(AVCaptureDeviceFormat *format, Float64 fps) -{ - Q_ASSERT(format && format.videoSupportedFrameRateRanges - && format.videoSupportedFrameRateRanges.count); - - AVFrameRateRange *range = [format.videoSupportedFrameRateRanges objectAtIndex:0]; - Float64 distance = qAbs(range.maxFrameRate - fps); - for (NSUInteger i = 1, e = format.videoSupportedFrameRateRanges.count; i < e; ++i) { - range = [format.videoSupportedFrameRateRanges objectAtIndex:i]; - distance = qMin(distance, qAbs(range.maxFrameRate - fps)); - } - - return distance; -} - -} // Unnamed namespace. - -QVector<AVCaptureDeviceFormat *> qt_unique_device_formats(AVCaptureDevice *captureDevice, FourCharCode filter) -{ - // 'filter' is the format we prefer if we have duplicates. - Q_ASSERT(captureDevice); - - QVector<AVCaptureDeviceFormat *> formats; - - if (!captureDevice.formats || !captureDevice.formats.count) - return formats; - - formats.reserve(captureDevice.formats.count); - for (AVCaptureDeviceFormat *format in captureDevice.formats) { - const QSize resolution(qt_device_format_resolution(format)); - if (resolution.isNull() || !resolution.isValid()) - continue; - formats << format; - } - - if (!formats.size()) - return formats; - - std::sort(formats.begin(), formats.end(), ByResolution<std::less>()); - - QSize size(qt_device_format_resolution(formats[0])); - FourCharCode codec = CMVideoFormatDescriptionGetCodecType(formats[0].formatDescription); - int last = 0; - for (int i = 1; i < formats.size(); ++i) { - const QSize nextSize(qt_device_format_resolution(formats[i])); - if (nextSize == size) { - if (codec == filter) - continue; - formats[last] = formats[i]; - } else { - ++last; - formats[last] = formats[i]; - size = nextSize; - } - codec = CMVideoFormatDescriptionGetCodecType(formats[i].formatDescription); - } - formats.resize(last + 1); - - return formats; -} - -QSize qt_device_format_resolution(AVCaptureDeviceFormat *format) -{ - if (!format || !format.formatDescription) - return QSize(); - - const CMVideoDimensions res = CMVideoFormatDescriptionGetDimensions(format.formatDescription); - return QSize(res.width, res.height); -} - -QSize qt_device_format_high_resolution(AVCaptureDeviceFormat *format) -{ - Q_ASSERT(format); - QSize res; -#if defined(Q_OS_IOS) - const CMVideoDimensions hrDim(format.highResolutionStillImageDimensions); - res.setWidth(hrDim.width); - res.setHeight(hrDim.height); -#endif - return res; -} - -QVector<AVFPSRange> qt_device_format_framerates(AVCaptureDeviceFormat *format) -{ - Q_ASSERT(format); - - QVector<AVFPSRange> qtRanges; - - if (!format.videoSupportedFrameRateRanges || !format.videoSupportedFrameRateRanges.count) - return qtRanges; - - qtRanges.reserve(format.videoSupportedFrameRateRanges.count); - for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) - qtRanges << AVFPSRange(range.minFrameRate, range.maxFrameRate); - - return qtRanges; -} - -QSize qt_device_format_pixel_aspect_ratio(AVCaptureDeviceFormat *format) -{ - Q_ASSERT(format); - - if (!format.formatDescription) { - qDebugCamera() << Q_FUNC_INFO << "no format description found"; - return QSize(); - } - - const CMVideoDimensions res = CMVideoFormatDescriptionGetDimensions(format.formatDescription); - const CGSize resPAR = CMVideoFormatDescriptionGetPresentationDimensions(format.formatDescription, true, false); - - if (qAbs(resPAR.width - res.width) < 1.) { - // "Pixel aspect ratio is used to adjust the width, leaving the height alone." - return QSize(1, 1); - } - - if (!res.width || !resPAR.width) - return QSize(); - - int n, d; - qt_real_to_fraction(resPAR.width > res.width - ? res.width / qreal(resPAR.width) - : resPAR.width / qreal(res.width), - &n, &d); - - return QSize(n, d); -} - -AVCaptureDeviceFormat *qt_find_best_resolution_match(AVCaptureDevice *captureDevice, - const QSize &request, - FourCharCode filter, - bool stillImage) -{ - Q_ASSERT(captureDevice); - Q_ASSERT(!request.isNull() && request.isValid()); - - if (!captureDevice.formats || !captureDevice.formats.count) - return nullptr; - - QVector<AVCaptureDeviceFormat *> formats(qt_unique_device_formats(captureDevice, filter)); - - for (int i = 0; i < formats.size(); ++i) { - AVCaptureDeviceFormat *format = formats[i]; - if (qt_device_format_resolution(format) == request) - return format; - // iOS only (still images). - if (stillImage && qt_device_format_high_resolution(format) == request) - return format; - } - - if (!qt_area_sane(request)) - return nullptr; - - typedef QPair<QSize, AVCaptureDeviceFormat *> FormatPair; - - QVector<FormatPair> pairs; // default|HR sizes - pairs.reserve(formats.size()); - - for (int i = 0; i < formats.size(); ++i) { - AVCaptureDeviceFormat *format = formats[i]; - const QSize res(qt_device_format_resolution(format)); - if (!res.isNull() && res.isValid() && qt_area_sane(res)) - pairs << FormatPair(res, format); - const QSize highRes(qt_device_format_high_resolution(format)); - if (stillImage && !highRes.isNull() && highRes.isValid() && qt_area_sane(highRes)) - pairs << FormatPair(highRes, format); - } - - if (!pairs.size()) - return nullptr; - - AVCaptureDeviceFormat *best = pairs[0].second; - QSize next(pairs[0].first); - int wDiff = qAbs(request.width() - next.width()); - int hDiff = qAbs(request.height() - next.height()); - const int area = request.width() * request.height(); - int areaDiff = qAbs(area - next.width() * next.height()); - for (int i = 1; i < pairs.size(); ++i) { - next = pairs[i].first; - const int newWDiff = qAbs(next.width() - request.width()); - const int newHDiff = qAbs(next.height() - request.height()); - const int newAreaDiff = qAbs(area - next.width() * next.height()); - - if ((newWDiff < wDiff && newHDiff < hDiff) - || ((newWDiff <= wDiff || newHDiff <= hDiff) && newAreaDiff <= areaDiff)) { - wDiff = newWDiff; - hDiff = newHDiff; - best = pairs[i].second; - areaDiff = newAreaDiff; - } - } - - return best; -} - -AVCaptureDeviceFormat *qt_find_best_framerate_match(AVCaptureDevice *captureDevice, - FourCharCode filter, - Float64 fps) -{ - Q_ASSERT(captureDevice); - Q_ASSERT(fps > 0.); - - const qreal epsilon = 0.1; - - QVector<AVCaptureDeviceFormat *>sorted(qt_unique_device_formats(captureDevice, filter)); - // Sort formats by their resolution in decreasing order: - std::sort(sorted.begin(), sorted.end(), ByResolution<std::greater>()); - // We can use only formats with framerate ranges: - sorted.erase(std::remove_if(sorted.begin(), sorted.end(), FormatHasNoFPSRange()), sorted.end()); - - if (!sorted.size()) - return nil; - - for (int i = 0; i < sorted.size(); ++i) { - AVCaptureDeviceFormat *format = sorted[i]; - for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) { - if (range.maxFrameRate - range.minFrameRate < epsilon) { - // On OS X ranges are points (built-in camera). - if (qAbs(fps - range.maxFrameRate) < epsilon) - return format; - } - - if (fps >= range.minFrameRate && fps <= range.maxFrameRate) - return format; - } - } - - Float64 distance = qt_find_min_framerate_distance(sorted[0], fps); - AVCaptureDeviceFormat *match = sorted[0]; - for (int i = 1; i < sorted.size(); ++i) { - const Float64 newDistance = qt_find_min_framerate_distance(sorted[i], fps); - if (newDistance < distance) { - distance = newDistance; - match = sorted[i]; - } - } - - return match; -} - -AVFrameRateRange *qt_find_supported_framerate_range(AVCaptureDeviceFormat *format, Float64 fps) -{ - Q_ASSERT(format && format.videoSupportedFrameRateRanges - && format.videoSupportedFrameRateRanges.count); - - const qreal epsilon = 0.1; - - for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) { - if (range.maxFrameRate - range.minFrameRate < epsilon) { - // On OS X ranges are points (built-in camera). - if (qAbs(fps - range.maxFrameRate) < epsilon) - return range; - } - - if (fps >= range.minFrameRate && fps <= range.maxFrameRate) - return range; - } - - AVFrameRateRange *match = [format.videoSupportedFrameRateRanges objectAtIndex:0]; - Float64 distance = qAbs(match.maxFrameRate - fps); - for (NSUInteger i = 1, e = format.videoSupportedFrameRateRanges.count; i < e; ++i) { - AVFrameRateRange *range = [format.videoSupportedFrameRateRanges objectAtIndex:i]; - const Float64 newDistance = qAbs(range.maxFrameRate - fps); - if (newDistance < distance) { - distance = newDistance; - match = range; - } - } - - return match; -} - -bool qt_formats_are_equal(AVCaptureDeviceFormat *f1, AVCaptureDeviceFormat *f2) -{ - if (f1 == f2) - return true; - - if (![f1.mediaType isEqualToString:f2.mediaType]) - return false; - - return CMFormatDescriptionEqual(f1.formatDescription, f2.formatDescription); -} - -bool qt_set_active_format(AVCaptureDevice *captureDevice, AVCaptureDeviceFormat *format, bool preserveFps) -{ - static bool firstSet = true; - - if (!captureDevice || !format) - return false; - - if (qt_formats_are_equal(captureDevice.activeFormat, format)) { - if (firstSet) { - // The capture device format is persistent. The first time we set a format, report that - // it changed even if the formats are the same. - // This prevents the session from resetting the format to the default value. - firstSet = false; - return true; - } - return false; - } - - firstSet = false; - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qWarning("Failed to set active format (lock failed)"); - return false; - } - - // Changing the activeFormat resets the frame rate. - AVFPSRange fps; - if (preserveFps) - fps = qt_current_framerates(captureDevice, nil); - - captureDevice.activeFormat = format; - - if (preserveFps) - qt_set_framerate_limits(captureDevice, nil, fps.first, fps.second); - - return true; -} - -void qt_set_framerate_limits(AVCaptureConnection *videoConnection, qreal minFPS, qreal maxFPS) -{ - Q_ASSERT(videoConnection); - - if (minFPS < 0. || maxFPS < 0. || (maxFPS && maxFPS < minFPS)) { - qDebugCamera() << Q_FUNC_INFO << "invalid framerates (min, max):" - << minFPS << maxFPS; - return; - } - - CMTime minDuration = kCMTimeInvalid; - if (maxFPS > 0.) { - if (!videoConnection.supportsVideoMinFrameDuration) - qDebugCamera() << Q_FUNC_INFO << "maximum framerate is not supported"; - else - minDuration = CMTimeMake(1, maxFPS); - } - if (videoConnection.supportsVideoMinFrameDuration) - videoConnection.videoMinFrameDuration = minDuration; - - CMTime maxDuration = kCMTimeInvalid; - if (minFPS > 0.) { - if (!videoConnection.supportsVideoMaxFrameDuration) - qDebugCamera() << Q_FUNC_INFO << "minimum framerate is not supported"; - else - maxDuration = CMTimeMake(1, minFPS); - } - if (videoConnection.supportsVideoMaxFrameDuration) - videoConnection.videoMaxFrameDuration = maxDuration; -} - -CMTime qt_adjusted_frame_duration(AVFrameRateRange *range, qreal fps) -{ - Q_ASSERT(range); - Q_ASSERT(fps > 0.); - - if (range.maxFrameRate - range.minFrameRate < 0.1) { - // Can happen on OS X. - return range.minFrameDuration; - } - - if (fps <= range.minFrameRate) - return range.maxFrameDuration; - if (fps >= range.maxFrameRate) - return range.minFrameDuration; - - int n, d; - qt_real_to_fraction(1. / fps, &n, &d); - return CMTimeMake(n, d); -} - -void qt_set_framerate_limits(AVCaptureDevice *captureDevice, qreal minFPS, qreal maxFPS) -{ - Q_ASSERT(captureDevice); - if (!captureDevice.activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "no active capture device format"; - return; - } - - if (minFPS < 0. || maxFPS < 0. || (maxFPS && maxFPS < minFPS)) { - qDebugCamera() << Q_FUNC_INFO << "invalid framerates (min, max):" - << minFPS << maxFPS; - return; - } - - CMTime minFrameDuration = kCMTimeInvalid; - CMTime maxFrameDuration = kCMTimeInvalid; - if (maxFPS || minFPS) { - AVFrameRateRange *range = qt_find_supported_framerate_range(captureDevice.activeFormat, - maxFPS ? maxFPS : minFPS); - if (!range) { - qDebugCamera() << Q_FUNC_INFO << "no framerate range found, (min, max):" - << minFPS << maxFPS; - return; - } - - if (maxFPS) - minFrameDuration = qt_adjusted_frame_duration(range, maxFPS); - if (minFPS) - maxFrameDuration = qt_adjusted_frame_duration(range, minFPS); - } - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - // While Apple's docs say kCMTimeInvalid will end in default - // settings for this format, kCMTimeInvalid on OS X ends with a runtime - // exception: - // "The activeVideoMinFrameDuration passed is not supported by the device." - // Instead, use the first item in the supported frame rates. -#ifdef Q_OS_IOS - [captureDevice setActiveVideoMinFrameDuration:minFrameDuration]; - [captureDevice setActiveVideoMaxFrameDuration:maxFrameDuration]; -#elif defined(Q_OS_MACOS) - if (CMTimeCompare(minFrameDuration, kCMTimeInvalid) == 0 - && CMTimeCompare(maxFrameDuration, kCMTimeInvalid) == 0) { - AVFrameRateRange *range = captureDevice.activeFormat.videoSupportedFrameRateRanges.firstObject; - minFrameDuration = range.minFrameDuration; - maxFrameDuration = range.maxFrameDuration; - } - - if (CMTimeCompare(minFrameDuration, kCMTimeInvalid)) - [captureDevice setActiveVideoMinFrameDuration:minFrameDuration]; - - if (CMTimeCompare(maxFrameDuration, kCMTimeInvalid)) - [captureDevice setActiveVideoMaxFrameDuration:maxFrameDuration]; -#endif // Q_OS_MACOS -} - -void qt_set_framerate_limits(AVCaptureDevice *captureDevice, AVCaptureConnection *videoConnection, - qreal minFPS, qreal maxFPS) -{ - Q_UNUSED(videoConnection); - Q_ASSERT(captureDevice); - qt_set_framerate_limits(captureDevice, minFPS, maxFPS); -} - -AVFPSRange qt_current_framerates(AVCaptureDevice *captureDevice, AVCaptureConnection *videoConnection) -{ - Q_UNUSED(videoConnection); - Q_ASSERT(captureDevice); - - AVFPSRange fps; - const CMTime minDuration = captureDevice.activeVideoMinFrameDuration; - if (CMTimeCompare(minDuration, kCMTimeInvalid)) { - if (const Float64 minSeconds = CMTimeGetSeconds(minDuration)) - fps.second = 1. / minSeconds; // Max FPS = 1 / MinDuration. - } - - const CMTime maxDuration = captureDevice.activeVideoMaxFrameDuration; - if (CMTimeCompare(maxDuration, kCMTimeInvalid)) { - if (const Float64 maxSeconds = CMTimeGetSeconds(maxDuration)) - fps.first = 1. / maxSeconds; // Min FPS = 1 / MaxDuration. - } - - return fps; -} - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfcamerawindowcontrol.h b/src/plugins/avfoundation/camera/avfcamerawindowcontrol.h deleted file mode 100644 index d1a950e38..000000000 --- a/src/plugins/avfoundation/camera/avfcamerawindowcontrol.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFCAMERAWINDOWCONTROL_H -#define AVFCAMERAWINDOWCONTROL_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 <QVideoWindowControl> - -@class AVCaptureVideoPreviewLayer; -#if defined(Q_OS_MACOS) -@class NSView; -typedef NSView NativeView; -#else -@class UIView; -typedef UIView NativeView; -#endif - -QT_BEGIN_NAMESPACE - -class AVFCameraWindowControl : public QVideoWindowControl -{ - Q_OBJECT -public: - AVFCameraWindowControl(QObject *parent = nullptr); - virtual ~AVFCameraWindowControl() override; - - // QVideoWindowControl interface -public: - WId winId() const override; - void setWinId(WId id) override; - - QRect displayRect() const override; - void setDisplayRect(const QRect &rect) override; - - bool isFullScreen() const override; - void setFullScreen(bool fullScreen) override; - - void repaint() override; - - QSize nativeSize() const override; - - Qt::AspectRatioMode aspectRatioMode() const override; - void setAspectRatioMode(Qt::AspectRatioMode mode) override; - - int brightness() const override; - void setBrightness(int brightness) override; - - int contrast() const override; - void setContrast(int contrast) override; - - int hue() const override; - void setHue(int hue) override; - - int saturation() const override; - void setSaturation(int saturation) override; - - // AVF Camera implementation details - void setNativeSize(QSize size); - void setLayer(AVCaptureVideoPreviewLayer *capturePreviewLayer); - -private: - void updateAspectRatio(); - void updateCaptureLayerBounds(); - - void retainNativeLayer(); - void releaseNativeLayer(); - - void attachNativeLayer(); - void detachNativeLayer(); - - WId m_winId{0}; - QRect m_displayRect; - bool m_fullscreen{false}; - Qt::AspectRatioMode m_aspectRatioMode{Qt::IgnoreAspectRatio}; - QSize m_nativeSize; - AVCaptureVideoPreviewLayer *m_captureLayer{nullptr}; - NativeView *m_nativeView{nullptr}; -}; - -QT_END_NAMESPACE - -#endif // AVFCAMERAWINDOWCONTROL_H diff --git a/src/plugins/avfoundation/camera/avfcamerawindowcontrol.mm b/src/plugins/avfoundation/camera/avfcamerawindowcontrol.mm deleted file mode 100644 index 5154d0646..000000000 --- a/src/plugins/avfoundation/camera/avfcamerawindowcontrol.mm +++ /dev/null @@ -1,262 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfcamerawindowcontrol.h" - -#import <AVFoundation/AVFoundation.h> -#import <QuartzCore/CATransaction.h> - -#if QT_HAS_INCLUDE(<AppKit/AppKit.h>) -#import <AppKit/AppKit.h> -#endif - -#if QT_HAS_INCLUDE(<UIKit/UIKit.h>) -#import <UIKit/UIKit.h> -#endif - -QT_USE_NAMESPACE - -AVFCameraWindowControl::AVFCameraWindowControl(QObject *parent) - : QVideoWindowControl(parent) -{ - setObjectName(QStringLiteral("AVFCameraWindowControl")); -} - -AVFCameraWindowControl::~AVFCameraWindowControl() -{ - releaseNativeLayer(); -} - -WId AVFCameraWindowControl::winId() const -{ - return m_winId; -} - -void AVFCameraWindowControl::setWinId(WId id) -{ - if (m_winId == id) - return; - - m_winId = id; - - detachNativeLayer(); - m_nativeView = (NativeView*)m_winId; - attachNativeLayer(); -} - -QRect AVFCameraWindowControl::displayRect() const -{ - return m_displayRect; -} - -void AVFCameraWindowControl::setDisplayRect(const QRect &rect) -{ - if (m_displayRect != rect) { - m_displayRect = rect; - updateCaptureLayerBounds(); - } -} - -bool AVFCameraWindowControl::isFullScreen() const -{ - return m_fullscreen; -} - -void AVFCameraWindowControl::setFullScreen(bool fullscreen) -{ - if (m_fullscreen != fullscreen) { - m_fullscreen = fullscreen; - Q_EMIT fullScreenChanged(fullscreen); - } -} - -void AVFCameraWindowControl::repaint() -{ - if (m_captureLayer) - [m_captureLayer setNeedsDisplay]; -} - -QSize AVFCameraWindowControl::nativeSize() const -{ - return m_nativeSize; -} - -void AVFCameraWindowControl::setNativeSize(QSize size) -{ - if (m_nativeSize != size) { - m_nativeSize = size; - Q_EMIT nativeSizeChanged(); - } -} - -Qt::AspectRatioMode AVFCameraWindowControl::aspectRatioMode() const -{ - return m_aspectRatioMode; -} - -void AVFCameraWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - if (m_aspectRatioMode != mode) { - m_aspectRatioMode = mode; - updateAspectRatio(); - } -} - -int AVFCameraWindowControl::brightness() const -{ - return 0; -} - -void AVFCameraWindowControl::setBrightness(int brightness) -{ - if (0 != brightness) - qWarning("AVFCameraWindowControl doesn't support changing Brightness"); -} - -int AVFCameraWindowControl::contrast() const -{ - return 0; -} - -void AVFCameraWindowControl::setContrast(int contrast) -{ - if (0 != contrast) - qWarning("AVFCameraWindowControl doesn't support changing Contrast"); -} - -int AVFCameraWindowControl::hue() const -{ - return 0; -} - -void AVFCameraWindowControl::setHue(int hue) -{ - if (0 != hue) - qWarning("AVFCameraWindowControl doesn't support changing Hue"); -} - -int AVFCameraWindowControl::saturation() const -{ - return 0; -} - -void AVFCameraWindowControl::setSaturation(int saturation) -{ - if (0 != saturation) - qWarning("AVFCameraWindowControl doesn't support changing Saturation"); -} - -void AVFCameraWindowControl::setLayer(AVCaptureVideoPreviewLayer *capturePreviewLayer) -{ - if (m_captureLayer == capturePreviewLayer) - return; - - releaseNativeLayer(); - - m_captureLayer = capturePreviewLayer; - - if (m_captureLayer) - retainNativeLayer(); -} - -void AVFCameraWindowControl::updateAspectRatio() -{ - if (m_captureLayer) { - switch (m_aspectRatioMode) { - case Qt::IgnoreAspectRatio: - [m_captureLayer setVideoGravity:AVLayerVideoGravityResize]; - break; - case Qt::KeepAspectRatio: - [m_captureLayer setVideoGravity:AVLayerVideoGravityResizeAspect]; - break; - case Qt::KeepAspectRatioByExpanding: - [m_captureLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; - break; - default: - break; - } - } -} - -void AVFCameraWindowControl::updateCaptureLayerBounds() -{ - if (m_captureLayer && m_nativeView) { - [CATransaction begin]; - [CATransaction setDisableActions: YES]; // disable animation/flicks - m_captureLayer.frame = m_displayRect.toCGRect(); - [CATransaction commit]; - } -} - -void AVFCameraWindowControl::retainNativeLayer() -{ - [m_captureLayer retain]; - - updateAspectRatio(); - attachNativeLayer(); -} - -void AVFCameraWindowControl::releaseNativeLayer() -{ - if (m_captureLayer) { - detachNativeLayer(); - [m_captureLayer release]; - m_captureLayer = nullptr; - } -} - -void AVFCameraWindowControl::attachNativeLayer() -{ - if (m_captureLayer && m_nativeView) { -#if defined(Q_OS_MACOS) - m_nativeView.wantsLayer = YES; -#endif - CALayer *nativeLayer = m_nativeView.layer; - [nativeLayer addSublayer:m_captureLayer]; - updateCaptureLayerBounds(); - } -} - -void AVFCameraWindowControl::detachNativeLayer() -{ - if (m_captureLayer && m_nativeView) - [m_captureLayer removeFromSuperlayer]; -} - -#include "moc_avfcamerawindowcontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfimagecapturecontrol.h b/src/plugins/avfoundation/camera/avfimagecapturecontrol.h deleted file mode 100644 index 7f3fdbd4d..000000000 --- a/src/plugins/avfoundation/camera/avfimagecapturecontrol.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFIMAGECAPTURECONTROL_H -#define AVFIMAGECAPTURECONTROL_H - -#import <AVFoundation/AVFoundation.h> - -#include <QtCore/qqueue.h> -#include <QtCore/qsemaphore.h> -#include <QtCore/qsharedpointer.h> -#include <QtMultimedia/qcameraimagecapturecontrol.h> -#include "avfcamerasession.h" -#include "avfstoragelocation.h" - -QT_BEGIN_NAMESPACE - -class AVFImageCaptureControl : public QCameraImageCaptureControl -{ -Q_OBJECT -public: - struct CaptureRequest { - int captureId; - QSharedPointer<QSemaphore> previewReady; - }; - - AVFImageCaptureControl(AVFCameraService *service, QObject *parent = nullptr); - ~AVFImageCaptureControl(); - - bool isReadyForCapture() const override; - - QCameraImageCapture::DriveMode driveMode() const override { return QCameraImageCapture::SingleImageCapture; } - void setDriveMode(QCameraImageCapture::DriveMode ) override {} - AVCaptureStillImageOutput *stillImageOutput() const {return m_stillImageOutput;} - - int capture(const QString &fileName) override; - void cancelCapture() override; - - QCameraImageCapture::CaptureDestinations captureDestination() const override; - void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) override; - -private Q_SLOTS: - void updateCaptureConnection(); - void updateReadyStatus(); - void onNewViewfinderFrame(const QVideoFrame &frame); - -private: - void makeCapturePreview(CaptureRequest request, const QVideoFrame &frame, int rotation); - - AVFCameraService *m_service; - AVFCameraSession *m_session; - AVFCameraControl *m_cameraControl; - bool m_ready; - int m_lastCaptureId; - AVCaptureStillImageOutput *m_stillImageOutput; - AVCaptureConnection *m_videoConnection; - AVFStorageLocation m_storageLocation; - - QMutex m_requestsMutex; - QQueue<CaptureRequest> m_captureRequests; - - QCameraImageCapture::CaptureDestinations m_destination = QCameraImageCapture::CaptureToFile; -}; - -Q_DECLARE_TYPEINFO(AVFImageCaptureControl::CaptureRequest, Q_PRIMITIVE_TYPE); - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm b/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm deleted file mode 100644 index 523dff20a..000000000 --- a/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm +++ /dev/null @@ -1,278 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfcameradebug.h" -#include "avfimagecapturecontrol.h" -#include "avfcameraservice.h" -#include "avfcamerautility.h" -#include "avfcameracontrol.h" -#include <private/qmemoryvideobuffer_p.h> - -#include <QtCore/qurl.h> -#include <QtCore/qfile.h> -#include <QtCore/qbuffer.h> -#include <QtConcurrent/qtconcurrentrun.h> -#include <QtGui/qimagereader.h> - -QT_USE_NAMESPACE - -AVFImageCaptureControl::AVFImageCaptureControl(AVFCameraService *service, QObject *parent) - : QCameraImageCaptureControl(parent) - , m_service(service) - , m_session(service->session()) - , m_cameraControl(service->cameraControl()) - , m_ready(false) - , m_lastCaptureId(0) - , m_videoConnection(nil) -{ - Q_UNUSED(service); - m_stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; - - NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: - AVVideoCodecJPEG, AVVideoCodecKey, nil]; - - [m_stillImageOutput setOutputSettings:outputSettings]; - [outputSettings release]; - connect(m_cameraControl, SIGNAL(captureModeChanged(QCamera::CaptureModes)), SLOT(updateReadyStatus())); - connect(m_cameraControl, SIGNAL(statusChanged(QCamera::Status)), SLOT(updateReadyStatus())); - - connect(m_session, SIGNAL(readyToConfigureConnections()), SLOT(updateCaptureConnection())); - connect(m_cameraControl, SIGNAL(captureModeChanged(QCamera::CaptureModes)), SLOT(updateCaptureConnection())); - - connect(m_session, &AVFCameraSession::newViewfinderFrame, - this, &AVFImageCaptureControl::onNewViewfinderFrame, - Qt::DirectConnection); -} - -AVFImageCaptureControl::~AVFImageCaptureControl() -{ -} - -bool AVFImageCaptureControl::isReadyForCapture() const -{ - return m_videoConnection && - m_cameraControl->captureMode().testFlag(QCamera::CaptureStillImage) && - m_cameraControl->status() == QCamera::ActiveStatus; -} - -void AVFImageCaptureControl::updateReadyStatus() -{ - if (m_ready != isReadyForCapture()) { - m_ready = !m_ready; - qDebugCamera() << "ReadyToCapture status changed:" << m_ready; - Q_EMIT readyForCaptureChanged(m_ready); - } -} - -int AVFImageCaptureControl::capture(const QString &fileName) -{ - m_lastCaptureId++; - - if (!isReadyForCapture()) { - QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, - Q_ARG(int, m_lastCaptureId), - Q_ARG(int, QCameraImageCapture::NotReadyError), - Q_ARG(QString, tr("Camera not ready"))); - return m_lastCaptureId; - } - - auto destination = m_service->imageCaptureControl()->captureDestination(); - QString actualFileName; - if (destination & QCameraImageCapture::CaptureToFile) { - actualFileName = m_storageLocation.generateFileName(fileName, - QCamera::CaptureStillImage, - QLatin1String("img_"), - QLatin1String("jpg")); - - qDebugCamera() << "Capture image to" << actualFileName; - } - - CaptureRequest request = { m_lastCaptureId, QSharedPointer<QSemaphore>::create()}; - m_requestsMutex.lock(); - m_captureRequests.enqueue(request); - m_requestsMutex.unlock(); - - [m_stillImageOutput captureStillImageAsynchronouslyFromConnection:m_videoConnection - completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) { - - if (error) { - QStringList messageParts; - messageParts << QString::fromUtf8([[error localizedDescription] UTF8String]); - messageParts << QString::fromUtf8([[error localizedFailureReason] UTF8String]); - messageParts << QString::fromUtf8([[error localizedRecoverySuggestion] UTF8String]); - - QString errorMessage = messageParts.join(" "); - qDebugCamera() << "Image capture failed:" << errorMessage; - - QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, - Q_ARG(int, request.captureId), - Q_ARG(int, QCameraImageCapture::ResourceError), - Q_ARG(QString, errorMessage)); - return; - } - - // Wait for the preview to be generated before saving the JPEG (but only - // if we have AVFCameraRendererControl attached). - // It is possible to stop camera immediately after trying to capture an - // image; this can result in a blocked callback's thread, waiting for a - // new viewfinder's frame to arrive/semaphore to be released. It is also - // unspecified on which thread this callback gets executed, (probably it's - // not the same thread that initiated a capture and stopped the camera), - // so we cannot reliably check the camera's status. Instead, we wait - // with a timeout and treat a failure to acquire a semaphore as an error. - if (!m_service->videoOutput() || request.previewReady->tryAcquire(1, 1000)) { - qDebugCamera() << "Image capture completed"; - - NSData *nsJpgData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer]; - QByteArray jpgData = QByteArray::fromRawData((const char *)[nsJpgData bytes], [nsJpgData length]); - - if (destination & QCameraImageCapture::CaptureToBuffer) { - QBuffer data(&jpgData); - QImageReader reader(&data, "JPEG"); - QSize size = reader.size(); - QVideoFrame frame(new QMemoryVideoBuffer(QByteArray(jpgData.constData(), jpgData.size()), -1), size, QVideoFrame::Format_Jpeg); - QMetaObject::invokeMethod(this, "imageAvailable", Qt::QueuedConnection, - Q_ARG(int, request.captureId), - Q_ARG(QVideoFrame, frame)); - } - - if (!(destination & QCameraImageCapture::CaptureToFile)) - return; - - QFile f(actualFileName); - if (f.open(QFile::WriteOnly)) { - if (f.write(jpgData) != -1) { - QMetaObject::invokeMethod(this, "imageSaved", Qt::QueuedConnection, - Q_ARG(int, request.captureId), - Q_ARG(QString, actualFileName)); - } else { - QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, - Q_ARG(int, request.captureId), - Q_ARG(int, QCameraImageCapture::OutOfSpaceError), - Q_ARG(QString, f.errorString())); - } - } else { - QString errorMessage = tr("Could not open destination file:\n%1").arg(actualFileName); - QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, - Q_ARG(int, request.captureId), - Q_ARG(int, QCameraImageCapture::ResourceError), - Q_ARG(QString, errorMessage)); - } - } else { - const QLatin1String errorMessage("Image capture failed: timed out waiting" - " for a preview frame."); - qDebugCamera() << errorMessage; - QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, - Q_ARG(int, request.captureId), - Q_ARG(int, QCameraImageCapture::ResourceError), - Q_ARG(QString, errorMessage)); - } - }]; - - return request.captureId; -} - -void AVFImageCaptureControl::onNewViewfinderFrame(const QVideoFrame &frame) -{ - QMutexLocker locker(&m_requestsMutex); - - if (m_captureRequests.isEmpty()) - return; - - CaptureRequest request = m_captureRequests.dequeue(); - Q_EMIT imageExposed(request.captureId); - - QtConcurrent::run(&AVFImageCaptureControl::makeCapturePreview, this, - request, - frame, - 0 /* rotation */); -} - -void AVFImageCaptureControl::makeCapturePreview(CaptureRequest request, - const QVideoFrame &frame, - int rotation) -{ - QTransform transform; - transform.rotate(rotation); - - Q_EMIT imageCaptured(request.captureId, frame.image().transformed(transform)); - - request.previewReady->release(); -} - -void AVFImageCaptureControl::cancelCapture() -{ - //not supported -} - -QCameraImageCapture::CaptureDestinations AVFImageCaptureControl::captureDestination() const -{ - return m_destination; -} - -void AVFImageCaptureControl::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) -{ - if (m_destination != destination) { - m_destination = destination; - updateCaptureConnection(); - } -} - -void AVFImageCaptureControl::updateCaptureConnection() -{ - if (m_session->videoCaptureDevice() - && m_cameraControl->captureMode().testFlag(QCamera::CaptureStillImage)) { - qDebugCamera() << Q_FUNC_INFO; - AVCaptureSession *captureSession = m_session->captureSession(); - - if (![captureSession.outputs containsObject:m_stillImageOutput]) { - if ([captureSession canAddOutput:m_stillImageOutput]) { - // Lock the video capture device to make sure the active format is not reset - const AVFConfigurationLock lock(m_session->videoCaptureDevice()); - [captureSession addOutput:m_stillImageOutput]; - m_videoConnection = [m_stillImageOutput connectionWithMediaType:AVMediaTypeVideo]; - updateReadyStatus(); - } - } else { - m_videoConnection = [m_stillImageOutput connectionWithMediaType:AVMediaTypeVideo]; - } - } -} - -#include "moc_avfimagecapturecontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfimageencodercontrol.h b/src/plugins/avfoundation/camera/avfimageencodercontrol.h deleted file mode 100644 index 7e2e34294..000000000 --- a/src/plugins/avfoundation/camera/avfimageencodercontrol.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFIMAGEENCODERCONTROL_H -#define AVFIMAGEENCODERCONTROL_H - -#include <QtMultimedia/qmediaencodersettings.h> -#include <QtMultimedia/qimageencodercontrol.h> - -#include <QtCore/qglobal.h> -#include <QtCore/qstring.h> -#include <QtCore/qlist.h> - -@class AVCaptureDeviceFormat; - -QT_BEGIN_NAMESPACE - -class AVFCameraService; - -class AVFImageEncoderControl : public QImageEncoderControl -{ - Q_OBJECT - - friend class AVFCameraSession; -public: - AVFImageEncoderControl(AVFCameraService *service); - - QStringList supportedImageCodecs() const override; - QString imageCodecDescription(const QString &codecName) const override; - QList<QSize> supportedResolutions(const QImageEncoderSettings &settings, - bool *continuous) const override; - QImageEncoderSettings imageSettings() const override; - void setImageSettings(const QImageEncoderSettings &settings) override; - - QImageEncoderSettings requestedSettings() const; - -private: - AVFCameraService *m_service; - QImageEncoderSettings m_settings; - - bool applySettings(); - bool videoCaptureDeviceIsValid() const; -}; - -QSize qt_image_high_resolution(AVCaptureDeviceFormat *fomat); - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfimageencodercontrol.mm b/src/plugins/avfoundation/camera/avfimageencodercontrol.mm deleted file mode 100644 index 104fb3c52..000000000 --- a/src/plugins/avfoundation/camera/avfimageencodercontrol.mm +++ /dev/null @@ -1,239 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfimageencodercontrol.h" -#include "avfimagecapturecontrol.h" -#include "avfcamerautility.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" -#include "avfcameradebug.h" -#include "avfcameracontrol.h" - -#include <QtMultimedia/qmediaencodersettings.h> - -#include <QtCore/qdebug.h> - -#include <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -AVFImageEncoderControl::AVFImageEncoderControl(AVFCameraService *service) - : m_service(service) -{ - Q_ASSERT(service); -} - -QStringList AVFImageEncoderControl::supportedImageCodecs() const -{ - return QStringList() << QLatin1String("jpeg"); -} - -QString AVFImageEncoderControl::imageCodecDescription(const QString &codecName) const -{ - if (codecName == QLatin1String("jpeg")) - return tr("JPEG image"); - - return QString(); -} - -QList<QSize> AVFImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, - bool *continuous) const -{ - Q_UNUSED(settings); - - QList<QSize> resolutions; - - if (!videoCaptureDeviceIsValid()) - return resolutions; - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - const QVector<AVCaptureDeviceFormat *> formats(qt_unique_device_formats(captureDevice, - m_service->session()->defaultCodec())); - - for (int i = 0; i < formats.size(); ++i) { - AVCaptureDeviceFormat *format = formats[i]; - - const QSize res(qt_device_format_resolution(format)); - if (!res.isNull() && res.isValid()) - resolutions << res; -#ifdef Q_OS_IOS - // From Apple's docs (iOS): - // By default, AVCaptureStillImageOutput emits images with the same dimensions as - // its source AVCaptureDevice instance’s activeFormat.formatDescription. However, - // if you set this property to YES, the receiver emits still images at the capture - // device’s highResolutionStillImageDimensions value. - const QSize hrRes(qt_device_format_high_resolution(format)); - if (!hrRes.isNull() && hrRes.isValid()) - resolutions << res; -#endif - } - - if (continuous) - *continuous = false; - - return resolutions; -} - -QImageEncoderSettings AVFImageEncoderControl::requestedSettings() const -{ - return m_settings; -} - -QImageEncoderSettings AVFImageEncoderControl::imageSettings() const -{ - QImageEncoderSettings settings; - - if (!videoCaptureDeviceIsValid()) - return settings; - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - if (!captureDevice.activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "no active format"; - return settings; - } - - QSize res(qt_device_format_resolution(captureDevice.activeFormat)); -#ifdef Q_OS_IOS - if (!m_service->imageCaptureControl() || !m_service->imageCaptureControl()->stillImageOutput()) { - qDebugCamera() << Q_FUNC_INFO << "no still image output"; - return settings; - } - - AVCaptureStillImageOutput *stillImageOutput = m_service->imageCaptureControl()->stillImageOutput(); - if (stillImageOutput.highResolutionStillImageOutputEnabled) - res = qt_device_format_high_resolution(captureDevice.activeFormat); -#endif - if (res.isNull() || !res.isValid()) { - qDebugCamera() << Q_FUNC_INFO << "failed to exctract the image resolution"; - return settings; - } - - settings.setResolution(res); - - settings.setCodec(QLatin1String("jpeg")); - - return settings; -} - -void AVFImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings) -{ - if (m_settings == settings) - return; - - m_settings = settings; - applySettings(); -} - -bool AVFImageEncoderControl::applySettings() -{ - if (!videoCaptureDeviceIsValid()) - return false; - - AVFCameraSession *session = m_service->session(); - if (!session || (session->state() != QCamera::ActiveState - && session->state() != QCamera::LoadedState) - || !m_service->cameraControl()->captureMode().testFlag(QCamera::CaptureStillImage)) { - return false; - } - - if (!m_service->imageCaptureControl() - || !m_service->imageCaptureControl()->stillImageOutput()) { - qDebugCamera() << Q_FUNC_INFO << "no still image output"; - return false; - } - - if (m_settings.codec().size() - && m_settings.codec() != QLatin1String("jpeg")) { - qDebugCamera() << Q_FUNC_INFO << "unsupported codec:" << m_settings.codec(); - return false; - } - - QSize res(m_settings.resolution()); - if (res.isNull()) { - qDebugCamera() << Q_FUNC_INFO << "invalid resolution:" << res; - return false; - } - - if (!res.isValid()) { - // Invalid == default value. - // Here we could choose the best format available, but - // activeFormat is already equal to 'preset high' by default, - // which is good enough, otherwise we can end in some format with low framerates. - return false; - } - - bool activeFormatChanged = false; - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - AVCaptureDeviceFormat *match = qt_find_best_resolution_match(captureDevice, res, - m_service->session()->defaultCodec()); - - if (!match) { - qDebugCamera() << Q_FUNC_INFO << "unsupported resolution:" << res; - return false; - } - - activeFormatChanged = qt_set_active_format(captureDevice, match, true); - -#ifdef Q_OS_IOS - AVCaptureStillImageOutput *imageOutput = m_service->imageCaptureControl()->stillImageOutput(); - if (res == qt_device_format_high_resolution(captureDevice.activeFormat)) - imageOutput.highResolutionStillImageOutputEnabled = YES; - else - imageOutput.highResolutionStillImageOutputEnabled = NO; -#endif - - return activeFormatChanged; -} - -bool AVFImageEncoderControl::videoCaptureDeviceIsValid() const -{ - if (!m_service->session() || !m_service->session()->videoCaptureDevice()) - return false; - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - if (!captureDevice.formats || !captureDevice.formats.count) - return false; - - return true; -} - -QT_END_NAMESPACE - -#include "moc_avfimageencodercontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfmediaassetwriter.h b/src/plugins/avfoundation/camera/avfmediaassetwriter.h deleted file mode 100644 index f063dab4b..000000000 --- a/src/plugins/avfoundation/camera/avfmediaassetwriter.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFMEDIAASSETWRITER_H -#define AVFMEDIAASSETWRITER_H - -#include "avfcamerautility.h" - -#include <QtCore/qglobal.h> - -#include <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -class AVFMediaRecorderControlIOS; -class AVFCameraService; - -QT_END_NAMESPACE - -@interface QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) : NSObject<AVCaptureVideoDataOutputSampleBufferDelegate, - AVCaptureAudioDataOutputSampleBufferDelegate> -- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(AVFMediaRecorderControlIOS) *)delegate; - -- (bool)setupWithFileURL:(NSURL *)fileURL - cameraService:(QT_PREPEND_NAMESPACE(AVFCameraService) *)service - audioSettings:(NSDictionary *)audioSettings - videoSettings:(NSDictionary *)videoSettings - transform:(CGAffineTransform)transform; - -// This to be called from the recorder control's thread: -- (void)start; -- (void)stop; -// This to be called from the recorder control's dtor: -- (void)abort; -- (qint64)durationInMs; - -@end - -#endif // AVFMEDIAASSETWRITER_H diff --git a/src/plugins/avfoundation/camera/avfmediaassetwriter.mm b/src/plugins/avfoundation/camera/avfmediaassetwriter.mm deleted file mode 100644 index 57c5cb8c5..000000000 --- a/src/plugins/avfoundation/camera/avfmediaassetwriter.mm +++ /dev/null @@ -1,514 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfaudioinputselectorcontrol.h" -#include "avfmediarecordercontrol_ios.h" -#include "avfcamerarenderercontrol.h" -#include "avfmediaassetwriter.h" -#include "avfcameraservice.h" -#include "avfcamerasession.h" -#include "avfcameradebug.h" -#include "avfmediacontainercontrol.h" - -#include <QtCore/qmetaobject.h> -#include <QtCore/qatomic.h> - -QT_USE_NAMESPACE - -namespace { - -bool qt_camera_service_isValid(AVFCameraService *service) -{ - if (!service || !service->session()) - return false; - - AVFCameraSession *session = service->session(); - if (!session->captureSession()) - return false; - - if (!session->videoInput()) - return false; - - if (!service->videoOutput() - || !service->videoOutput()->videoDataOutput()) { - return false; - } - - return true; -} - -enum WriterState -{ - WriterStateIdle, - WriterStateActive, - WriterStateAborted -}; - -using AVFAtomicInt64 = QAtomicInteger<qint64>; - -} // unnamed namespace - -@interface QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) (PrivateAPI) -- (bool)addAudioCapture; -- (bool)addWriterInputs; -- (void)setQueues; -- (void)updateDuration:(CMTime)newTimeStamp; -@end - -@implementation QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) -{ -@private - AVFCameraService *m_service; - - AVFScopedPointer<AVAssetWriterInput> m_cameraWriterInput; - AVFScopedPointer<AVCaptureDeviceInput> m_audioInput; - AVFScopedPointer<AVCaptureAudioDataOutput> m_audioOutput; - AVFScopedPointer<AVAssetWriterInput> m_audioWriterInput; - - AVCaptureDevice *m_audioCaptureDevice; - - // Queue to write sample buffers: - AVFScopedPointer<dispatch_queue_t> m_writerQueue; - // High priority serial queue for video output: - AVFScopedPointer<dispatch_queue_t> m_videoQueue; - // Serial queue for audio output: - AVFScopedPointer<dispatch_queue_t> m_audioQueue; - - AVFScopedPointer<AVAssetWriter> m_assetWriter; - - AVFMediaRecorderControlIOS *m_delegate; - - bool m_setStartTime; - - QAtomicInt m_state; - - CMTime m_startTime; - CMTime m_lastTimeStamp; - - NSDictionary *m_audioSettings; - NSDictionary *m_videoSettings; - - AVFAtomicInt64 m_durationInMs; -} - -- (id)initWithDelegate:(AVFMediaRecorderControlIOS *)delegate -{ - Q_ASSERT(delegate); - - if (self = [super init]) { - m_delegate = delegate; - m_setStartTime = true; - m_state.storeRelaxed(WriterStateIdle); - m_startTime = kCMTimeInvalid; - m_lastTimeStamp = kCMTimeInvalid; - m_durationInMs.storeRelaxed(0); - m_audioSettings = nil; - m_videoSettings = nil; - } - - return self; -} - -- (bool)setupWithFileURL:(NSURL *)fileURL - cameraService:(AVFCameraService *)service - audioSettings:(NSDictionary *)audioSettings - videoSettings:(NSDictionary *)videoSettings - transform:(CGAffineTransform)transform -{ - Q_ASSERT(fileURL); - - if (!qt_camera_service_isValid(service)) { - qDebugCamera() << Q_FUNC_INFO << "invalid camera service"; - return false; - } - - m_service = service; - m_audioSettings = audioSettings; - m_videoSettings = videoSettings; - - m_writerQueue.reset(dispatch_queue_create("asset-writer-queue", DISPATCH_QUEUE_SERIAL)); - if (!m_writerQueue) { - qDebugCamera() << Q_FUNC_INFO << "failed to create an asset writer's queue"; - return false; - } - - m_videoQueue.reset(dispatch_queue_create("video-output-queue", DISPATCH_QUEUE_SERIAL)); - if (!m_videoQueue) { - qDebugCamera() << Q_FUNC_INFO << "failed to create video queue"; - return false; - } - dispatch_set_target_queue(m_videoQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)); - m_audioQueue.reset(dispatch_queue_create("audio-output-queue", DISPATCH_QUEUE_SERIAL)); - if (!m_audioQueue) { - qDebugCamera() << Q_FUNC_INFO << "failed to create audio queue"; - // But we still can write video! - } - - m_assetWriter.reset([[AVAssetWriter alloc] initWithURL:fileURL - fileType:m_service->mediaContainerControl()->fileType() - error:nil]); - if (!m_assetWriter) { - qDebugCamera() << Q_FUNC_INFO << "failed to create asset writer"; - return false; - } - - bool audioCaptureOn = false; - - if (m_audioQueue) - audioCaptureOn = [self addAudioCapture]; - - if (![self addWriterInputs]) { - if (audioCaptureOn) { - AVCaptureSession *session = m_service->session()->captureSession(); - [session removeOutput:m_audioOutput]; - [session removeInput:m_audioInput]; - m_audioOutput.reset(); - m_audioInput.reset(); - m_audioCaptureDevice = 0; - } - m_assetWriter.reset(); - return false; - } - - m_cameraWriterInput.data().transform = transform; - - // Ready to start ... - return true; -} - -- (void)start -{ - [self setQueues]; - - m_setStartTime = true; - - m_state.storeRelease(WriterStateActive); - - [m_assetWriter startWriting]; - AVCaptureSession *session = m_service->session()->captureSession(); - if (!session.running) - [session startRunning]; -} - -- (void)stop -{ - if (m_state.loadAcquire() != WriterStateActive) - return; - - if ([m_assetWriter status] != AVAssetWriterStatusWriting) - return; - - // Do this here so that - - // 1. '-abort' should not try calling finishWriting again and - // 2. async block (see below) will know if recorder control was deleted - // before the block's execution: - m_state.storeRelease(WriterStateIdle); - // Now, since we have to ensure no sample buffers are - // appended after a call to finishWriting, we must - // ensure writer's queue sees this change in m_state - // _before_ we call finishWriting: - dispatch_sync(m_writerQueue, ^{}); - // Done, but now we also want to prevent video queue - // from updating our viewfinder: - dispatch_sync(m_videoQueue, ^{}); - - // Now we're safe to stop: - [m_assetWriter finishWritingWithCompletionHandler:^{ - // This block is async, so by the time it's executed, - // it's possible that render control was deleted already ... - if (m_state.loadAcquire() == WriterStateAborted) - return; - - AVCaptureSession *session = m_service->session()->captureSession(); - if (session.running) - [session stopRunning]; - [session removeOutput:m_audioOutput]; - [session removeInput:m_audioInput]; - QMetaObject::invokeMethod(m_delegate, "assetWriterFinished", Qt::QueuedConnection); - }]; -} - -- (void)abort -{ - // -abort is to be called from recorder control's dtor. - - if (m_state.fetchAndStoreRelease(WriterStateAborted) != WriterStateActive) { - // Not recording, nothing to stop. - return; - } - - // From Apple's docs: - // "To guarantee that all sample buffers are successfully written, - // you must ensure that all calls to appendSampleBuffer: and - // appendPixelBuffer:withPresentationTime: have returned before - // invoking this method." - // - // The only way we can ensure this is: - dispatch_sync(m_writerQueue, ^{}); - // At this point next block (if any) on the writer's queue - // will see m_state preventing it from any further processing. - dispatch_sync(m_videoQueue, ^{}); - // After this point video queue will not try to modify our - // viewfider, so we're safe to delete now. - - [m_assetWriter finishWritingWithCompletionHandler:^{ - }]; -} - -- (void)setStartTimeFrom:(CMSampleBufferRef)sampleBuffer -{ - // Writer's queue only. - Q_ASSERT(m_setStartTime); - Q_ASSERT(sampleBuffer); - - if (m_state.loadAcquire() != WriterStateActive) - return; - - QMetaObject::invokeMethod(m_delegate, "assetWriterStarted", Qt::QueuedConnection); - - m_durationInMs.storeRelease(0); - m_startTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); - m_lastTimeStamp = m_startTime; - [m_assetWriter startSessionAtSourceTime:m_startTime]; - m_setStartTime = false; -} - -- (void)writeVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer -{ - // This code is executed only on a writer's queue. - Q_ASSERT(sampleBuffer); - - if (m_state.loadAcquire() == WriterStateActive) { - if (m_setStartTime) - [self setStartTimeFrom:sampleBuffer]; - - if (m_cameraWriterInput.data().readyForMoreMediaData) { - [self updateDuration:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)]; - [m_cameraWriterInput appendSampleBuffer:sampleBuffer]; - } - } - - CFRelease(sampleBuffer); -} - -- (void)writeAudioSampleBuffer:(CMSampleBufferRef)sampleBuffer -{ - Q_ASSERT(sampleBuffer); - - // This code is executed only on a writer's queue. - if (m_state.loadAcquire() == WriterStateActive) { - if (m_setStartTime) - [self setStartTimeFrom:sampleBuffer]; - - if (m_audioWriterInput.data().readyForMoreMediaData) { - [self updateDuration:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)]; - [m_audioWriterInput appendSampleBuffer:sampleBuffer]; - } - } - - CFRelease(sampleBuffer); -} - -- (void)captureOutput:(AVCaptureOutput *)captureOutput - didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer - fromConnection:(AVCaptureConnection *)connection -{ - Q_UNUSED(connection); - - if (m_state.loadAcquire() != WriterStateActive) - return; - - if (!CMSampleBufferDataIsReady(sampleBuffer)) { - qDebugCamera() << Q_FUNC_INFO << "sample buffer is not ready, skipping."; - return; - } - - CFRetain(sampleBuffer); - - if (captureOutput != m_audioOutput.data()) { - if (m_state.loadRelaxed() != WriterStateActive) { - CFRelease(sampleBuffer); - return; - } - // Find renderercontrol's delegate and invoke its method to - // show updated viewfinder's frame. - if (m_service && m_service->videoOutput()) { - NSObject<AVCaptureVideoDataOutputSampleBufferDelegate> *vfDelegate = - (NSObject<AVCaptureVideoDataOutputSampleBufferDelegate> *)m_service->videoOutput()->captureDelegate(); - if (vfDelegate) - [vfDelegate captureOutput:nil didOutputSampleBuffer:sampleBuffer fromConnection:nil]; - } - - dispatch_async(m_writerQueue, ^{ - [self writeVideoSampleBuffer:sampleBuffer]; - }); - } else { - dispatch_async(m_writerQueue, ^{ - [self writeAudioSampleBuffer:sampleBuffer]; - }); - } -} - -- (bool)addAudioCapture -{ - Q_ASSERT(m_service && m_service->session() && m_service->session()->captureSession()); - - if (!m_service->audioInputSelectorControl()) - return false; - - AVCaptureSession *captureSession = m_service->session()->captureSession(); - - m_audioCaptureDevice = m_service->audioInputSelectorControl()->createCaptureDevice(); - if (!m_audioCaptureDevice) { - qWarning() << Q_FUNC_INFO << "no audio input device available"; - return false; - } else { - NSError *error = nil; - m_audioInput.reset([[AVCaptureDeviceInput deviceInputWithDevice:m_audioCaptureDevice error:&error] retain]); - - if (!m_audioInput || error) { - qWarning() << Q_FUNC_INFO << "failed to create audio device input"; - m_audioCaptureDevice = 0; - m_audioInput.reset(); - return false; - } else if (![captureSession canAddInput:m_audioInput]) { - qWarning() << Q_FUNC_INFO << "could not connect the audio input"; - m_audioCaptureDevice = 0; - m_audioInput.reset(); - return false; - } else { - [captureSession addInput:m_audioInput]; - } - } - - - m_audioOutput.reset([[AVCaptureAudioDataOutput alloc] init]); - if (m_audioOutput.data() && [captureSession canAddOutput:m_audioOutput]) { - [captureSession addOutput:m_audioOutput]; - } else { - qDebugCamera() << Q_FUNC_INFO << "failed to add audio output"; - [captureSession removeInput:m_audioInput]; - m_audioCaptureDevice = 0; - m_audioInput.reset(); - m_audioOutput.reset(); - return false; - } - - return true; -} - -- (bool)addWriterInputs -{ - Q_ASSERT(m_service && m_service->videoOutput() - && m_service->videoOutput()->videoDataOutput()); - Q_ASSERT(m_assetWriter.data()); - - m_cameraWriterInput.reset([[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo - outputSettings:m_videoSettings - sourceFormatHint:m_service->session()->videoCaptureDevice().activeFormat.formatDescription]); - if (!m_cameraWriterInput) { - qDebugCamera() << Q_FUNC_INFO << "failed to create camera writer input"; - return false; - } - - if ([m_assetWriter canAddInput:m_cameraWriterInput]) { - [m_assetWriter addInput:m_cameraWriterInput]; - } else { - qDebugCamera() << Q_FUNC_INFO << "failed to add camera writer input"; - m_cameraWriterInput.reset(); - return false; - } - - m_cameraWriterInput.data().expectsMediaDataInRealTime = YES; - - if (m_audioOutput.data()) { - CMFormatDescriptionRef sourceFormat = m_audioCaptureDevice ? m_audioCaptureDevice.activeFormat.formatDescription : 0; - m_audioWriterInput.reset([[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeAudio - outputSettings:m_audioSettings - sourceFormatHint:sourceFormat]); - if (!m_audioWriterInput) { - qDebugCamera() << Q_FUNC_INFO << "failed to create audio writer input"; - // But we still can record video. - } else if ([m_assetWriter canAddInput:m_audioWriterInput]) { - [m_assetWriter addInput:m_audioWriterInput]; - m_audioWriterInput.data().expectsMediaDataInRealTime = YES; - } else { - qDebugCamera() << Q_FUNC_INFO << "failed to add audio writer input"; - m_audioWriterInput.reset(); - // We can (still) write video though ... - } - } - - return true; -} - -- (void)setQueues -{ - Q_ASSERT(m_service && m_service->videoOutput() && m_service->videoOutput()->videoDataOutput()); - Q_ASSERT(m_videoQueue); - - [m_service->videoOutput()->videoDataOutput() setSampleBufferDelegate:self queue:m_videoQueue]; - - if (m_audioOutput.data()) { - Q_ASSERT(m_audioQueue); - [m_audioOutput setSampleBufferDelegate:self queue:m_audioQueue]; - } -} - -- (void)updateDuration:(CMTime)newTimeStamp -{ - Q_ASSERT(CMTimeCompare(m_startTime, kCMTimeInvalid)); - Q_ASSERT(CMTimeCompare(m_lastTimeStamp, kCMTimeInvalid)); - if (CMTimeCompare(newTimeStamp, m_lastTimeStamp) > 0) { - - const CMTime duration = CMTimeSubtract(newTimeStamp, m_startTime); - if (!CMTimeCompare(duration, kCMTimeInvalid)) - return; - - m_durationInMs.storeRelease(CMTimeGetSeconds(duration) * 1000); - m_lastTimeStamp = newTimeStamp; - } -} - -- (qint64)durationInMs -{ - return m_durationInMs.loadAcquire(); -} - -@end diff --git a/src/plugins/avfoundation/camera/avfmediacontainercontrol.h b/src/plugins/avfoundation/camera/avfmediacontainercontrol.h deleted file mode 100644 index e43e70baf..000000000 --- a/src/plugins/avfoundation/camera/avfmediacontainercontrol.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFMEDIACONTAINERCONTROL_H -#define AVFMEDIACONTAINERCONTROL_H - -#include <qmediacontainercontrol.h> - -@class NSString; - -QT_BEGIN_NAMESPACE - -class AVFCameraService; - -class AVFMediaContainerControl : public QMediaContainerControl -{ -public: - explicit AVFMediaContainerControl(AVFCameraService *service); - - QStringList supportedContainers() const override; - QString containerFormat() const override; - void setContainerFormat(const QString &format) override; - QString containerDescription(const QString &formatMimeType) const override; - - NSString *fileType() const; - -private: - QString m_format; -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIACONTAINERCONTROL_H diff --git a/src/plugins/avfoundation/camera/avfmediacontainercontrol.mm b/src/plugins/avfoundation/camera/avfmediacontainercontrol.mm deleted file mode 100644 index 9a36bc632..000000000 --- a/src/plugins/avfoundation/camera/avfmediacontainercontrol.mm +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfmediacontainercontrol.h" - -#include <AVFoundation/AVMediaFormat.h> -#include <QtCore/qmap.h> - -QT_BEGIN_NAMESPACE - -struct ContainerInfo -{ - QString description; - NSString *fileType; - - ContainerInfo() : fileType(nil) { } - ContainerInfo(const QString &desc, NSString *type) - : description(desc), fileType(type) - { } -}; - -typedef QMap<QString, ContainerInfo> SupportedContainers; -Q_GLOBAL_STATIC(SupportedContainers, containers); - -AVFMediaContainerControl::AVFMediaContainerControl(AVFCameraService *) - : QMediaContainerControl() - , m_format(QStringLiteral("mov")) // .mov is the default container format on Apple platforms -{ - if (containers->isEmpty()) { - containers->insert(QStringLiteral("mov"), - ContainerInfo(QStringLiteral("QuickTime movie file format"), - AVFileTypeQuickTimeMovie)); - containers->insert(QStringLiteral("mp4"), - ContainerInfo(QStringLiteral("MPEG-4 file format"), - AVFileTypeMPEG4)); - containers->insert(QStringLiteral("m4v"), - ContainerInfo(QStringLiteral("iTunes video file format"), - AVFileTypeAppleM4V)); -#ifdef Q_OS_IOS - containers->insert(QStringLiteral("3gp"), - ContainerInfo(QStringLiteral("3GPP file format"), - AVFileType3GPP)); -#endif - } -} - -QStringList AVFMediaContainerControl::supportedContainers() const -{ - return containers->keys(); -} - -QString AVFMediaContainerControl::containerFormat() const -{ - return m_format; -} - -void AVFMediaContainerControl::setContainerFormat(const QString &format) -{ - if (!containers->contains(format)) { - qWarning("Unsupported container format: '%s'", format.toLocal8Bit().constData()); - return; - } - - m_format = format; -} - -QString AVFMediaContainerControl::containerDescription(const QString &formatMimeType) const -{ - return containers->value(formatMimeType).description; -} - -NSString *AVFMediaContainerControl::fileType() const -{ - return containers->value(m_format).fileType; -} - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfmediarecordercontrol.h b/src/plugins/avfoundation/camera/avfmediarecordercontrol.h deleted file mode 100644 index fbba5eca4..000000000 --- a/src/plugins/avfoundation/camera/avfmediarecordercontrol.h +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFMEDIARECORDERCONTROL_H -#define AVFMEDIARECORDERCONTROL_H - -#include <QtCore/qurl.h> -#include <QtMultimedia/qmediarecordercontrol.h> - -#import <AVFoundation/AVFoundation.h> -#include "avfstoragelocation.h" -#include "avfcamerautility.h" - -@class AVFMediaRecorderDelegate; - -QT_BEGIN_NAMESPACE - -class AVFCameraSession; -class AVFCameraControl; -class AVFAudioInputSelectorControl; -class AVFCameraService; - -class AVFMediaRecorderControl : public QMediaRecorderControl -{ -Q_OBJECT -public: - AVFMediaRecorderControl(AVFCameraService *service, QObject *parent = nullptr); - ~AVFMediaRecorderControl(); - - QUrl outputLocation() const override; - bool setOutputLocation(const QUrl &location) override; - - QMediaRecorder::State state() const override; - QMediaRecorder::Status status() const override; - - qint64 duration() const override; - - bool isMuted() const override; - qreal volume() const override; - - void applySettings() override; - void unapplySettings(); - -public Q_SLOTS: - void setState(QMediaRecorder::State state) override; - void setMuted(bool muted) override; - void setVolume(qreal volume) override; - - void handleRecordingStarted(); - void handleRecordingFinished(); - void handleRecordingFailed(const QString &message); - -private Q_SLOTS: - void setupSessionForCapture(); - void updateStatus(); - -private: - AVFCameraService *m_service; - AVFCameraControl *m_cameraControl; - AVFAudioInputSelectorControl *m_audioInputControl; - AVFCameraSession *m_session; - - bool m_connected; - QUrl m_outputLocation; - QMediaRecorder::State m_state; - QMediaRecorder::Status m_lastStatus; - - bool m_recordingStarted; - bool m_recordingFinished; - - bool m_muted; - qreal m_volume; - - AVCaptureDeviceInput *m_audioInput; - AVCaptureMovieFileOutput *m_movieOutput; - AVFMediaRecorderDelegate *m_recorderDelagate; - AVFStorageLocation m_storageLocation; - - AVFPSRange m_restoreFPS; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfmediarecordercontrol.mm b/src/plugins/avfoundation/camera/avfmediarecordercontrol.mm deleted file mode 100644 index 7296b7dc1..000000000 --- a/src/plugins/avfoundation/camera/avfmediarecordercontrol.mm +++ /dev/null @@ -1,430 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfcameradebug.h" -#include "avfmediarecordercontrol.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" -#include "avfcameracontrol.h" -#include "avfaudioinputselectorcontrol.h" -#include "avfaudioencodersettingscontrol.h" -#include "avfvideoencodersettingscontrol.h" -#include "avfmediacontainercontrol.h" - -#include <QtCore/qurl.h> -#include <QtCore/qfileinfo.h> -#include <QtMultimedia/qcameracontrol.h> - - -QT_USE_NAMESPACE - -@interface AVFMediaRecorderDelegate : NSObject <AVCaptureFileOutputRecordingDelegate> -{ -@private - AVFMediaRecorderControl *m_recorder; -} - -- (AVFMediaRecorderDelegate *) initWithRecorder:(AVFMediaRecorderControl*)recorder; - -- (void) captureOutput:(AVCaptureFileOutput *)captureOutput - didStartRecordingToOutputFileAtURL:(NSURL *)fileURL - fromConnections:(NSArray *)connections; - -- (void) captureOutput:(AVCaptureFileOutput *)captureOutput - didFinishRecordingToOutputFileAtURL:(NSURL *)fileURL - fromConnections:(NSArray *)connections - error:(NSError *)error; -@end - -@implementation AVFMediaRecorderDelegate - -- (AVFMediaRecorderDelegate *) initWithRecorder:(AVFMediaRecorderControl*)recorder -{ - if (!(self = [super init])) - return nil; - - self->m_recorder = recorder; - return self; -} - -- (void) captureOutput:(AVCaptureFileOutput *)captureOutput - didStartRecordingToOutputFileAtURL:(NSURL *)fileURL - fromConnections:(NSArray *)connections -{ - Q_UNUSED(captureOutput); - Q_UNUSED(fileURL); - Q_UNUSED(connections); - - QMetaObject::invokeMethod(m_recorder, "handleRecordingStarted", Qt::QueuedConnection); -} - -- (void) captureOutput:(AVCaptureFileOutput *)captureOutput - didFinishRecordingToOutputFileAtURL:(NSURL *)fileURL - fromConnections:(NSArray *)connections - error:(NSError *)error -{ - Q_UNUSED(captureOutput); - Q_UNUSED(fileURL); - Q_UNUSED(connections); - - if (error) { - QStringList messageParts; - messageParts << QString::fromUtf8([[error localizedDescription] UTF8String]); - messageParts << QString::fromUtf8([[error localizedFailureReason] UTF8String]); - messageParts << QString::fromUtf8([[error localizedRecoverySuggestion] UTF8String]); - - QString errorMessage = messageParts.join(" "); - - QMetaObject::invokeMethod(m_recorder, "handleRecordingFailed", Qt::QueuedConnection, - Q_ARG(QString, errorMessage)); - } else { - QMetaObject::invokeMethod(m_recorder, "handleRecordingFinished", Qt::QueuedConnection); - } -} - -@end - - -AVFMediaRecorderControl::AVFMediaRecorderControl(AVFCameraService *service, QObject *parent) - : QMediaRecorderControl(parent) - , m_service(service) - , m_cameraControl(service->cameraControl()) - , m_audioInputControl(service->audioInputSelectorControl()) - , m_session(service->session()) - , m_connected(false) - , m_state(QMediaRecorder::StoppedState) - , m_lastStatus(QMediaRecorder::UnloadedStatus) - , m_recordingStarted(false) - , m_recordingFinished(false) - , m_muted(false) - , m_volume(1.0) - , m_audioInput(nil) - , m_restoreFPS(-1, -1) -{ - m_movieOutput = [[AVCaptureMovieFileOutput alloc] init]; - m_recorderDelagate = [[AVFMediaRecorderDelegate alloc] initWithRecorder:this]; - - connect(m_cameraControl, SIGNAL(stateChanged(QCamera::State)), SLOT(updateStatus())); - connect(m_cameraControl, SIGNAL(statusChanged(QCamera::Status)), SLOT(updateStatus())); - connect(m_cameraControl, SIGNAL(captureModeChanged(QCamera::CaptureModes)), SLOT(setupSessionForCapture())); - connect(m_session, SIGNAL(readyToConfigureConnections()), SLOT(setupSessionForCapture())); - connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(setupSessionForCapture())); -} - -AVFMediaRecorderControl::~AVFMediaRecorderControl() -{ - if (m_movieOutput) { - [m_session->captureSession() removeOutput:m_movieOutput]; - [m_movieOutput release]; - } - - if (m_audioInput) { - [m_session->captureSession() removeInput:m_audioInput]; - [m_audioInput release]; - } - - [m_recorderDelagate release]; -} - -QUrl AVFMediaRecorderControl::outputLocation() const -{ - return m_outputLocation; -} - -bool AVFMediaRecorderControl::setOutputLocation(const QUrl &location) -{ - m_outputLocation = location; - return location.scheme() == QLatin1String("file") || location.scheme().isEmpty(); -} - -QMediaRecorder::State AVFMediaRecorderControl::state() const -{ - return m_state; -} - -QMediaRecorder::Status AVFMediaRecorderControl::status() const -{ - QMediaRecorder::Status status = m_lastStatus; - //bool videoEnabled = m_cameraControl->captureMode().testFlag(QCamera::CaptureVideo); - - if (m_cameraControl->status() == QCamera::ActiveStatus && m_connected) { - if (m_state == QMediaRecorder::StoppedState) { - if (m_recordingStarted && !m_recordingFinished) - status = QMediaRecorder::FinalizingStatus; - else - status = QMediaRecorder::LoadedStatus; - } else { - status = m_recordingStarted ? QMediaRecorder::RecordingStatus : - QMediaRecorder::StartingStatus; - } - } else { - //camera not started yet - status = m_cameraControl->state() == QCamera::ActiveState && m_connected ? - QMediaRecorder::LoadingStatus: - QMediaRecorder::UnloadedStatus; - } - - return status; -} - -void AVFMediaRecorderControl::updateStatus() -{ - QMediaRecorder::Status newStatus = status(); - - if (m_lastStatus != newStatus) { - qDebugCamera() << "Camera recorder status changed: " << m_lastStatus << " -> " << newStatus; - m_lastStatus = newStatus; - Q_EMIT statusChanged(m_lastStatus); - } -} - - -qint64 AVFMediaRecorderControl::duration() const -{ - if (!m_movieOutput) - return 0; - - return qint64(CMTimeGetSeconds(m_movieOutput.recordedDuration) * 1000); -} - -bool AVFMediaRecorderControl::isMuted() const -{ - return m_muted; -} - -qreal AVFMediaRecorderControl::volume() const -{ - return m_volume; -} - -void AVFMediaRecorderControl::applySettings() -{ - if (m_state != QMediaRecorder::StoppedState - || (m_session->state() != QCamera::ActiveState && m_session->state() != QCamera::LoadedState) - || !m_service->cameraControl()->captureMode().testFlag(QCamera::CaptureVideo)) { - return; - } - - // Configure audio settings - [m_movieOutput setOutputSettings:m_service->audioEncoderSettingsControl()->applySettings() - forConnection:[m_movieOutput connectionWithMediaType:AVMediaTypeAudio]]; - - // Configure video settings - AVCaptureConnection *videoConnection = [m_movieOutput connectionWithMediaType:AVMediaTypeVideo]; - NSDictionary *videoSettings = m_service->videoEncoderSettingsControl()->applySettings(videoConnection); - - const AVFConfigurationLock lock(m_session->videoCaptureDevice()); // prevents activeFormat from being overridden - - [m_movieOutput setOutputSettings:videoSettings forConnection:videoConnection]; -} - -void AVFMediaRecorderControl::unapplySettings() -{ - m_service->audioEncoderSettingsControl()->unapplySettings(); - m_service->videoEncoderSettingsControl()->unapplySettings([m_movieOutput connectionWithMediaType:AVMediaTypeVideo]); -} - -void AVFMediaRecorderControl::setState(QMediaRecorder::State state) -{ - if (m_state == state) - return; - - qDebugCamera() << Q_FUNC_INFO << m_state << " -> " << state; - - switch (state) { - case QMediaRecorder::RecordingState: - { - if (m_connected) { - QString outputLocationPath = m_outputLocation.scheme() == QLatin1String("file") ? - m_outputLocation.path() : m_outputLocation.toString(); - - QString extension = m_service->mediaContainerControl()->containerFormat(); - - QUrl actualLocation = QUrl::fromLocalFile( - m_storageLocation.generateFileName(outputLocationPath, - QCamera::CaptureVideo, - QLatin1String("clip_"), - extension)); - - qDebugCamera() << "Video capture location:" << actualLocation.toString(); - - applySettings(); - - [m_movieOutput startRecordingToOutputFileURL:actualLocation.toNSURL() - recordingDelegate:m_recorderDelagate]; - - m_state = QMediaRecorder::RecordingState; - m_recordingStarted = false; - m_recordingFinished = false; - - Q_EMIT actualLocationChanged(actualLocation); - updateStatus(); - Q_EMIT stateChanged(m_state); - } else { - Q_EMIT error(QMediaRecorder::FormatError, tr("Recorder not configured")); - } - - } break; - case QMediaRecorder::PausedState: - { - Q_EMIT error(QMediaRecorder::FormatError, tr("Recording pause not supported")); - return; - } break; - case QMediaRecorder::StoppedState: - { - m_lastStatus = QMediaRecorder::FinalizingStatus; - Q_EMIT statusChanged(m_lastStatus); - [m_movieOutput stopRecording]; - unapplySettings(); - } - } -} - -void AVFMediaRecorderControl::setMuted(bool muted) -{ - if (m_muted != muted) { - m_muted = muted; - Q_EMIT mutedChanged(muted); - } -} - -void AVFMediaRecorderControl::setVolume(qreal volume) -{ - if (m_volume != volume) { - m_volume = volume; - Q_EMIT volumeChanged(volume); - } -} - -void AVFMediaRecorderControl::handleRecordingStarted() -{ - m_recordingStarted = true; - updateStatus(); -} - -void AVFMediaRecorderControl::handleRecordingFinished() -{ - m_recordingFinished = true; - if (m_state != QMediaRecorder::StoppedState) { - m_state = QMediaRecorder::StoppedState; - Q_EMIT stateChanged(m_state); - } - updateStatus(); -} - -void AVFMediaRecorderControl::handleRecordingFailed(const QString &message) -{ - m_recordingFinished = true; - if (m_state != QMediaRecorder::StoppedState) { - m_state = QMediaRecorder::StoppedState; - Q_EMIT stateChanged(m_state); - } - updateStatus(); - - Q_EMIT error(QMediaRecorder::ResourceError, message); -} - -void AVFMediaRecorderControl::setupSessionForCapture() -{ - if (!m_session->videoCaptureDevice()) - return; - - //adding movie output causes high CPU usage even when while recording is not active, - //connect it only while video capture mode is enabled. - // Similarly, connect the Audio input only in that mode, since it's only necessary - // when recording anyway. Adding an Audio input will trigger the microphone permission - // request on iOS, but it shoudn't do so until we actually try to record. - AVCaptureSession *captureSession = m_session->captureSession(); - - if (!m_connected - && m_cameraControl->captureMode().testFlag(QCamera::CaptureVideo) - && m_session->state() != QCamera::UnloadedState) { - - // Lock the video capture device to make sure the active format is not reset - const AVFConfigurationLock lock(m_session->videoCaptureDevice()); - - // Add audio input - // Allow recording even if something wrong happens with the audio input initialization - AVCaptureDevice *audioDevice = m_audioInputControl->createCaptureDevice(); - if (!audioDevice) { - qWarning("No audio input device available"); - } else { - NSError *error = nil; - m_audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error]; - - if (!m_audioInput) { - qWarning() << "Failed to create audio device input"; - } else if (![captureSession canAddInput:m_audioInput]) { - qWarning() << "Could not connect the audio input"; - m_audioInput = nullptr; - } else { - [m_audioInput retain]; - [captureSession addInput:m_audioInput]; - } - } - - if ([captureSession canAddOutput:m_movieOutput]) { - [captureSession addOutput:m_movieOutput]; - m_connected = true; - } else { - Q_EMIT error(QMediaRecorder::ResourceError, tr("Could not connect the video recorder")); - qWarning() << "Could not connect the video recorder"; - } - } else if (m_connected - && (!m_cameraControl->captureMode().testFlag(QCamera::CaptureVideo) - || m_session->state() == QCamera::UnloadedState)) { - - // Lock the video capture device to make sure the active format is not reset - const AVFConfigurationLock lock(m_session->videoCaptureDevice()); - - [captureSession removeOutput:m_movieOutput]; - - if (m_audioInput) { - [captureSession removeInput:m_audioInput]; - [m_audioInput release]; - m_audioInput = nil; - } - - m_connected = false; - } - - updateStatus(); -} - -#include "moc_avfmediarecordercontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.h b/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.h deleted file mode 100644 index 9afb1068d..000000000 --- a/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFMEDIARECORDERCONTROL_IOS_H -#define AVFMEDIARECORDERCONTROL_IOS_H - -#include "avfmediaassetwriter.h" -#include "avfstoragelocation.h" -#include "avfcamerautility.h" - -#include <QtMultimedia/qmediarecordercontrol.h> -#include <private/qvideooutputorientationhandler_p.h> - -#include <QtCore/qglobal.h> -#include <QtCore/qurl.h> - -#include <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraService; -class QString; -class QUrl; - -class AVFMediaRecorderControlIOS : public QMediaRecorderControl -{ - Q_OBJECT -public: - AVFMediaRecorderControlIOS(AVFCameraService *service, QObject *parent = nullptr); - ~AVFMediaRecorderControlIOS() override; - - QUrl outputLocation() const override; - bool setOutputLocation(const QUrl &location) override; - - QMediaRecorder::State state() const override; - QMediaRecorder::Status status() const override; - - qint64 duration() const override; - - bool isMuted() const override; - qreal volume() const override; - - void applySettings() override; - void unapplySettings(); - -public Q_SLOTS: - void setState(QMediaRecorder::State state) override; - void setMuted(bool muted) override; - void setVolume(qreal volume) override; - -private: - - Q_INVOKABLE void assetWriterStarted(); - Q_INVOKABLE void assetWriterFinished(); - -private Q_SLOTS: - void captureModeChanged(QCamera::CaptureModes); - void cameraStatusChanged(QCamera::Status newStatus); - -private: - void stopWriter(); - - AVFCameraService *m_service; - AVFScopedPointer<QT_MANGLE_NAMESPACE(AVFMediaAssetWriter)> m_writer; - - QUrl m_outputLocation; - AVFStorageLocation m_storageLocation; - - QMediaRecorder::State m_state; - QMediaRecorder::Status m_lastStatus; - - NSDictionary *m_audioSettings; - NSDictionary *m_videoSettings; - QVideoOutputOrientationHandler m_orientationHandler; -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIARECORDERCONTROL_IOS_H diff --git a/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.mm b/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.mm deleted file mode 100644 index 33064827d..000000000 --- a/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.mm +++ /dev/null @@ -1,414 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "avfmediarecordercontrol_ios.h" -#include "avfcamerarenderercontrol.h" -#include "avfcamerasession.h" -#include "avfcameracontrol.h" -#include "avfcameraservice.h" -#include "avfcameradebug.h" -#include "avfaudioencodersettingscontrol.h" -#include "avfvideoencodersettingscontrol.h" -#include "avfmediacontainercontrol.h" -#include "avfcamerautility.h" - -#include <QtCore/qmath.h> -#include <QtCore/qdebug.h> - -QT_USE_NAMESPACE - -namespace { - -bool qt_is_writable_file_URL(NSURL *fileURL) -{ - Q_ASSERT(fileURL); - - if (![fileURL isFileURL]) - return false; - - if (NSString *path = [[fileURL path] stringByExpandingTildeInPath]) { - return [[NSFileManager defaultManager] - isWritableFileAtPath:[path stringByDeletingLastPathComponent]]; - } - - return false; -} - -bool qt_file_exists(NSURL *fileURL) -{ - Q_ASSERT(fileURL); - - if (NSString *path = [[fileURL path] stringByExpandingTildeInPath]) - return [[NSFileManager defaultManager] fileExistsAtPath:path]; - - return false; -} - -} - -AVFMediaRecorderControlIOS::AVFMediaRecorderControlIOS(AVFCameraService *service, QObject *parent) - : QMediaRecorderControl(parent) - , m_service(service) - , m_state(QMediaRecorder::StoppedState) - , m_lastStatus(QMediaRecorder::UnloadedStatus) - , m_audioSettings(nil) - , m_videoSettings(nil) -{ - Q_ASSERT(service); - - m_writer.reset([[QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) alloc] initWithDelegate:this]); - if (!m_writer) { - qDebugCamera() << Q_FUNC_INFO << "failed to create an asset writer"; - return; - } - - AVFCameraControl *cameraControl = m_service->cameraControl(); - if (!cameraControl) { - qDebugCamera() << Q_FUNC_INFO << "camera control is nil"; - return; - } - - connect(cameraControl, SIGNAL(captureModeChanged(QCamera::CaptureModes)), - SLOT(captureModeChanged(QCamera::CaptureModes))); - connect(cameraControl, SIGNAL(statusChanged(QCamera::Status)), - SLOT(cameraStatusChanged(QCamera::Status))); -} - -AVFMediaRecorderControlIOS::~AVFMediaRecorderControlIOS() -{ - [m_writer abort]; - - if (m_audioSettings) - [m_audioSettings release]; - if (m_videoSettings) - [m_videoSettings release]; -} - -QUrl AVFMediaRecorderControlIOS::outputLocation() const -{ - return m_outputLocation; -} - -bool AVFMediaRecorderControlIOS::setOutputLocation(const QUrl &location) -{ - m_outputLocation = location; - return location.scheme() == QLatin1String("file") || location.scheme().isEmpty(); -} - -QMediaRecorder::State AVFMediaRecorderControlIOS::state() const -{ - return m_state; -} - -QMediaRecorder::Status AVFMediaRecorderControlIOS::status() const -{ - return m_lastStatus; -} - -qint64 AVFMediaRecorderControlIOS::duration() const -{ - return m_writer.data().durationInMs; -} - -bool AVFMediaRecorderControlIOS::isMuted() const -{ - return false; -} - -qreal AVFMediaRecorderControlIOS::volume() const -{ - return 1.; -} - -void AVFMediaRecorderControlIOS::applySettings() -{ - AVFCameraSession *session = m_service->session(); - if (!session) - return; - - if (m_state != QMediaRecorder::StoppedState - || (session->state() != QCamera::ActiveState && session->state() != QCamera::LoadedState) - || !m_service->cameraControl()->captureMode().testFlag(QCamera::CaptureVideo)) { - return; - } - - // audio settings - m_audioSettings = m_service->audioEncoderSettingsControl()->applySettings(); - if (m_audioSettings) - [m_audioSettings retain]; - - // video settings - AVCaptureConnection *conn = [m_service->videoOutput()->videoDataOutput() connectionWithMediaType:AVMediaTypeVideo]; - m_videoSettings = m_service->videoEncoderSettingsControl()->applySettings(conn); - if (m_videoSettings) - [m_videoSettings retain]; -} - -void AVFMediaRecorderControlIOS::unapplySettings() -{ - m_service->audioEncoderSettingsControl()->unapplySettings(); - - AVCaptureConnection *conn = [m_service->videoOutput()->videoDataOutput() connectionWithMediaType:AVMediaTypeVideo]; - m_service->videoEncoderSettingsControl()->unapplySettings(conn); - - if (m_audioSettings) { - [m_audioSettings release]; - m_audioSettings = nil; - } - if (m_videoSettings) { - [m_videoSettings release]; - m_videoSettings = nil; - } -} - -void AVFMediaRecorderControlIOS::setState(QMediaRecorder::State state) -{ - Q_ASSERT(m_service->session() - && m_service->session()->captureSession()); - - if (!m_writer) { - qDebugCamera() << Q_FUNC_INFO << "Invalid recorder"; - return; - } - - if (state == m_state) - return; - - switch (state) { - case QMediaRecorder::RecordingState: - { - AVFCameraControl *cameraControl = m_service->cameraControl(); - Q_ASSERT(cameraControl); - - if (!(cameraControl->captureMode() & QCamera::CaptureVideo)) { - qDebugCamera() << Q_FUNC_INFO << "wrong capture mode, CaptureVideo expected"; - Q_EMIT error(QMediaRecorder::ResourceError, tr("Failed to start recording")); - return; - } - - if (cameraControl->status() != QCamera::ActiveStatus) { - qDebugCamera() << Q_FUNC_INFO << "can not start record while camera is not active"; - Q_EMIT error(QMediaRecorder::ResourceError, tr("Failed to start recording")); - return; - } - - const QString path(m_outputLocation.scheme() == QLatin1String("file") ? - m_outputLocation.path() : m_outputLocation.toString()); - const QUrl fileURL(QUrl::fromLocalFile(m_storageLocation.generateFileName(path, QCamera::CaptureVideo, - QLatin1String("clip_"), - m_service->mediaContainerControl()->containerFormat()))); - - NSURL *nsFileURL = fileURL.toNSURL(); - if (!nsFileURL) { - qWarning() << Q_FUNC_INFO << "invalid output URL:" << fileURL; - Q_EMIT error(QMediaRecorder::ResourceError, tr("Invalid output file URL")); - return; - } - if (!qt_is_writable_file_URL(nsFileURL)) { - qWarning() << Q_FUNC_INFO << "invalid output URL:" << fileURL - << "(the location is not writable)"; - Q_EMIT error(QMediaRecorder::ResourceError, tr("Non-writeable file location")); - return; - } - if (qt_file_exists(nsFileURL)) { - // We test for/handle this error here since AWAssetWriter will raise an - // Objective-C exception, which is not good at all. - qWarning() << Q_FUNC_INFO << "invalid output URL:" << fileURL - << "(file already exists)"; - Q_EMIT error(QMediaRecorder::ResourceError, tr("File already exists")); - return; - } - - AVCaptureSession *session = m_service->session()->captureSession(); - // We stop session now so that no more frames for renderer's queue - // generated, will restart in assetWriterStarted. - [session stopRunning]; - - applySettings(); - - // Make sure the video is recorded in device orientation. - // The top of the video will match the side of the device which is on top - // when recording starts (regardless of the UI orientation). - AVFCameraInfo cameraInfo = m_service->session()->activeCameraInfo(); - int screenOrientation = 360 - m_orientationHandler.currentOrientation(); - float rotation = 0; - if (cameraInfo.position == QCamera::FrontFace) - rotation = (screenOrientation + cameraInfo.orientation) % 360; - else - rotation = (screenOrientation + (360 - cameraInfo.orientation)) % 360; - - if ([m_writer setupWithFileURL:nsFileURL - cameraService:m_service - audioSettings:m_audioSettings - videoSettings:m_videoSettings - transform:CGAffineTransformMakeRotation(qDegreesToRadians(rotation))]) { - - m_state = QMediaRecorder::RecordingState; - m_lastStatus = QMediaRecorder::StartingStatus; - - Q_EMIT actualLocationChanged(fileURL); - Q_EMIT stateChanged(m_state); - Q_EMIT statusChanged(m_lastStatus); - - // Apple recommends to call startRunning and do all - // setup on a special queue, and that's what we had - // initially (dispatch_async to writerQueue). Unfortunately, - // writer's queue is not the only queue/thread that can - // access/modify the session, and as a result we have - // all possible data/race-conditions with Obj-C exceptions - // at best and something worse in general. - // Now we try to only modify session on the same thread. - [m_writer start]; - } else { - [session startRunning]; - Q_EMIT error(QMediaRecorder::FormatError, tr("Failed to start recording")); - } - } break; - case QMediaRecorder::PausedState: - { - Q_EMIT error(QMediaRecorder::FormatError, tr("Recording pause not supported")); - return; - } break; - case QMediaRecorder::StoppedState: - { - // Do not check the camera status, we can stop if we started. - stopWriter(); - } - } -} - -void AVFMediaRecorderControlIOS::setMuted(bool muted) -{ - Q_UNUSED(muted); - qDebugCamera() << Q_FUNC_INFO << "not implemented"; -} - -void AVFMediaRecorderControlIOS::setVolume(qreal volume) -{ - Q_UNUSED(volume); - qDebugCamera() << Q_FUNC_INFO << "not implemented"; -} - -void AVFMediaRecorderControlIOS::assetWriterStarted() -{ - m_lastStatus = QMediaRecorder::RecordingStatus; - Q_EMIT statusChanged(QMediaRecorder::RecordingStatus); -} - -void AVFMediaRecorderControlIOS::assetWriterFinished() -{ - AVFCameraControl *cameraControl = m_service->cameraControl(); - Q_ASSERT(cameraControl); - - const QMediaRecorder::Status lastStatus = m_lastStatus; - const QMediaRecorder::State lastState = m_state; - if (cameraControl->captureMode() & QCamera::CaptureVideo) - m_lastStatus = QMediaRecorder::LoadedStatus; - else - m_lastStatus = QMediaRecorder::UnloadedStatus; - - unapplySettings(); - - m_service->videoOutput()->resetCaptureDelegate(); - [m_service->session()->captureSession() startRunning]; - m_state = QMediaRecorder::StoppedState; - if (m_lastStatus != lastStatus) - Q_EMIT statusChanged(m_lastStatus); - if (m_state != lastState) - Q_EMIT stateChanged(m_state); -} - -void AVFMediaRecorderControlIOS::captureModeChanged(QCamera::CaptureModes newMode) -{ - AVFCameraControl *cameraControl = m_service->cameraControl(); - Q_ASSERT(cameraControl); - - const QMediaRecorder::Status lastStatus = m_lastStatus; - - if (newMode & QCamera::CaptureVideo) { - if (cameraControl->status() == QCamera::ActiveStatus) - m_lastStatus = QMediaRecorder::LoadedStatus; - } else { - if (m_lastStatus == QMediaRecorder::RecordingStatus) - return stopWriter(); - else - m_lastStatus = QMediaRecorder::UnloadedStatus; - } - - if (m_lastStatus != lastStatus) - Q_EMIT statusChanged(m_lastStatus); -} - -void AVFMediaRecorderControlIOS::cameraStatusChanged(QCamera::Status newStatus) -{ - AVFCameraControl *cameraControl = m_service->cameraControl(); - Q_ASSERT(cameraControl); - - const QMediaRecorder::Status lastStatus = m_lastStatus; - const bool isCapture = cameraControl->captureMode() & QCamera::CaptureVideo; - if (newStatus == QCamera::StartingStatus) { - if (isCapture && m_lastStatus == QMediaRecorder::UnloadedStatus) - m_lastStatus = QMediaRecorder::LoadingStatus; - } else if (newStatus == QCamera::ActiveStatus) { - if (isCapture && m_lastStatus == QMediaRecorder::LoadingStatus) - m_lastStatus = QMediaRecorder::LoadedStatus; - } else { - if (m_lastStatus == QMediaRecorder::RecordingStatus) - return stopWriter(); - if (newStatus == QCamera::UnloadedStatus) - m_lastStatus = QMediaRecorder::UnloadedStatus; - } - - if (lastStatus != m_lastStatus) - Q_EMIT statusChanged(m_lastStatus); -} - -void AVFMediaRecorderControlIOS::stopWriter() -{ - if (m_lastStatus == QMediaRecorder::RecordingStatus) { - m_lastStatus = QMediaRecorder::FinalizingStatus; - - Q_EMIT statusChanged(m_lastStatus); - - [m_writer stop]; - } -} - -#include "moc_avfmediarecordercontrol_ios.cpp" diff --git a/src/plugins/avfoundation/camera/avfmediavideoprobecontrol.h b/src/plugins/avfoundation/camera/avfmediavideoprobecontrol.h deleted file mode 100644 index 69a452a97..000000000 --- a/src/plugins/avfoundation/camera/avfmediavideoprobecontrol.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFMEDIAVIDEOPROBECONTROL_H -#define AVFMEDIAVIDEOPROBECONTROL_H - -#include <qmediavideoprobecontrol.h> - -QT_BEGIN_NAMESPACE - -class AVFMediaVideoProbeControl : public QMediaVideoProbeControl -{ - Q_OBJECT -public: - explicit AVFMediaVideoProbeControl(QObject *parent = nullptr); - ~AVFMediaVideoProbeControl(); - - void newFrameProbed(const QVideoFrame& frame); - -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIAVIDEOPROBECONTROL_H diff --git a/src/plugins/avfoundation/camera/avfmediavideoprobecontrol.mm b/src/plugins/avfoundation/camera/avfmediavideoprobecontrol.mm deleted file mode 100644 index 7621661c3..000000000 --- a/src/plugins/avfoundation/camera/avfmediavideoprobecontrol.mm +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Copyright (C) 2016 Integrated Computer Solutions, Inc -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfmediavideoprobecontrol.h" -#include <qvideoframe.h> - -QT_BEGIN_NAMESPACE - -AVFMediaVideoProbeControl::AVFMediaVideoProbeControl(QObject *parent) : - QMediaVideoProbeControl(parent) -{ -} - -AVFMediaVideoProbeControl::~AVFMediaVideoProbeControl() -{ - -} - -void AVFMediaVideoProbeControl::newFrameProbed(const QVideoFrame &frame) -{ - Q_EMIT videoFrameProbed(frame); -} - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfstoragelocation.h b/src/plugins/avfoundation/camera/avfstoragelocation.h deleted file mode 100644 index 76621983d..000000000 --- a/src/plugins/avfoundation/camera/avfstoragelocation.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFSTORAGE_H -#define AVFSTORAGE_H - -#include "qtmultimediaglobal.h" - -#include <QtCore/qdir.h> -#include <QtMultimedia/qcamera.h> - -QT_BEGIN_NAMESPACE - -class AVFStorageLocation -{ -public: - AVFStorageLocation(); - ~AVFStorageLocation(); - - QString generateFileName(const QString &requestedName, - QCamera::CaptureMode mode, - const QString &prefix, - const QString &ext) const; - - - QDir defaultDir(QCamera::CaptureMode mode) const; - QString generateFileName(const QString &prefix, const QDir &dir, const QString &ext) const; - -private: - mutable QMap<QString, int> m_lastUsedIndex; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfstoragelocation.mm b/src/plugins/avfoundation/camera/avfstoragelocation.mm deleted file mode 100644 index 6a1cdca17..000000000 --- a/src/plugins/avfoundation/camera/avfstoragelocation.mm +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfstoragelocation.h" -#include "QtCore/qstandardpaths.h" - - -QT_BEGIN_NAMESPACE - - -AVFStorageLocation::AVFStorageLocation() -{ -} - -AVFStorageLocation::~AVFStorageLocation() -{ -} - -/*! - * Generate the actual file name from user requested one. - * requestedName may be either empty (the default dir and naming theme is used), - * points to existing dir (the default name used) - * or specify the full actual path. - */ -QString AVFStorageLocation::generateFileName(const QString &requestedName, - QCamera::CaptureMode mode, - const QString &prefix, - const QString &ext) const -{ - if (requestedName.isEmpty()) - return generateFileName(prefix, defaultDir(mode), ext); - - if (QFileInfo(requestedName).isDir()) - return generateFileName(prefix, QDir(requestedName), ext); - - return requestedName; -} - -QDir AVFStorageLocation::defaultDir(QCamera::CaptureMode mode) const -{ - QStringList dirCandidates; - - if (mode == QCamera::CaptureVideo) { - dirCandidates << QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); - } else { - dirCandidates << QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); - } - - dirCandidates << QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); - dirCandidates << QDir::homePath(); - dirCandidates << QDir::currentPath(); - dirCandidates << QDir::tempPath(); - - for (const QString &path : qAsConst(dirCandidates)) { - if (QFileInfo(path).isWritable()) - return QDir(path); - } - - return QDir(); -} - -QString AVFStorageLocation::generateFileName(const QString &prefix, const QDir &dir, const QString &ext) const -{ - QString lastClipKey = dir.absolutePath()+QLatin1Char(' ')+prefix+QLatin1Char(' ')+ext; - int lastClip = m_lastUsedIndex.value(lastClipKey, 0); - - if (lastClip == 0) { - //first run, find the maximum clip number during the fist capture - const auto list = dir.entryList(QStringList() << QString("%1*.%2").arg(prefix).arg(ext)); - for (const QString &fileName : list) { - int imgNumber = QStringView{fileName}.mid(prefix.length(), fileName.size()-prefix.length()-ext.length()-1).toInt(); - lastClip = qMax(lastClip, imgNumber); - } - } - - - //don't just rely on cached lastClip value, - //someone else may create a file after camera started - while (true) { - QString name = QString("%1%2.%3").arg(prefix) - .arg(lastClip+1, - 4, //fieldWidth - 10, - QLatin1Char('0')) - .arg(ext); - - QString path = dir.absoluteFilePath(name); - if (!QFileInfo(path).exists()) { - m_lastUsedIndex[lastClipKey] = lastClip+1; - return path; - } - - lastClip++; - } - - return QString(); -} - - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.h b/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.h deleted file mode 100644 index 7c9574f3d..000000000 --- a/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFVIDEOENCODERSETTINGSCONTROL_H -#define AVFVIDEOENCODERSETTINGSCONTROL_H - -#include <qvideoencodersettingscontrol.h> - -#include "avfcamerautility.h" -#import <AVFoundation/AVFoundation.h> - -@class NSDictionary; - -QT_BEGIN_NAMESPACE - -class AVFCameraService; - -class AVFVideoEncoderSettingsControl : public QVideoEncoderSettingsControl -{ - Q_OBJECT - -public: - explicit AVFVideoEncoderSettingsControl(AVFCameraService *service); - - QList<QSize> supportedResolutions(const QVideoEncoderSettings &requestedVideoSettings, - bool *continuous = nullptr) const override; - - QList<qreal> supportedFrameRates(const QVideoEncoderSettings &requestedVideoSettings, - bool *continuous = nullptr) const override; - - QStringList supportedVideoCodecs() const override; - QString videoCodecDescription(const QString &codecName) const override; - - QVideoEncoderSettings videoSettings() const override; - void setVideoSettings(const QVideoEncoderSettings &requestedVideoSettings) override; - - NSDictionary *applySettings(AVCaptureConnection *connection); - void unapplySettings(AVCaptureConnection *connection); - -private: - AVFCameraService *m_service; - - QVideoEncoderSettings m_requestedSettings; - QVideoEncoderSettings m_actualSettings; - - AVCaptureDeviceFormat *m_restoreFormat; - AVFPSRange m_restoreFps; -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEOENCODERSETTINGSCONTROL_H diff --git a/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.mm b/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.mm deleted file mode 100644 index 70ec38988..000000000 --- a/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.mm +++ /dev/null @@ -1,385 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfvideoencodersettingscontrol.h" - -#include "avfcameraservice.h" -#include "avfcamerautility.h" -#include "avfcamerasession.h" -#include "avfcamerarenderercontrol.h" - -#include <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -Q_GLOBAL_STATIC_WITH_ARGS(QStringList, supportedCodecs, (QStringList() << QLatin1String("avc1") - << QLatin1String("jpeg") - #ifdef Q_OS_OSX - << QLatin1String("ap4h") - << QLatin1String("apcn") - #endif - )) - -static bool format_supports_framerate(AVCaptureDeviceFormat *format, qreal fps) -{ - if (format && fps > qreal(0)) { - const qreal epsilon = 0.1; - for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) { - if (range.maxFrameRate - range.minFrameRate < epsilon) { - if (qAbs(fps - range.maxFrameRate) < epsilon) - return true; - } - - if (fps >= range.minFrameRate && fps <= range.maxFrameRate) - return true; - } - } - - return false; -} - -static bool real_list_contains(const QList<qreal> &list, qreal value) -{ - for (qreal r : list) { - if (qFuzzyCompare(r, value)) - return true; - } - return false; -} - -AVFVideoEncoderSettingsControl::AVFVideoEncoderSettingsControl(AVFCameraService *service) - : QVideoEncoderSettingsControl() - , m_service(service) - , m_restoreFormat(nil) -{ -} - -QList<QSize> AVFVideoEncoderSettingsControl::supportedResolutions(const QVideoEncoderSettings &settings, - bool *continuous) const -{ - Q_UNUSED(settings); - - if (continuous) - *continuous = true; - - // AVFoundation seems to support any resolution for recording, with the following limitations: - // - The recording resolution can't be higher than the camera's active resolution - // - On OS X, the recording resolution is automatically adjusted to have the same aspect ratio as - // the camera's active resolution - QList<QSize> resolutions; - resolutions.append(QSize(32, 32)); - - AVCaptureDevice *device = m_service->session()->videoCaptureDevice(); - if (device) { - int maximumWidth = 0; - const QVector<AVCaptureDeviceFormat *> formats(qt_unique_device_formats(device, - m_service->session()->defaultCodec())); - for (int i = 0; i < formats.size(); ++i) { - const QSize res(qt_device_format_resolution(formats[i])); - if (res.width() > maximumWidth) - maximumWidth = res.width(); - } - - if (maximumWidth > 0) - resolutions.append(QSize(maximumWidth, maximumWidth)); - } - - if (resolutions.count() == 1) - resolutions.append(QSize(3840, 3840)); - - return resolutions; -} - -QList<qreal> AVFVideoEncoderSettingsControl::supportedFrameRates(const QVideoEncoderSettings &settings, - bool *continuous) const -{ - QList<qreal> uniqueFrameRates; - - AVCaptureDevice *device = m_service->session()->videoCaptureDevice(); - if (!device) - return uniqueFrameRates; - - if (continuous) - *continuous = false; - - QVector<AVFPSRange> allRates; - - if (!settings.resolution().isValid()) { - const QVector<AVCaptureDeviceFormat *> formats(qt_unique_device_formats(device, 0)); - for (int i = 0; i < formats.size(); ++i) { - AVCaptureDeviceFormat *format = formats.at(i); - allRates += qt_device_format_framerates(format); - } - } else { - AVCaptureDeviceFormat *format = qt_find_best_resolution_match(device, - settings.resolution(), - m_service->session()->defaultCodec()); - if (format) - allRates = qt_device_format_framerates(format); - } - - for (int j = 0; j < allRates.size(); ++j) { - if (!real_list_contains(uniqueFrameRates, allRates[j].first)) - uniqueFrameRates.append(allRates[j].first); - if (!real_list_contains(uniqueFrameRates, allRates[j].second)) - uniqueFrameRates.append(allRates[j].second); - } - - return uniqueFrameRates; -} - -QStringList AVFVideoEncoderSettingsControl::supportedVideoCodecs() const -{ - return *supportedCodecs; -} - -QString AVFVideoEncoderSettingsControl::videoCodecDescription(const QString &codecName) const -{ - if (codecName == QLatin1String("avc1")) - return QStringLiteral("H.264"); - else if (codecName == QLatin1String("jpeg")) - return QStringLiteral("M-JPEG"); -#ifdef Q_OS_OSX - else if (codecName == QLatin1String("ap4h")) - return QStringLiteral("Apple ProRes 4444"); - else if (codecName == QLatin1String("apcn")) - return QStringLiteral("Apple ProRes 422 Standard Definition"); -#endif - - return QString(); -} - -QVideoEncoderSettings AVFVideoEncoderSettingsControl::videoSettings() const -{ - return m_actualSettings; -} - -void AVFVideoEncoderSettingsControl::setVideoSettings(const QVideoEncoderSettings &settings) -{ - if (m_requestedSettings == settings) - return; - - m_requestedSettings = m_actualSettings = settings; -} - -NSDictionary *AVFVideoEncoderSettingsControl::applySettings(AVCaptureConnection *connection) -{ - if (m_service->session()->state() != QCamera::LoadedState && - m_service->session()->state() != QCamera::ActiveState) { - return nil; - } - - AVCaptureDevice *device = m_service->session()->videoCaptureDevice(); - if (!device) - return nil; - - AVFPSRange currentFps = qt_current_framerates(device, connection); - const bool needFpsChange = m_requestedSettings.frameRate() > 0 - && m_requestedSettings.frameRate() != currentFps.second; - - NSMutableDictionary *videoSettings = [NSMutableDictionary dictionary]; - - // -- Codec - - // AVVideoCodecKey is the only mandatory key - QString codec = m_requestedSettings.codec().isEmpty() ? supportedCodecs->first() : m_requestedSettings.codec(); - if (!supportedCodecs->contains(codec)) { - qWarning("Unsupported codec: '%s'", codec.toLocal8Bit().constData()); - codec = supportedCodecs->first(); - } - [videoSettings setObject:codec.toNSString() forKey:AVVideoCodecKey]; - m_actualSettings.setCodec(codec); - - // -- Resolution - - int w = m_requestedSettings.resolution().width(); - int h = m_requestedSettings.resolution().height(); - - if (AVCaptureDeviceFormat *currentFormat = device.activeFormat) { - CMFormatDescriptionRef formatDesc = currentFormat.formatDescription; - CMVideoDimensions dim = CMVideoFormatDescriptionGetDimensions(formatDesc); - - // We have to change the device's activeFormat in 3 cases: - // - the requested recording resolution is higher than the current device resolution - // - the requested recording resolution has a different aspect ratio than the current device aspect ratio - // - the requested frame rate is not available for the current device format - AVCaptureDeviceFormat *newFormat = nil; - if ((w <= 0 || h <= 0) - && m_requestedSettings.frameRate() > 0 - && !format_supports_framerate(currentFormat, m_requestedSettings.frameRate())) { - - newFormat = qt_find_best_framerate_match(device, - m_service->session()->defaultCodec(), - m_requestedSettings.frameRate()); - - } else if (w > 0 && h > 0) { - AVCaptureDeviceFormat *f = qt_find_best_resolution_match(device, - m_requestedSettings.resolution(), - m_service->session()->defaultCodec()); - - if (f) { - CMVideoDimensions d = CMVideoFormatDescriptionGetDimensions(f.formatDescription); - qreal fAspectRatio = qreal(d.width) / d.height; - - if (w > dim.width || h > dim.height - || qAbs((qreal(dim.width) / dim.height) - fAspectRatio) > 0.01) { - newFormat = f; - } - } - } - - if (qt_set_active_format(device, newFormat, !needFpsChange)) { - m_restoreFormat = [currentFormat retain]; - formatDesc = newFormat.formatDescription; - dim = CMVideoFormatDescriptionGetDimensions(formatDesc); - } - - if (w > 0 && h > 0) { - // Make sure the recording resolution has the same aspect ratio as the device's - // current resolution - qreal deviceAspectRatio = qreal(dim.width) / dim.height; - qreal recAspectRatio = qreal(w) / h; - if (qAbs(deviceAspectRatio - recAspectRatio) > 0.01) { - if (recAspectRatio > deviceAspectRatio) - w = qRound(h * deviceAspectRatio); - else - h = qRound(w / deviceAspectRatio); - } - - // recording resolution can't be higher than the device's active resolution - w = qMin(w, dim.width); - h = qMin(h, dim.height); - } - } - - if (w > 0 && h > 0) { - // Width and height must be divisible by 2 - w += w & 1; - h += h & 1; - - [videoSettings setObject:[NSNumber numberWithInt:w] forKey:AVVideoWidthKey]; - [videoSettings setObject:[NSNumber numberWithInt:h] forKey:AVVideoHeightKey]; - m_actualSettings.setResolution(w, h); - } else { - m_actualSettings.setResolution(qt_device_format_resolution(device.activeFormat)); - } - - // -- FPS - - if (needFpsChange) { - m_restoreFps = currentFps; - const qreal fps = m_requestedSettings.frameRate(); - qt_set_framerate_limits(device, connection, fps, fps); - } - m_actualSettings.setFrameRate(qt_current_framerates(device, connection).second); - - // -- Codec Settings - - NSMutableDictionary *codecProperties = [NSMutableDictionary dictionary]; - int bitrate = -1; - float quality = -1.f; - - if (m_requestedSettings.encodingMode() == QMultimedia::ConstantQualityEncoding) { - if (m_requestedSettings.quality() != QMultimedia::NormalQuality) { - if (codec != QLatin1String("jpeg")) { - qWarning("ConstantQualityEncoding is not supported for codec: '%s'", codec.toLocal8Bit().constData()); - } else { - switch (m_requestedSettings.quality()) { - case QMultimedia::VeryLowQuality: - quality = 0.f; - break; - case QMultimedia::LowQuality: - quality = 0.25f; - break; - case QMultimedia::HighQuality: - quality = 0.75f; - break; - case QMultimedia::VeryHighQuality: - quality = 1.f; - break; - default: - quality = -1.f; // NormalQuality, let the system decide - break; - } - } - } - } else if (m_requestedSettings.encodingMode() == QMultimedia::AverageBitRateEncoding){ - if (codec != QLatin1String("avc1")) - qWarning("AverageBitRateEncoding is not supported for codec: '%s'", codec.toLocal8Bit().constData()); - else - bitrate = m_requestedSettings.bitRate(); - } else { - qWarning("Encoding mode is not supported"); - } - - if (bitrate != -1) - [codecProperties setObject:[NSNumber numberWithInt:bitrate] forKey:AVVideoAverageBitRateKey]; - if (quality != -1.f) - [codecProperties setObject:[NSNumber numberWithFloat:quality] forKey:AVVideoQualityKey]; - - [videoSettings setObject:codecProperties forKey:AVVideoCompressionPropertiesKey]; - - return videoSettings; -} - -void AVFVideoEncoderSettingsControl::unapplySettings(AVCaptureConnection *connection) -{ - m_actualSettings = m_requestedSettings; - - AVCaptureDevice *device = m_service->session()->videoCaptureDevice(); - if (!device) - return; - - const bool needFpsChanged = m_restoreFps.first || m_restoreFps.second; - - if (m_restoreFormat) { - qt_set_active_format(device, m_restoreFormat, !needFpsChanged); - [m_restoreFormat release]; - m_restoreFormat = nil; - } - - if (needFpsChanged) { - qt_set_framerate_limits(device, connection, m_restoreFps.first, m_restoreFps.second); - m_restoreFps = AVFPSRange(); - } -} - -QT_END_NAMESPACE - -#include "moc_avfvideoencodersettingscontrol.cpp" diff --git a/src/plugins/avfoundation/camera/camera.pro b/src/plugins/avfoundation/camera/camera.pro deleted file mode 100644 index 841e5a592..000000000 --- a/src/plugins/avfoundation/camera/camera.pro +++ /dev/null @@ -1,85 +0,0 @@ -TARGET = qavfcamera - -# Avoid clash with a variable named `slots' in a Quartz header -CONFIG += no_keywords - -QT += multimedia-private network - -LIBS += -framework CoreFoundation \ - -framework Foundation \ - -framework AudioToolbox \ - -framework CoreAudio \ - -framework QuartzCore \ - -framework CoreMedia -osx:LIBS += -framework AppKit \ - -framework AudioUnit -ios:LIBS += -framework CoreGraphics \ - -framework CoreVideo - -QMAKE_USE += avfoundation - -OTHER_FILES += avfcamera.json - -HEADERS += \ - avfcameradebug.h \ - avfcameraserviceplugin.h \ - avfcameracontrol.h \ - avfcamerametadatacontrol.h \ - avfimagecapturecontrol.h \ - avfcameraservice.h \ - avfcamerasession.h \ - avfstoragelocation.h \ - avfaudioinputselectorcontrol.h \ - avfmediavideoprobecontrol.h \ - avfcamerarenderercontrol.h \ - avfcameradevicecontrol.h \ - avfcamerafocuscontrol.h \ - avfcameraexposurecontrol.h \ - avfcamerautility.h \ - avfimageencodercontrol.h \ - avfvideoencodersettingscontrol.h \ - avfmediacontainercontrol.h \ - avfaudioencodersettingscontrol.h \ - avfcamerawindowcontrol.h \ - -OBJECTIVE_SOURCES += \ - avfcameraserviceplugin.mm \ - avfcameracontrol.mm \ - avfcamerametadatacontrol.mm \ - avfimagecapturecontrol.mm \ - avfcameraservice.mm \ - avfcamerasession.mm \ - avfstoragelocation.mm \ - avfaudioinputselectorcontrol.mm \ - avfmediavideoprobecontrol.mm \ - avfcameradevicecontrol.mm \ - avfcamerarenderercontrol.mm \ - avfcamerafocuscontrol.mm \ - avfcameraexposurecontrol.mm \ - avfcamerautility.mm \ - avfimageencodercontrol.mm \ - avfvideoencodersettingscontrol.mm \ - avfmediacontainercontrol.mm \ - avfaudioencodersettingscontrol.mm \ - avfcamerawindowcontrol.mm \ - -osx { - -HEADERS += avfmediarecordercontrol.h -OBJECTIVE_SOURCES += avfmediarecordercontrol.mm - -} - -ios { - -HEADERS += \ - avfmediaassetwriter.h \ - avfmediarecordercontrol_ios.h -OBJECTIVE_SOURCES += avfmediaassetwriter.mm \ - avfmediarecordercontrol_ios.mm - -} - -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = AVFServicePlugin -load(qt_plugin) diff --git a/src/plugins/avfoundation/mediaplayer/CMakeLists.txt b/src/plugins/avfoundation/mediaplayer/CMakeLists.txt deleted file mode 100644 index 4510fdbfc..000000000 --- a/src/plugins/avfoundation/mediaplayer/CMakeLists.txt +++ /dev/null @@ -1,67 +0,0 @@ -# Generated from mediaplayer.pro. - -##################################################################### -## AVFMediaPlayerServicePlugin Plugin: -##################################################################### - -qt_internal_add_plugin(AVFMediaPlayerServicePlugin - OUTPUT_NAME qavfmediaplayer - TYPE mediaservice - SOURCES - avfmediaplayercontrol.h avfmediaplayercontrol.mm - avfmediaplayermetadatacontrol.h avfmediaplayermetadatacontrol.mm - avfmediaplayerservice.h avfmediaplayerservice.mm - avfmediaplayerserviceplugin.h avfmediaplayerserviceplugin.mm - avfmediaplayersession.h avfmediaplayersession.mm - avfvideooutput.h avfvideooutput.mm - avfvideowindowcontrol.h avfvideowindowcontrol.mm - PUBLIC_LIBRARIES - ${FWCoreMedia} - ${FWCoreVideo} - ${FWMetal} - ${FWQuartzCore} - Qt::Core - Qt::Gui - Qt::MultimediaPrivate - Qt::Network - Qt::OpenGL - avfoundation -) - -#### Keys ignored in scope 1:.:.:mediaplayer.pro:<TRUE>: -# OTHER_FILES = "avfmediaplayer.json" - -## Scopes: -##################################################################### - -qt_internal_extend_target(AVFMediaPlayerServicePlugin CONDITION TARGET Qt::Widgets - SOURCES - avfvideowidget.h avfvideowidget.mm - avfvideowidgetcontrol.h avfvideowidgetcontrol.mm - PUBLIC_LIBRARIES - Qt::MultimediaWidgetsPrivate -) - -qt_internal_extend_target(AVFMediaPlayerServicePlugin CONDITION IOS OR TVOS - PUBLIC_LIBRARIES - ${FWFoundation} -) - -qt_internal_extend_target(AVFMediaPlayerServicePlugin CONDITION QT_FEATURE_opengl AND (IOS OR TVOS) - SOURCES - avfdisplaylink.h avfdisplaylink.mm - avfvideoframerenderer_ios.h avfvideoframerenderer_ios.mm - avfvideorenderercontrol.h avfvideorenderercontrol.mm -) - -qt_internal_extend_target(AVFMediaPlayerServicePlugin CONDITION NOT IOS AND NOT TVOS - PUBLIC_LIBRARIES - ${FWAppKit} -) - -qt_internal_extend_target(AVFMediaPlayerServicePlugin CONDITION QT_FEATURE_opengl AND NOT IOS AND NOT TVOS - SOURCES - avfdisplaylink.h avfdisplaylink.mm - avfvideoframerenderer.h avfvideoframerenderer.mm - avfvideorenderercontrol.h avfvideorenderercontrol.mm -) diff --git a/src/plugins/avfoundation/mediaplayer/avfdisplaylink.h b/src/plugins/avfoundation/mediaplayer/avfdisplaylink.h deleted file mode 100644 index ba0803807..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfdisplaylink.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFDISPLAYLINK_H -#define AVFDISPLAYLINK_H - -#include <QtCore/qobject.h> -#include <QtCore/qmutex.h> - -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) -#include <CoreVideo/CVBase.h> -#else -#include <QuartzCore/CVDisplayLink.h> -#endif - -QT_BEGIN_NAMESPACE - -class AVFDisplayLink : public QObject -{ - Q_OBJECT -public: - explicit AVFDisplayLink(QObject *parent = nullptr); - virtual ~AVFDisplayLink(); - bool isValid() const; - bool isActive() const; - -public Q_SLOTS: - void start(); - void stop(); - -Q_SIGNALS: - void tick(const CVTimeStamp &ts); - -public: - void displayLinkEvent(const CVTimeStamp *); - -protected: - virtual bool event(QEvent *) override; - -private: -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - void *m_displayLink; -#else - CVDisplayLinkRef m_displayLink; -#endif - QMutex m_displayLinkMutex; - bool m_pendingDisplayLinkEvent; - bool m_isActive; - CVTimeStamp m_frameTimeStamp; -}; - -QT_END_NAMESPACE - -#endif // AVFDISPLAYLINK_H diff --git a/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm b/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm deleted file mode 100644 index bae18bc0a..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm +++ /dev/null @@ -1,241 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfdisplaylink.h" -#include <QtCore/qcoreapplication.h> - -#ifdef QT_DEBUG_AVF -#include <QtCore/qdebug.h> -#endif - -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) -#import <QuartzCore/CADisplayLink.h> -#import <Foundation/NSRunLoop.h> -#define _m_displayLink static_cast<DisplayLinkObserver*>(m_displayLink) -#else -#endif - -QT_USE_NAMESPACE - -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) -@interface DisplayLinkObserver : NSObject - -- (void)start; -- (void)stop; -- (void)displayLinkNotification:(CADisplayLink *)sender; - -@end - -@implementation DisplayLinkObserver -{ - AVFDisplayLink *m_avfDisplayLink; - CADisplayLink *m_displayLink; -} - -- (id)initWithAVFDisplayLink:(AVFDisplayLink *)link -{ - self = [super init]; - - if (self) { - m_avfDisplayLink = link; - m_displayLink = [[CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkNotification:)] retain]; - } - - return self; -} - -- (void) dealloc -{ - if (m_displayLink) { - [m_displayLink release]; - m_displayLink = nullptr; - } - - [super dealloc]; -} - -- (void)start -{ - [m_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; -} - -- (void)stop -{ - [m_displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; -} - -- (void)displayLinkNotification:(CADisplayLink *)sender -{ - Q_UNUSED(sender); - m_avfDisplayLink->displayLinkEvent(nullptr); -} - -@end -#else -static CVReturn CVDisplayLinkCallback(CVDisplayLinkRef displayLink, - const CVTimeStamp *inNow, - const CVTimeStamp *inOutputTime, - CVOptionFlags flagsIn, - CVOptionFlags *flagsOut, - void *displayLinkContext) -{ - Q_UNUSED(displayLink); - Q_UNUSED(inNow); - Q_UNUSED(flagsIn); - Q_UNUSED(flagsOut); - - AVFDisplayLink *link = (AVFDisplayLink *)displayLinkContext; - - link->displayLinkEvent(inOutputTime); - return kCVReturnSuccess; -} -#endif - -AVFDisplayLink::AVFDisplayLink(QObject *parent) - : QObject(parent) - , m_displayLink(nullptr) - , m_pendingDisplayLinkEvent(false) - , m_isActive(false) -{ -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - m_displayLink = [[DisplayLinkObserver alloc] initWithAVFDisplayLink:this]; -#else - // create display link for the main display - CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &m_displayLink); - if (m_displayLink) { - // set the current display of a display link. - CVDisplayLinkSetCurrentCGDisplay(m_displayLink, kCGDirectMainDisplay); - - // set the renderer output callback function - CVDisplayLinkSetOutputCallback(m_displayLink, &CVDisplayLinkCallback, this); - } -#endif -} - -AVFDisplayLink::~AVFDisplayLink() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - - if (m_displayLink) { - stop(); -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - [_m_displayLink release]; -#else - CVDisplayLinkRelease(m_displayLink); -#endif - m_displayLink = nullptr; - } -} - -bool AVFDisplayLink::isValid() const -{ - return m_displayLink != nullptr; -} - -bool AVFDisplayLink::isActive() const -{ - return m_isActive; -} - -void AVFDisplayLink::start() -{ - if (m_displayLink && !m_isActive) { -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - [_m_displayLink start]; -#else - CVDisplayLinkStart(m_displayLink); -#endif - m_isActive = true; - } -} - -void AVFDisplayLink::stop() -{ - if (m_displayLink && m_isActive) { -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - [_m_displayLink stop]; -#else - CVDisplayLinkStop(m_displayLink); -#endif - m_isActive = false; - } -} - -void AVFDisplayLink::displayLinkEvent(const CVTimeStamp *ts) -{ - // This function is called from a - // thread != gui thread. So we post the event. - // But we need to make sure that we don't post faster - // than the event loop can eat: - m_displayLinkMutex.lock(); - bool pending = m_pendingDisplayLinkEvent; - m_pendingDisplayLinkEvent = true; -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - Q_UNUSED(ts); - memset(&m_frameTimeStamp, 0, sizeof(CVTimeStamp)); -#else - m_frameTimeStamp = *ts; -#endif - m_displayLinkMutex.unlock(); - - if (!pending) - qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority); -} - -bool AVFDisplayLink::event(QEvent *event) -{ - switch (event->type()){ - case QEvent::User: { - m_displayLinkMutex.lock(); - m_pendingDisplayLinkEvent = false; - CVTimeStamp ts = m_frameTimeStamp; - m_displayLinkMutex.unlock(); - - Q_EMIT tick(ts); - - return false; - } - break; - default: - break; - } - return QObject::event(event); -} diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayer.json b/src/plugins/avfoundation/mediaplayer/avfmediaplayer.json deleted file mode 100644 index 5626edec0..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayer.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["avfoundationmediaplayer"], - "Services": ["org.qt-project.qt.mediaplayer"] -} diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.h deleted file mode 100644 index d9dc4a1b7..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFMEDIAPLAYERCONTROL_H -#define AVFMEDIAPLAYERCONTROL_H - -#include <QtMultimedia/QMediaPlayerControl> -#include <QtCore/QObject> - -QT_BEGIN_NAMESPACE - -class AVFMediaPlayerSession; - -class AVFMediaPlayerControl : public QMediaPlayerControl -{ - Q_OBJECT -public: - explicit AVFMediaPlayerControl(QObject *parent = nullptr); - ~AVFMediaPlayerControl(); - - void setSession(AVFMediaPlayerSession *session); - - QMediaPlayer::State state() const override; - QMediaPlayer::MediaStatus mediaStatus() const override; - - QUrl media() const override; - const QIODevice *mediaStream() const override; - void setMedia(const QUrl &content, QIODevice *stream) override; - - qint64 position() const override; - qint64 duration() const override; - - int bufferStatus() const override; - - int volume() const override; - bool isMuted() const override; - - bool isAudioAvailable() const override; - bool isVideoAvailable() const override; - - bool isSeekable() const override; - QMediaTimeRange availablePlaybackRanges() const override; - - qreal playbackRate() const override; - void setPlaybackRate(qreal rate) override; - -public Q_SLOTS: - void setPosition(qint64 pos) override; - - void play() override; - void pause() override; - void stop() override; - - void setVolume(int volume) override; - void setMuted(bool muted) override; - -private: - AVFMediaPlayerSession *m_session; -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIAPLAYERCONTROL_H diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm deleted file mode 100644 index bf7ebb4a0..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm +++ /dev/null @@ -1,192 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfmediaplayercontrol.h" -#include "avfmediaplayersession.h" - -QT_USE_NAMESPACE - -AVFMediaPlayerControl::AVFMediaPlayerControl(QObject *parent) : - QMediaPlayerControl(parent) -{ -} - -AVFMediaPlayerControl::~AVFMediaPlayerControl() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif -} - -void AVFMediaPlayerControl::setSession(AVFMediaPlayerSession *session) -{ - m_session = session; - - connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(positionChanged(qint64))); - connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64))); - connect(m_session, SIGNAL(bufferStatusChanged(int)), this, SIGNAL(bufferStatusChanged(int))); - connect(m_session, SIGNAL(stateChanged(QMediaPlayer::State)), - this, SIGNAL(stateChanged(QMediaPlayer::State))); - connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), - this, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); - connect(m_session, SIGNAL(volumeChanged(int)), this, SIGNAL(volumeChanged(int))); - connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool))); - connect(m_session, SIGNAL(audioAvailableChanged(bool)), this, SIGNAL(audioAvailableChanged(bool))); - connect(m_session, SIGNAL(videoAvailableChanged(bool)), this, SIGNAL(videoAvailableChanged(bool))); - connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString))); - connect(m_session, &AVFMediaPlayerSession::playbackRateChanged, - this, &AVFMediaPlayerControl::playbackRateChanged); - connect(m_session, &AVFMediaPlayerSession::seekableChanged, - this, &AVFMediaPlayerControl::seekableChanged); -} - -QMediaPlayer::State AVFMediaPlayerControl::state() const -{ - return m_session->state(); -} - -QMediaPlayer::MediaStatus AVFMediaPlayerControl::mediaStatus() const -{ - return m_session->mediaStatus(); -} - -QMediaContent AVFMediaPlayerControl::media() const -{ - return m_session->media(); -} - -const QIODevice *AVFMediaPlayerControl::mediaStream() const -{ - return m_session->mediaStream(); -} - -void AVFMediaPlayerControl::setMedia(const QMediaContent &content, QIODevice *stream) -{ - const QMediaContent oldContent = m_session->media(); - - m_session->setMedia(content, stream); - - if (content != oldContent) - Q_EMIT mediaChanged(content); -} - -qint64 AVFMediaPlayerControl::position() const -{ - return m_session->position(); -} - -qint64 AVFMediaPlayerControl::duration() const -{ - return m_session->duration(); -} - -int AVFMediaPlayerControl::bufferStatus() const -{ - return m_session->bufferStatus(); -} - -int AVFMediaPlayerControl::volume() const -{ - return m_session->volume(); -} - -bool AVFMediaPlayerControl::isMuted() const -{ - return m_session->isMuted(); -} - -bool AVFMediaPlayerControl::isAudioAvailable() const -{ - return m_session->isAudioAvailable(); -} - -bool AVFMediaPlayerControl::isVideoAvailable() const -{ - return m_session->isVideoAvailable(); -} - -bool AVFMediaPlayerControl::isSeekable() const -{ - return m_session->isSeekable(); -} - -QMediaTimeRange AVFMediaPlayerControl::availablePlaybackRanges() const -{ - return m_session->availablePlaybackRanges(); -} - -qreal AVFMediaPlayerControl::playbackRate() const -{ - return m_session->playbackRate(); -} - -void AVFMediaPlayerControl::setPlaybackRate(qreal rate) -{ - m_session->setPlaybackRate(rate); -} - -void AVFMediaPlayerControl::setPosition(qint64 pos) -{ - m_session->setPosition(pos); -} - -void AVFMediaPlayerControl::play() -{ - m_session->play(); -} - -void AVFMediaPlayerControl::pause() -{ - m_session->pause(); -} - -void AVFMediaPlayerControl::stop() -{ - m_session->stop(); -} - -void AVFMediaPlayerControl::setVolume(int volume) -{ - m_session->setVolume(volume); -} - -void AVFMediaPlayerControl::setMuted(bool muted) -{ - m_session->setMuted(muted); -} diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h deleted file mode 100644 index f27573d60..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFMEDIAPLAYERMETADATACONTROL_H -#define AVFMEDIAPLAYERMETADATACONTROL_H - -#include <QtMultimedia/QMetaDataReaderControl> -#include <QtCore/qvariant.h> - -QT_BEGIN_NAMESPACE - -class AVFMediaPlayerSession; - -class AVFMediaPlayerMetaDataControl : public QMetaDataReaderControl -{ - Q_OBJECT -public: - explicit AVFMediaPlayerMetaDataControl(AVFMediaPlayerSession *session, QObject *parent = nullptr); - virtual ~AVFMediaPlayerMetaDataControl(); - - bool isMetaDataAvailable() const override; - bool isWritable() const; - - QVariant metaData(const QString &key) const override; - QStringList availableMetaData() const override; - -private Q_SLOTS: - void updateTags(); - -private: - AVFMediaPlayerSession *m_session; - QVariantMap m_tags; - void *m_asset; - -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIAPLAYERMETADATACONTROL_H diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm deleted file mode 100644 index b9ec38c0f..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfmediaplayermetadatacontrol.h" -#include "avfmediaplayersession.h" - -#include <QtMultimedia/qmediametadata.h> - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -AVFMediaPlayerMetaDataControl::AVFMediaPlayerMetaDataControl(AVFMediaPlayerSession *session, QObject *parent) - : QMetaDataReaderControl(parent) - , m_session(session) - , m_asset(nullptr) -{ - QObject::connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(updateTags())); -} - -AVFMediaPlayerMetaDataControl::~AVFMediaPlayerMetaDataControl() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif -} - -bool AVFMediaPlayerMetaDataControl::isMetaDataAvailable() const -{ - return !m_tags.isEmpty(); -} - -bool AVFMediaPlayerMetaDataControl::isWritable() const -{ - return false; -} - -QVariant AVFMediaPlayerMetaDataControl::metaData(const QString &key) const -{ - return m_tags.value(key); -} - -QStringList AVFMediaPlayerMetaDataControl::availableMetaData() const -{ - return m_tags.keys(); -} - -static QString itemKey(AVMetadataItem *item) -{ - NSString *keyString = [item commonKey]; - - if (keyString.length != 0) { - if ([keyString isEqualToString:AVMetadataCommonKeyTitle]) { - return QMediaMetaData::Title; - } else if ([keyString isEqualToString: AVMetadataCommonKeySubject]) { - return QMediaMetaData::SubTitle; - } else if ([keyString isEqualToString: AVMetadataCommonKeyDescription]) { - return QMediaMetaData::Description; - } else if ([keyString isEqualToString: AVMetadataCommonKeyPublisher]) { - return QMediaMetaData::Publisher; - } else if ([keyString isEqualToString: AVMetadataCommonKeyCreationDate]) { - return QMediaMetaData::Date; - } else if ([keyString isEqualToString: AVMetadataCommonKeyType]) { - return QMediaMetaData::MediaType; - } else if ([keyString isEqualToString: AVMetadataCommonKeyLanguage]) { - return QMediaMetaData::Language; - } else if ([keyString isEqualToString: AVMetadataCommonKeyCopyrights]) { - return QMediaMetaData::Copyright; - } else if ([keyString isEqualToString: AVMetadataCommonKeyAlbumName]) { - return QMediaMetaData::AlbumTitle; - } else if ([keyString isEqualToString: AVMetadataCommonKeyAuthor]) { - return QMediaMetaData::Author; - } else if ([keyString isEqualToString: AVMetadataCommonKeyArtist]) { - return QMediaMetaData::ContributingArtist; - } else if ([keyString isEqualToString: AVMetadataCommonKeyArtwork]) { - return QMediaMetaData::PosterUrl; - } - } - - return QString(); -} - -void AVFMediaPlayerMetaDataControl::updateTags() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - AVAsset *currentAsset = static_cast<AVAsset*>(m_session->currentAssetHandle()); - - //Don't read the tags from the same asset more than once - if (currentAsset == m_asset) - return; - - m_asset = currentAsset; - - QVariantMap oldTags = m_tags; - //Since we've changed assets, clear old tags - m_tags.clear(); - bool changed = false; - - // TODO: also process ID3, iTunes and QuickTime metadata - - NSArray *metadataItems = [currentAsset commonMetadata]; - for (AVMetadataItem* item in metadataItems) { - const QString key = itemKey(item); - if (!key.isEmpty()) { - const QString value = QString::fromNSString([item stringValue]); - if (!value.isNull()) { - m_tags.insert(key, value); - if (value != oldTags.value(key)) { - changed = true; - Q_EMIT metaDataChanged(key, value); - } - } - } - } - - if (oldTags.isEmpty() != m_tags.isEmpty()) { - Q_EMIT metaDataAvailableChanged(!m_tags.isEmpty()); - changed = true; - } - - if (changed) - Q_EMIT metaDataChanged(); -} diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.h deleted file mode 100644 index 50a15409f..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFMEDIAPLAYERSERVICE_H -#define AVFMEDIAPLAYERSERVICE_H - -#include <QtMultimedia/QMediaService> - -QT_BEGIN_NAMESPACE - -class AVFMediaPlayerSession; -class AVFMediaPlayerControl; -class AVFMediaPlayerMetaDataControl; -class AVFVideoOutput; - -class AVFMediaPlayerService : public QMediaService -{ -public: - explicit AVFMediaPlayerService(QObject *parent = nullptr); - ~AVFMediaPlayerService(); - - QObject *requestControl(const char *name) override; - void releaseControl(QObject *control) override; - -private: - AVFMediaPlayerSession *m_session; - AVFMediaPlayerControl *m_control; - QObject *m_videoOutput; - AVFMediaPlayerMetaDataControl *m_playerMetaDataControl; -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIAPLAYERSERVICE_H diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm deleted file mode 100644 index 6b050e7bf..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfmediaplayerservice.h" -#include "avfmediaplayersession.h" -#include "avfmediaplayercontrol.h" -#include "avfmediaplayermetadatacontrol.h" -#include "avfvideooutput.h" -#if QT_CONFIG(opengl) -#include "avfvideorenderercontrol.h" -#endif -#ifndef QT_NO_WIDGETS -# include "avfvideowidgetcontrol.h" -#endif -#include "avfvideowindowcontrol.h" - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -AVFMediaPlayerService::AVFMediaPlayerService(QObject *parent) - : QMediaService(parent) - , m_videoOutput(nullptr) -{ - m_session = new AVFMediaPlayerSession(this); - m_control = new AVFMediaPlayerControl(this); - m_control->setSession(m_session); - m_playerMetaDataControl = new AVFMediaPlayerMetaDataControl(m_session, this); - - connect(m_control, SIGNAL(mediaChanged(QMediaContent)), m_playerMetaDataControl, SLOT(updateTags())); -} - -AVFMediaPlayerService::~AVFMediaPlayerService() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - delete m_session; -} - -QObject *AVFMediaPlayerService::requestControl(const char *name) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << name; -#endif - - if (qstrcmp(name, QMediaPlayerControl_iid) == 0) - return m_control; - - if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) - return m_playerMetaDataControl; - -#if QT_CONFIG(opengl) - if (qstrcmp(name, QVideoRendererControl_iid) == 0) { - if (!m_videoOutput) - m_videoOutput = new AVFVideoRendererControl(this); - - m_session->setVideoOutput(qobject_cast<AVFVideoOutput*>(m_videoOutput)); - return m_videoOutput; - } -#endif -#ifndef QT_NO_WIDGETS - if (qstrcmp(name, QVideoWidgetControl_iid) == 0) { - if (!m_videoOutput) - m_videoOutput = new AVFVideoWidgetControl(this); - - m_session->setVideoOutput(qobject_cast<AVFVideoOutput*>(m_videoOutput)); - return m_videoOutput; - } -#endif - if (qstrcmp(name, QVideoWindowControl_iid) == 0) { - if (!m_videoOutput) - m_videoOutput = new AVFVideoWindowControl(this); - - m_session->setVideoOutput(qobject_cast<AVFVideoOutput*>(m_videoOutput)); - return m_videoOutput; - } - return nullptr; -} - -void AVFMediaPlayerService::releaseControl(QObject *control) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << control; -#endif - if (m_videoOutput == control) { -#if QT_CONFIG(opengl) - AVFVideoRendererControl *renderControl = qobject_cast<AVFVideoRendererControl*>(m_videoOutput); - - if (renderControl) - renderControl->setSurface(nullptr); -#endif - m_videoOutput = nullptr; - m_session->setVideoOutput(nullptr); - - delete control; - } -} diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.h deleted file mode 100644 index 07f30d3d6..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef AVFMEDIAPLAYERSERVICEPLUGIN_H -#define AVFMEDIAPLAYERSERVICEPLUGIN_H - -#include <QtCore/qglobal.h> -#include <QtMultimedia/qmediaserviceproviderplugin.h> - -QT_BEGIN_NAMESPACE - -class AVFMediaPlayerServicePlugin - : public QMediaServiceProviderPlugin - , public QMediaServiceSupportedFormatsInterface -{ - Q_OBJECT - Q_INTERFACES(QMediaServiceSupportedFormatsInterface) - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "avfmediaplayer.json") - -public: - explicit AVFMediaPlayerServicePlugin(); - - QMediaService* create(QString const& key) override; - void release(QMediaService *service) override; - - QMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const override; - QStringList supportedMimeTypes() const override; - -private: - void buildSupportedTypes(); - - QStringList m_supportedMimeTypes; -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIAPLAYERSERVICEPLUGIN_H diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.mm deleted file mode 100644 index d91956e69..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.mm +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfmediaplayerserviceplugin.h" -#include <QtCore/QDebug> - -#include "avfmediaplayerservice.h" - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -AVFMediaPlayerServicePlugin::AVFMediaPlayerServicePlugin() -{ - buildSupportedTypes(); -} - -QMediaService *AVFMediaPlayerServicePlugin::create(const QString &key) -{ -#ifdef QT_DEBUG_AVF - qDebug() << "AVFMediaPlayerServicePlugin::create" << key; -#endif - if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) - return new AVFMediaPlayerService; - - qWarning() << "unsupported key: " << key; - return nullptr; -} - -void AVFMediaPlayerServicePlugin::release(QMediaService *service) -{ - delete service; -} - -QMultimedia::SupportEstimate AVFMediaPlayerServicePlugin::hasSupport(const QString &mimeType, const QStringList &codecs) const -{ - Q_UNUSED(codecs); - - if (m_supportedMimeTypes.contains(mimeType)) - return QMultimedia::ProbablySupported; - - return QMultimedia::MaybeSupported; -} - -QStringList AVFMediaPlayerServicePlugin::supportedMimeTypes() const -{ - return m_supportedMimeTypes; -} - -void AVFMediaPlayerServicePlugin::buildSupportedTypes() -{ - //Populate m_supportedMimeTypes with mimetypes AVAsset supports - NSArray *mimeTypes = [AVURLAsset audiovisualMIMETypes]; - for (NSString *mimeType in mimeTypes) - { - m_supportedMimeTypes.append(QString::fromUtf8([mimeType UTF8String])); - } -#ifdef QT_DEBUG_AVF - qDebug() << "AVFMediaPlayerServicePlugin::buildSupportedTypes"; - qDebug() << "Supported Types: " << m_supportedMimeTypes; -#endif - -} diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h deleted file mode 100644 index 6d01162b2..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFMEDIAPLAYERSESSION_H -#define AVFMEDIAPLAYERSESSION_H - -#include <QtCore/QObject> -#include <QtCore/QByteArray> -#include <QtCore/QSet> -#include <QtCore/QResource> - -#include <QtMultimedia/QMediaPlayerControl> -#include <QtMultimedia/QMediaPlayer> - -QT_BEGIN_NAMESPACE - -class AVFMediaPlayerService; -class AVFVideoOutput; - -class AVFMediaPlayerSession : public QObject -{ - Q_OBJECT -public: - AVFMediaPlayerSession(AVFMediaPlayerService *service, QObject *parent = nullptr); - virtual ~AVFMediaPlayerSession(); - - void setVideoOutput(AVFVideoOutput *output); - void *currentAssetHandle(); - - QMediaPlayer::State state() const; - QMediaPlayer::MediaStatus mediaStatus() const; - - QUrl media() const; - QIODevice *mediaStream() const; - void setMedia(const QUrl &content, QIODevice *stream); - - qint64 position() const; - qint64 duration() const; - - int bufferStatus() const; - - int volume() const; - bool isMuted() const; - - bool isAudioAvailable() const; - bool isVideoAvailable() const; - - bool isSeekable() const; - QMediaTimeRange availablePlaybackRanges() const; - - qreal playbackRate() const; - -public Q_SLOTS: - void setPlaybackRate(qreal rate); - - void setPosition(qint64 pos); - - void play(); - void pause(); - void stop(); - - void setVolume(int volume); - void setMuted(bool muted); - - void processEOS(); - void processLoadStateChange(QMediaPlayer::State newState); - void processPositionChange(); - void processMediaLoadError(); - - void processLoadStateChange(); - void processLoadStateFailure(); - - void processBufferStateChange(int bufferStatus); - - void processDurationChange(qint64 duration); - - void streamReady(); - void streamDestroyed(); - -Q_SIGNALS: - void positionChanged(qint64 position); - void durationChanged(qint64 duration); - void stateChanged(QMediaPlayer::State newState); - void bufferStatusChanged(int bufferStatus); - void mediaStatusChanged(QMediaPlayer::MediaStatus status); - void volumeChanged(int volume); - void mutedChanged(bool muted); - void audioAvailableChanged(bool audioAvailable); - void videoAvailableChanged(bool videoAvailable); - void playbackRateChanged(qreal rate); - void seekableChanged(bool seekable); - void error(int error, const QString &errorString); - -private: - void setAudioAvailable(bool available); - void setVideoAvailable(bool available); - void setSeekable(bool seekable); - void resetStream(QIODevice *stream = nullptr); - - AVFMediaPlayerService *m_service; - AVFVideoOutput *m_videoOutput; - - QMediaPlayer::State m_state; - QMediaPlayer::MediaStatus m_mediaStatus; - QIODevice *m_mediaStream; - QUrl m_resources; - - bool m_muted; - bool m_tryingAsync; - int m_volume; - qreal m_rate; - qint64 m_requestedPosition; - - qint64 m_duration; - int m_bufferStatus; - bool m_videoAvailable; - bool m_audioAvailable; - bool m_seekable; - - void *m_observer; -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIAPLAYERSESSION_H diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm deleted file mode 100644 index 95121f58a..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm +++ /dev/null @@ -1,1067 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfmediaplayersession.h" -#include "avfmediaplayerservice.h" -#include "avfvideooutput.h" - -#include <qpointer.h> -#include <QFileInfo> - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -//AVAsset Keys -static NSString* const AVF_TRACKS_KEY = @"tracks"; -static NSString* const AVF_PLAYABLE_KEY = @"playable"; - -//AVPlayerItem keys -static NSString* const AVF_STATUS_KEY = @"status"; -static NSString* const AVF_BUFFER_LIKELY_KEEP_UP_KEY = @"playbackLikelyToKeepUp"; - -//AVPlayer keys -static NSString* const AVF_RATE_KEY = @"rate"; -static NSString* const AVF_CURRENT_ITEM_KEY = @"currentItem"; -static NSString* const AVF_CURRENT_ITEM_DURATION_KEY = @"currentItem.duration"; - -static void *AVFMediaPlayerSessionObserverRateObservationContext = &AVFMediaPlayerSessionObserverRateObservationContext; -static void *AVFMediaPlayerSessionObserverStatusObservationContext = &AVFMediaPlayerSessionObserverStatusObservationContext; -static void *AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext = &AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext; -static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMediaPlayerSessionObserverCurrentItemObservationContext; -static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext = &AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext; - -@interface AVFMediaPlayerSessionObserver : NSObject<AVAssetResourceLoaderDelegate> - -@property (readonly, getter=player) AVPlayer* m_player; -@property (readonly, getter=playerItem) AVPlayerItem* m_playerItem; -@property (readonly, getter=playerLayer) AVPlayerLayer* m_playerLayer; -@property (readonly, getter=session) AVFMediaPlayerSession* m_session; - -- (AVFMediaPlayerSessionObserver *) initWithMediaPlayerSession:(AVFMediaPlayerSession *)session; -- (void) setURL:(NSURL *)url mimeType:(NSString *)mimeType; -- (void) unloadMedia; -- (void) prepareToPlayAsset:(AVURLAsset *)asset withKeys:(NSArray *)requestedKeys; -- (void) assetFailedToPrepareForPlayback:(NSError *)error; -- (void) playerItemDidReachEnd:(NSNotification *)notification; -- (void) playerItemTimeJumped:(NSNotification *)notification; -- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object - change:(NSDictionary *)change context:(void *)context; -- (void) detatchSession; -- (void) dealloc; -- (BOOL) resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest; -@end - -@implementation AVFMediaPlayerSessionObserver -{ -@private - AVFMediaPlayerSession *m_session; - AVPlayer *m_player; - AVPlayerItem *m_playerItem; - AVPlayerLayer *m_playerLayer; - NSURL *m_URL; - BOOL m_bufferIsLikelyToKeepUp; - NSData *m_data; - NSString *m_mimeType; -} - -@synthesize m_player, m_playerItem, m_playerLayer, m_session; - -- (AVFMediaPlayerSessionObserver *) initWithMediaPlayerSession:(AVFMediaPlayerSession *)session -{ - if (!(self = [super init])) - return nil; - - self->m_session = session; - self->m_bufferIsLikelyToKeepUp = FALSE; - return self; -} - -- (void) setURL:(NSURL *)url mimeType:(NSString *)mimeType -{ - [m_mimeType release]; - m_mimeType = [mimeType retain]; - - if (m_URL != url) - { - [m_URL release]; - m_URL = [url copy]; - - //Create an asset for inspection of a resource referenced by a given URL. - //Load the values for the asset keys "tracks", "playable". - - // 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; - QPointer<AVFMediaPlayerSession> session(m_session); - - // Tells the asset to load the values of any of the specified keys that are not already loaded. - [asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler: - ^{ - dispatch_async( dispatch_get_main_queue(), - ^{ - if (session) - [blockSelf prepareToPlayAsset:asset withKeys:requestedKeys]; - [asset release]; - [requestedKeys release]; - }); - }]; - } -} - -- (void) unloadMedia -{ - if (m_playerItem) { - [m_playerItem removeObserver:self forKeyPath:AVF_STATUS_KEY]; - [m_playerItem removeObserver:self forKeyPath:AVF_BUFFER_LIKELY_KEEP_UP_KEY]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:AVPlayerItemDidPlayToEndTimeNotification - object:m_playerItem]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:AVPlayerItemTimeJumpedNotification - object:m_playerItem]; - m_playerItem = 0; - } - if (m_player) { - [m_player setRate:0.0]; - [m_player removeObserver:self forKeyPath:AVF_CURRENT_ITEM_DURATION_KEY]; - [m_player removeObserver:self forKeyPath:AVF_CURRENT_ITEM_KEY]; - [m_player removeObserver:self forKeyPath:AVF_RATE_KEY]; - [m_player release]; - m_player = 0; - } - if (m_playerLayer) { - [m_playerLayer release]; - m_playerLayer = 0; - } -#if defined(Q_OS_IOS) - [[AVAudioSession sharedInstance] setActive:NO error:nil]; -#endif -} - -- (void) prepareToPlayAsset:(AVURLAsset *)asset - withKeys:(NSArray *)requestedKeys -{ - //Make sure that the value of each key has loaded successfully. - for (NSString *thisKey in requestedKeys) - { - NSError *error = nil; - AVKeyValueStatus keyStatus = [asset statusOfValueForKey:thisKey error:&error]; -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << [thisKey UTF8String] << " status: " << keyStatus; -#endif - if (keyStatus == AVKeyValueStatusFailed) - { - [self assetFailedToPrepareForPlayback:error]; - return; - } - } - - //Use the AVAsset playable property to detect whether the asset can be played. -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << "isPlayable: " << [asset isPlayable]; -#endif - if (!asset.playable) - { - //Generate an error describing the failure. - NSString *localizedDescription = NSLocalizedString(@"Item cannot be played", @"Item cannot be played description"); - NSString *localizedFailureReason = NSLocalizedString(@"The assets tracks were loaded, but could not be made playable.", @"Item cannot be played failure reason"); - NSDictionary *errorDict = [NSDictionary dictionaryWithObjectsAndKeys: - localizedDescription, NSLocalizedDescriptionKey, - localizedFailureReason, NSLocalizedFailureReasonErrorKey, - nil]; - NSError *assetCannotBePlayedError = [NSError errorWithDomain:@"StitchedStreamPlayer" code:0 userInfo:errorDict]; - - [self assetFailedToPrepareForPlayback:assetCannotBePlayedError]; - - return; - } - - //At this point we're ready to set up for playback of the asset. - //Stop observing our prior AVPlayerItem, if we have one. - if (m_playerItem) - { - //Remove existing player item key value observers and notifications. - [self unloadMedia]; - } - - //Create a new instance of AVPlayerItem from the now successfully loaded AVAsset. - m_playerItem = [AVPlayerItem playerItemWithAsset:asset]; - - //Observe the player item "status" key to determine when it is ready to play. - [m_playerItem addObserver:self - forKeyPath:AVF_STATUS_KEY - options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew - context:AVFMediaPlayerSessionObserverStatusObservationContext]; - - [m_playerItem addObserver:self - forKeyPath:AVF_BUFFER_LIKELY_KEEP_UP_KEY - options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew - context:AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext]; - - //When the player item has played to its end time we'll toggle - //the movie controller Pause button to be the Play button - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(playerItemDidReachEnd:) - name:AVPlayerItemDidPlayToEndTimeNotification - object:m_playerItem]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(playerItemTimeJumped:) - name:AVPlayerItemTimeJumpedNotification - object:m_playerItem]; - - //Get a new AVPlayer initialized to play the specified player item. - m_player = [AVPlayer playerWithPlayerItem:m_playerItem]; - [m_player retain]; - - //Set the initial volume on new player object - if (self.session) { - [m_player setVolume:m_session->volume() / 100.0f]; - [m_player setMuted:m_session->isMuted()]; - } - - //Create a new player layer if we don't have one already - if (!m_playerLayer) - { - m_playerLayer = [AVPlayerLayer playerLayerWithPlayer:m_player]; - [m_playerLayer retain]; - m_playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; - m_playerLayer.anchorPoint = CGPointMake(0.0f, 0.0f); - } - - //Observe the AVPlayer "currentItem" property to find out when any - //AVPlayer replaceCurrentItemWithPlayerItem: replacement will/did - //occur. - [m_player addObserver:self - forKeyPath:AVF_CURRENT_ITEM_KEY - options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew - context:AVFMediaPlayerSessionObserverCurrentItemObservationContext]; - - //Observe the AVPlayer "rate" property to update the scrubber control. - [m_player addObserver:self - forKeyPath:AVF_RATE_KEY - options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew - context:AVFMediaPlayerSessionObserverRateObservationContext]; - - //Observe the duration for getting the buffer state - [m_player addObserver:self - forKeyPath:AVF_CURRENT_ITEM_DURATION_KEY - options:0 - context:AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext]; -#if defined(Q_OS_IOS) - [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil]; - [[AVAudioSession sharedInstance] setActive:YES error:nil]; -#endif -} - --(void) assetFailedToPrepareForPlayback:(NSError *)error -{ - Q_UNUSED(error); - QMetaObject::invokeMethod(m_session, "processMediaLoadError", Qt::AutoConnection); -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; - qDebug() << [[error localizedDescription] UTF8String]; - qDebug() << [[error localizedFailureReason] UTF8String]; - qDebug() << [[error localizedRecoverySuggestion] UTF8String]; -#endif -} - -- (void) playerItemDidReachEnd:(NSNotification *)notification -{ - Q_UNUSED(notification); - if (self.session) - QMetaObject::invokeMethod(m_session, "processEOS", Qt::AutoConnection); -} - -- (void) playerItemTimeJumped:(NSNotification *)notification -{ - Q_UNUSED(notification); - if (self.session) - QMetaObject::invokeMethod(m_session, "processPositionChange", Qt::AutoConnection); -} - -- (void) observeValueForKeyPath:(NSString*) path - ofObject:(id)object - change:(NSDictionary*)change - context:(void*)context -{ - //AVPlayerItem "status" property value observer. - if (context == AVFMediaPlayerSessionObserverStatusObservationContext) - { - AVPlayerStatus status = (AVPlayerStatus)[[change objectForKey:NSKeyValueChangeNewKey] integerValue]; - switch (status) - { - //Indicates that the status of the player is not yet known because - //it has not tried to load new media resources for playback - case AVPlayerStatusUnknown: - { - //QMetaObject::invokeMethod(m_session, "processLoadStateChange", Qt::AutoConnection); - } - break; - - case AVPlayerStatusReadyToPlay: - { - //Once the AVPlayerItem becomes ready to play, i.e. - //[playerItem status] == AVPlayerItemStatusReadyToPlay, - //its duration can be fetched from the item. - if (self.session) - QMetaObject::invokeMethod(m_session, "processLoadStateChange", Qt::AutoConnection); - } - break; - - case AVPlayerStatusFailed: - { - AVPlayerItem *playerItem = static_cast<AVPlayerItem*>(object); - [self assetFailedToPrepareForPlayback:playerItem.error]; - - if (self.session) - QMetaObject::invokeMethod(m_session, "processLoadStateFailure", Qt::AutoConnection); - } - break; - } - } - else if (context == AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext) - { - const bool isPlaybackLikelyToKeepUp = [m_playerItem isPlaybackLikelyToKeepUp]; - if (isPlaybackLikelyToKeepUp != m_bufferIsLikelyToKeepUp) { - m_bufferIsLikelyToKeepUp = isPlaybackLikelyToKeepUp; - QMetaObject::invokeMethod(m_session, "processBufferStateChange", Qt::AutoConnection, - Q_ARG(int, isPlaybackLikelyToKeepUp ? 100 : 0)); - } - } - //AVPlayer "rate" property value observer. - else if (context == AVFMediaPlayerSessionObserverRateObservationContext) - { - //QMetaObject::invokeMethod(m_session, "setPlaybackRate", Qt::AutoConnection, Q_ARG(qreal, [m_player rate])); - } - //AVPlayer "currentItem" property observer. - //Called when the AVPlayer replaceCurrentItemWithPlayerItem: - //replacement will/did occur. - else if (context == AVFMediaPlayerSessionObserverCurrentItemObservationContext) - { - AVPlayerItem *newPlayerItem = [change objectForKey:NSKeyValueChangeNewKey]; - if (m_playerItem != newPlayerItem) - m_playerItem = newPlayerItem; - } - else if (context == AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext) - { - const CMTime time = [m_playerItem duration]; - const qint64 duration = static_cast<qint64>(float(time.value) / float(time.timescale) * 1000.0f); - if (self.session) - QMetaObject::invokeMethod(m_session, "processDurationChange", Qt::AutoConnection, Q_ARG(qint64, duration)); - } - else - { - [super observeValueForKeyPath:path ofObject:object change:change context:context]; - } -} - -- (void) detatchSession -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - m_session = 0; -} - -- (void) dealloc -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - [self unloadMedia]; - - if (m_URL) { - [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) - : QObject(parent) - , m_service(service) - , m_videoOutput(nullptr) - , m_state(QMediaPlayer::StoppedState) - , m_mediaStatus(QMediaPlayer::NoMedia) - , m_mediaStream(nullptr) - , m_muted(false) - , m_tryingAsync(false) - , m_volume(100) - , m_rate(1.0) - , m_requestedPosition(-1) - , m_duration(0) - , m_bufferStatus(0) - , m_videoAvailable(false) - , m_audioAvailable(false) - , m_seekable(false) -{ - m_observer = [[AVFMediaPlayerSessionObserver alloc] initWithMediaPlayerSession:this]; -} - -AVFMediaPlayerSession::~AVFMediaPlayerSession() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - //Detatch the session from the sessionObserver (which could still be alive trying to communicate with this session). - [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) detatchSession]; - [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) release]; -} - -void AVFMediaPlayerSession::setVideoOutput(AVFVideoOutput *output) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << output; -#endif - - if (m_videoOutput == output) - return; - - //Set the current output layer to null to stop rendering - if (m_videoOutput) { - m_videoOutput->setLayer(nullptr); - } - - m_videoOutput = output; - - if (m_videoOutput && m_state != QMediaPlayer::StoppedState) - m_videoOutput->setLayer([static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerLayer]); -} - -void *AVFMediaPlayerSession::currentAssetHandle() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - AVAsset *currentAsset = [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerItem] asset]; - return currentAsset; -} - -QMediaPlayer::State AVFMediaPlayerSession::state() const -{ - return m_state; -} - -QMediaPlayer::MediaStatus AVFMediaPlayerSession::mediaStatus() const -{ - return m_mediaStatus; -} - -QMediaContent AVFMediaPlayerSession::media() const -{ - return m_resources; -} - -QIODevice *AVFMediaPlayerSession::mediaStream() const -{ - return m_mediaStream; -} - -static void setURL(void *observer, const QByteArray &url, const QString &mimeType = QString()) -{ - NSString *urlString = [NSString stringWithUTF8String:url.constData()]; - NSURL *nsurl = [NSURL URLWithString:urlString]; - [static_cast<AVFMediaPlayerSessionObserver*>(observer) setURL:nsurl mimeType:[NSString stringWithUTF8String:mimeType.toLatin1().constData()]]; -} - -static void setStreamURL(void *observer, const QByteArray &url) -{ - setURL(observer, QByteArrayLiteral("iodevice://") + url, QFileInfo(url).suffix()); -} - -void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *stream) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << content.request().url(); -#endif - - [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) unloadMedia]; - - m_resources = content; - resetStream(stream); - - setAudioAvailable(false); - setVideoAvailable(false); - setSeekable(false); - m_requestedPosition = -1; - Q_EMIT positionChanged(position()); - - const QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatus; - const QMediaPlayer::State oldState = m_state; - - if (!m_mediaStream && (content.isNull() || content.request().url().isEmpty())) { - m_mediaStatus = QMediaPlayer::NoMedia; - if (m_mediaStatus != oldMediaStatus) - Q_EMIT mediaStatusChanged(m_mediaStatus); - - m_state = QMediaPlayer::StoppedState; - if (m_state != oldState) - Q_EMIT stateChanged(m_state); - - return; - } - - m_mediaStatus = QMediaPlayer::LoadingMedia; - if (m_mediaStatus != oldMediaStatus) - Q_EMIT mediaStatusChanged(m_mediaStatus); - - 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().toEncoded()); - } else { - //Load AVURLAsset - //initialize asset using content's URL - setURL(m_observer, m_resources.request().url().toEncoded()); - } - - m_state = QMediaPlayer::StoppedState; - if (m_state != oldState) - Q_EMIT stateChanged(m_state); -} - -qint64 AVFMediaPlayerSession::position() const -{ - AVPlayerItem *playerItem = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerItem]; - - if (!playerItem) - return m_requestedPosition != -1 ? m_requestedPosition : 0; - - CMTime time = [playerItem currentTime]; - return static_cast<quint64>(float(time.value) / float(time.timescale) * 1000.0f); -} - -qint64 AVFMediaPlayerSession::duration() const -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - return m_duration; -} - -int AVFMediaPlayerSession::bufferStatus() const -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - return m_bufferStatus; -} - -int AVFMediaPlayerSession::volume() const -{ - return m_volume; -} - -bool AVFMediaPlayerSession::isMuted() const -{ - return m_muted; -} - -void AVFMediaPlayerSession::setAudioAvailable(bool available) -{ - if (m_audioAvailable == available) - return; - - m_audioAvailable = available; - Q_EMIT audioAvailableChanged(available); -} - -bool AVFMediaPlayerSession::isAudioAvailable() const -{ - return m_audioAvailable; -} - -void AVFMediaPlayerSession::setVideoAvailable(bool available) -{ - if (m_videoAvailable == available) - return; - - m_videoAvailable = available; - Q_EMIT videoAvailableChanged(available); -} - -bool AVFMediaPlayerSession::isVideoAvailable() const -{ - return m_videoAvailable; -} - -bool AVFMediaPlayerSession::isSeekable() const -{ - return m_seekable; -} - -void AVFMediaPlayerSession::setSeekable(bool seekable) -{ - if (m_seekable == seekable) - return; - - m_seekable = seekable; - Q_EMIT seekableChanged(seekable); -} - -QMediaTimeRange AVFMediaPlayerSession::availablePlaybackRanges() const -{ - AVPlayerItem *playerItem = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerItem]; - - if (playerItem) { - QMediaTimeRange timeRanges; - - NSArray *ranges = [playerItem loadedTimeRanges]; - for (NSValue *timeRange in ranges) { - CMTimeRange currentTimeRange = [timeRange CMTimeRangeValue]; - qint64 startTime = qint64(float(currentTimeRange.start.value) / currentTimeRange.start.timescale * 1000.0); - timeRanges.addInterval(startTime, startTime + qint64(float(currentTimeRange.duration.value) / currentTimeRange.duration.timescale * 1000.0)); - } - if (!timeRanges.isEmpty()) - return timeRanges; - } - return QMediaTimeRange(0, duration()); -} - -qreal AVFMediaPlayerSession::playbackRate() const -{ - return m_rate; -} - -void AVFMediaPlayerSession::setPlaybackRate(qreal rate) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << rate; -#endif - - if (qFuzzyCompare(m_rate, rate)) - return; - - m_rate = rate; - - AVPlayer *player = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player]; - if (player && m_state == QMediaPlayer::PlayingState) - [player setRate:m_rate]; - - Q_EMIT playbackRateChanged(m_rate); -} - -void AVFMediaPlayerSession::setPosition(qint64 pos) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << pos; -#endif - - if (pos == position()) - return; - - AVPlayerItem *playerItem = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerItem]; - if (!playerItem) { - m_requestedPosition = pos; - Q_EMIT positionChanged(m_requestedPosition); - return; - } - - if (!isSeekable()) { - if (m_requestedPosition != -1) { - m_requestedPosition = -1; - Q_EMIT positionChanged(position()); - } - return; - } - - pos = qMax(qint64(0), pos); - if (duration() > 0) - pos = qMin(pos, duration()); - - CMTime newTime = [playerItem currentTime]; - newTime.value = (pos / 1000.0f) * newTime.timescale; - [playerItem seekToTime:newTime toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:nil]; - - Q_EMIT positionChanged(pos); - - // Reset media status if the current status is EndOfMedia - if (m_mediaStatus == QMediaPlayer::EndOfMedia) { - QMediaPlayer::MediaStatus newMediaStatus = (m_state == QMediaPlayer::PausedState) ? QMediaPlayer::BufferedMedia - : QMediaPlayer::LoadedMedia; - Q_EMIT mediaStatusChanged((m_mediaStatus = newMediaStatus)); - } -} - -void AVFMediaPlayerSession::play() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << "currently: " << m_state; -#endif - - if (m_mediaStatus == QMediaPlayer::NoMedia || m_mediaStatus == QMediaPlayer::InvalidMedia) - return; - - if (m_state == QMediaPlayer::PlayingState) - return; - - if (m_videoOutput) { - m_videoOutput->setLayer([static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerLayer]); - } - - // Reset media status if the current status is EndOfMedia - if (m_mediaStatus == QMediaPlayer::EndOfMedia) - setPosition(0); - - if (m_mediaStatus == QMediaPlayer::LoadedMedia || m_mediaStatus == QMediaPlayer::BufferedMedia) { - // Setting the rate starts playback - [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player] setRate:m_rate]; - } - - m_state = QMediaPlayer::PlayingState; - processLoadStateChange(); - - Q_EMIT stateChanged(m_state); -} - -void AVFMediaPlayerSession::pause() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << "currently: " << m_state; -#endif - - if (m_mediaStatus == QMediaPlayer::NoMedia) - return; - - if (m_state == QMediaPlayer::PausedState) - return; - - m_state = QMediaPlayer::PausedState; - - if (m_videoOutput) { - m_videoOutput->setLayer([static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerLayer]); - } - - [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player] pause]; - - // Reset media status if the current status is EndOfMedia - if (m_mediaStatus == QMediaPlayer::EndOfMedia) - setPosition(0); - - - Q_EMIT stateChanged(m_state); -} - -void AVFMediaPlayerSession::stop() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << "currently: " << m_state; -#endif - - if (m_state == QMediaPlayer::StoppedState) - return; - - // AVPlayer doesn't have stop(), only pause() and play(). - [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player] pause]; - setPosition(0); - - if (m_videoOutput) { - m_videoOutput->setLayer(nullptr); - } - - if (m_mediaStatus == QMediaPlayer::BufferedMedia) - Q_EMIT mediaStatusChanged((m_mediaStatus = QMediaPlayer::LoadedMedia)); - - Q_EMIT positionChanged(position()); - Q_EMIT stateChanged((m_state = QMediaPlayer::StoppedState)); -} - -void AVFMediaPlayerSession::setVolume(int volume) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << volume; -#endif - - if (m_volume == volume) - return; - - m_volume = volume; - - AVPlayer *player = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player]; - if (player) - [player setVolume:volume / 100.0f]; - - Q_EMIT volumeChanged(m_volume); -} - -void AVFMediaPlayerSession::setMuted(bool muted) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << muted; -#endif - - if (m_muted == muted) - return; - - m_muted = muted; - - AVPlayer *player = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player]; - if (player) - [player setMuted:muted]; - - Q_EMIT mutedChanged(muted); -} - -void AVFMediaPlayerSession::processEOS() -{ - //AVPlayerItem has reached end of track/stream -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - Q_EMIT positionChanged(position()); - m_mediaStatus = QMediaPlayer::EndOfMedia; - m_state = QMediaPlayer::StoppedState; - - // At this point, frames should not be rendered anymore. - // Clear the output layer to make sure of that. - if (m_videoOutput) - m_videoOutput->setLayer(nullptr); - - Q_EMIT mediaStatusChanged(m_mediaStatus); - Q_EMIT stateChanged(m_state); -} - -void AVFMediaPlayerSession::processLoadStateChange(QMediaPlayer::State newState) -{ - AVPlayerStatus currentStatus = [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player] status]; - -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << currentStatus << ", " << m_mediaStatus << ", " << newState; -#endif - - if (m_mediaStatus == QMediaPlayer::NoMedia) - return; - - if (currentStatus == AVPlayerStatusReadyToPlay) { - - QMediaPlayer::MediaStatus newStatus = m_mediaStatus; - - AVPlayerItem *playerItem = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerItem]; - - if (playerItem) { - // Check each track for audio and video content - AVAssetTrack *videoTrack = nil; - NSArray *tracks = playerItem.tracks; - for (AVPlayerItemTrack *track in tracks) { - AVAssetTrack *assetTrack = track.assetTrack; - if (assetTrack) { - if ([assetTrack.mediaType isEqualToString:AVMediaTypeAudio]) - setAudioAvailable(true); - if ([assetTrack.mediaType isEqualToString:AVMediaTypeVideo]) { - setVideoAvailable(true); - if (!videoTrack) - videoTrack = assetTrack; - } - } - } - - setSeekable([[playerItem seekableTimeRanges] count] > 0); - - // Get the native size of the video, and reset the bounds of the player layer - AVPlayerLayer *playerLayer = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerLayer]; - if (videoTrack && playerLayer) { - if (!playerLayer.bounds.size.width || !playerLayer.bounds.size.height) { - playerLayer.bounds = CGRectMake(0.0f, 0.0f, - videoTrack.naturalSize.width, - videoTrack.naturalSize.height); - } - - if (m_videoOutput && newState != QMediaPlayer::StoppedState) { - m_videoOutput->setLayer(playerLayer); - } - } - - if (m_requestedPosition != -1) { - setPosition(m_requestedPosition); - m_requestedPosition = -1; - } - } - - newStatus = (newState != QMediaPlayer::StoppedState) ? QMediaPlayer::BufferedMedia - : QMediaPlayer::LoadedMedia; - - if (newStatus != m_mediaStatus) - Q_EMIT mediaStatusChanged((m_mediaStatus = newStatus)); - - } - - if (newState == QMediaPlayer::PlayingState && [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player]) { - // Setting the rate is enough to start playback, no need to call play() - [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player] setRate:m_rate]; - } -} - - -void AVFMediaPlayerSession::processLoadStateChange() -{ - processLoadStateChange(m_state); -} - - -void AVFMediaPlayerSession::processLoadStateFailure() -{ - Q_EMIT stateChanged((m_state = QMediaPlayer::StoppedState)); -} - -void AVFMediaPlayerSession::processBufferStateChange(int bufferStatus) -{ - if (bufferStatus == m_bufferStatus) - return; - - auto status = m_mediaStatus; - // Buffered -> unbuffered. - if (!bufferStatus) { - status = QMediaPlayer::StalledMedia; - } else if (status == QMediaPlayer::StalledMedia) { - status = QMediaPlayer::BufferedMedia; - // Resume playback. - if (m_state == QMediaPlayer::PlayingState) - [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player] setRate:m_rate]; - } - - if (m_mediaStatus != status) - Q_EMIT mediaStatusChanged(m_mediaStatus = status); - - m_bufferStatus = bufferStatus; - Q_EMIT bufferStatusChanged(bufferStatus); -} - -void AVFMediaPlayerSession::processDurationChange(qint64 duration) -{ - if (duration == m_duration) - return; - - m_duration = duration; - Q_EMIT durationChanged(duration); -} - -void AVFMediaPlayerSession::processPositionChange() -{ - if (m_state == QMediaPlayer::StoppedState) - return; - - Q_EMIT positionChanged(position()); -} - -void AVFMediaPlayerSession::processMediaLoadError() -{ - if (m_requestedPosition != -1) { - m_requestedPosition = -1; - Q_EMIT positionChanged(position()); - } - - Q_EMIT mediaStatusChanged((m_mediaStatus = QMediaPlayer::InvalidMedia)); - - Q_EMIT error(QMediaPlayer::FormatError, tr("Failed to load media")); -} - -void AVFMediaPlayerSession::streamReady() -{ - setStreamURL(m_observer, m_resources.request().url().toEncoded()); -} - -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/avfvideoframerenderer.h b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.h deleted file mode 100644 index 2d8a7df81..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFVIDEOFRAMERENDERER_H -#define AVFVIDEOFRAMERENDERER_H - -#include <QtCore/QObject> -#include <QtGui/QImage> -#include <QtGui/QOpenGLContext> -#include <QtCore/QSize> - -#import "Metal/Metal.h" -#import "MetalKit/MetalKit.h" - -@class CARenderer; -@class AVPlayerLayer; - -QT_BEGIN_NAMESPACE - -class QOpenGLFramebufferObject; -class QOpenGLShaderProgram; -class QWindow; -class QOpenGLContext; -class QAbstractVideoSurface; - -class AVFVideoFrameRenderer : public QObject -{ -public: - AVFVideoFrameRenderer(QAbstractVideoSurface *surface, QObject *parent = nullptr); - - virtual ~AVFVideoFrameRenderer(); - - quint64 renderLayerToTexture(AVPlayerLayer *layer); - quint64 renderLayerToMTLTexture(AVPlayerLayer *layer); - QImage renderLayerToImage(AVPlayerLayer *layer); - - static GLuint createGLTexture(CGLContextObj cglContextObj, CGLPixelFormatObj cglPixelFormtObj, - CVOpenGLTextureCacheRef cvglTextureCache, - CVPixelBufferRef cvPixelBufferRef, - CVOpenGLTextureRef cvOpenGLTextureRef); - - static id<MTLTexture> createMetalTexture(id<MTLDevice> mtlDevice, - CVMetalTextureCacheRef cvMetalTextureCacheRef, - CVPixelBufferRef cvPixelBufferRef, - MTLPixelFormat pixelFormat, size_t width, size_t height, - CVMetalTextureRef cvMetalTextureRef); - -private: - QOpenGLFramebufferObject* initRenderer(AVPlayerLayer *layer); - void renderLayerToFBO(AVPlayerLayer *layer, QOpenGLFramebufferObject *fbo); - void renderLayerToFBOCoreOpenGL(AVPlayerLayer *layer, QOpenGLFramebufferObject *fbo); - - CARenderer *m_videoLayerRenderer; - QAbstractVideoSurface *m_surface; - QOpenGLFramebufferObject *m_fbo[2]; - QOpenGLShaderProgram *m_shader = nullptr; - QWindow *m_offscreenSurface; - QOpenGLContext *m_glContext; - QSize m_targetSize; - - bool m_useCoreProfile = false; - - // Shared pixel buffer - CVPixelBufferRef m_CVPixelBuffer; - - // OpenGL Texture - CVOpenGLTextureCacheRef m_CVGLTextureCache; - CVOpenGLTextureRef m_CVGLTexture; - CGLPixelFormatObj m_CGLPixelFormat; - GLuint m_textureName = 0; - - // Metal Texture - CVMetalTextureRef m_CVMTLTexture; - CVMetalTextureCacheRef m_CVMTLTextureCache; - - NSOpenGLContext *m_NSGLContext = nullptr; - - GLuint m_quadVao = 0; - GLuint m_quadVbos[2]; - - uint m_currentBuffer; - bool m_isContextShared; - - id<MTLDevice> m_metalDevice = nil; - id<MTLTexture> m_metalTexture = nil; -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEOFRAMERENDERER_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm deleted file mode 100644 index f57b26dff..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm +++ /dev/null @@ -1,464 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfvideoframerenderer.h" - -#include <QtMultimedia/qabstractvideosurface.h> -#include <QtOpenGL/QOpenGLFramebufferObject> -#include <QtGui/QWindow> -#include <QOpenGLShaderProgram> - -#ifdef QT_DEBUG_AVF -#include <QtCore/qdebug.h> -#endif - -#import <CoreVideo/CVBase.h> -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -AVFVideoFrameRenderer::AVFVideoFrameRenderer(QAbstractVideoSurface *surface, QObject *parent) - : QObject(parent) - , m_videoLayerRenderer(nullptr) - , m_surface(surface) - , m_offscreenSurface(nullptr) - , m_glContext(nullptr) - , m_currentBuffer(1) - , m_isContextShared(true) -{ - m_fbo[0] = nullptr; - m_fbo[1] = nullptr; -} - -AVFVideoFrameRenderer::~AVFVideoFrameRenderer() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - - [m_videoLayerRenderer release]; - [m_metalDevice release]; - delete m_fbo[0]; - delete m_fbo[1]; - delete m_offscreenSurface; - delete m_glContext; - - if (m_useCoreProfile) { - glDeleteVertexArrays(1, &m_quadVao); - glDeleteBuffers(2, m_quadVbos); - delete m_shader; - } -} - -quint64 AVFVideoFrameRenderer::renderLayerToTexture(AVPlayerLayer *layer) -{ - //Is layer valid - if (!layer) - return 0; - - //If the glContext isn't shared, it doesn't make sense to return a texture for us - if (m_offscreenSurface && !m_isContextShared) - return 0; - - QOpenGLFramebufferObject *fbo = initRenderer(layer); - - if (!fbo) - return 0; - - renderLayerToFBO(layer, fbo); - if (m_glContext) - m_glContext->doneCurrent(); - - return fbo->texture(); -} - -quint64 AVFVideoFrameRenderer::renderLayerToMTLTexture(AVPlayerLayer *layer) -{ - m_targetSize = QSize(layer.bounds.size.width, layer.bounds.size.height); - - if (!m_metalDevice) - m_metalDevice = MTLCreateSystemDefaultDevice(); - - if (!m_metalTexture) { - auto desc = [[MTLTextureDescriptor alloc] init]; - desc.textureType = MTLTextureType2D; - desc.width = NSUInteger(m_targetSize.width()); - desc.height = NSUInteger(m_targetSize.height()); - desc.resourceOptions = MTLResourceStorageModePrivate; - desc.usage = MTLTextureUsageRenderTarget; - desc.pixelFormat = MTLPixelFormatRGBA8Unorm; - - m_metalTexture = [m_metalDevice newTextureWithDescriptor: desc]; - [desc release]; - } - - if (!m_videoLayerRenderer) { - m_videoLayerRenderer = [CARenderer rendererWithMTLTexture:m_metalTexture options:nil]; - [m_videoLayerRenderer retain]; - } - - if (m_videoLayerRenderer.layer != layer) { - m_videoLayerRenderer.layer = layer; - m_videoLayerRenderer.bounds = layer.bounds; - } - - [m_videoLayerRenderer beginFrameAtTime:CACurrentMediaTime() timeStamp:NULL]; - [m_videoLayerRenderer addUpdateRect:layer.bounds]; - [m_videoLayerRenderer render]; - [m_videoLayerRenderer endFrame]; - - return quint64(m_metalTexture); -} - -QImage AVFVideoFrameRenderer::renderLayerToImage(AVPlayerLayer *layer) -{ - //Is layer valid - if (!layer) { - return QImage(); - } - - QOpenGLFramebufferObject *fbo = initRenderer(layer); - - if (!fbo) - return QImage(); - - renderLayerToFBO(layer, fbo); - QImage fboImage = fbo->toImage(); - if (m_glContext) - m_glContext->doneCurrent(); - - return fboImage; -} - -QOpenGLFramebufferObject *AVFVideoFrameRenderer::initRenderer(AVPlayerLayer *layer) -{ - - //Get size from AVPlayerLayer - m_targetSize = QSize(layer.bounds.size.width, layer.bounds.size.height); - - QOpenGLContext *shareContext = !m_glContext && m_surface - ? qobject_cast<QOpenGLContext*>(m_surface->property("GLContext").value<QObject*>()) - : nullptr; - - //Make sure we have an OpenGL context to make current - if (shareContext || (!QOpenGLContext::currentContext() && !m_glContext)) { - - //Create Hidden QWindow surface to create context in this thread - delete m_offscreenSurface; - m_offscreenSurface = new QWindow(); - m_offscreenSurface->setSurfaceType(QWindow::OpenGLSurface); - //Needs geometry to be a valid surface, but size is not important - m_offscreenSurface->setGeometry(0, 0, 1, 1); - m_offscreenSurface->create(); - - delete m_glContext; - m_glContext = new QOpenGLContext(); - m_glContext->setFormat(m_offscreenSurface->requestedFormat()); - - if (shareContext) { - m_glContext->setShareContext(shareContext); - m_isContextShared = true; - } else { -#ifdef QT_DEBUG_AVF - qWarning("failed to get Render Thread context"); -#endif - m_isContextShared = false; - } - if (!m_glContext->create()) { - qWarning("failed to create QOpenGLContext"); - return nullptr; - } - - // CARenderer must be re-created with different current context, so release it now. - // See lines below where m_videoLayerRenderer is constructed. - if (m_videoLayerRenderer) { - [m_videoLayerRenderer release]; - m_videoLayerRenderer = nullptr; - } - - if (m_useCoreProfile) { - glDeleteVertexArrays(1, &m_quadVao); - glDeleteBuffers(2, m_quadVbos); - delete m_shader; - m_shader = nullptr; - } - } - - //Need current context - if (m_glContext) - m_glContext->makeCurrent(m_offscreenSurface); - - if (!m_metalDevice) - m_metalDevice = MTLCreateSystemDefaultDevice(); - - if (@available(macOS 10.13, *)) { - m_useCoreProfile = m_metalDevice && (QOpenGLContext::currentContext()->format().profile() == - QSurfaceFormat::CoreProfile); - } else { - m_useCoreProfile = false; - } - - // Create the CARenderer if needed for no Core OpenGL - if (!m_videoLayerRenderer) { - if (!m_useCoreProfile) { - m_videoLayerRenderer = [CARenderer rendererWithCGLContext: CGLGetCurrentContext() - options: nil]; - [m_videoLayerRenderer retain]; - } else if (@available(macOS 10.13, *)) { - // This is always true when m_useCoreProfile is true, but the compiler wants the check - // anyway - // Setup Core OpenGL shader, VAO, VBOs and metal renderer - m_shader = new QOpenGLShaderProgram(); - m_shader->create(); - if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, R"(#version 150 core - in vec2 qt_VertexPosition; - in vec2 qt_VertexTexCoord; - out vec2 qt_TexCoord; - void main() - { - qt_TexCoord = qt_VertexTexCoord; - gl_Position = vec4(qt_VertexPosition, 0.0f, 1.0f); - })")) { - qCritical() << "Vertex shader compilation failed" << m_shader->log(); - } - if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, R"(#version 150 core - in vec2 qt_TexCoord; - out vec4 fragColor; - uniform sampler2DRect videoFrame; - void main(void) - { - ivec2 textureDim = textureSize(videoFrame); - fragColor = texture(videoFrame, qt_TexCoord * textureDim); - })")) { - qCritical() << "Fragment shader compilation failed" << m_shader->log(); - } - - // Setup quad where the video frame will be attached - GLfloat vertices[] = { - -1.0f, -1.0f, - 1.0f, -1.0f, - -1.0f, 1.0f, - 1.0f, 1.0f, - }; - - GLfloat uvs[] = { - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - }; - - glGenVertexArrays(1, &m_quadVao); - glBindVertexArray(m_quadVao); - - // Create vertex buffer objects for vertices - glGenBuffers(2, m_quadVbos); - - // Setup vertices - glBindBuffer(GL_ARRAY_BUFFER, m_quadVbos[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), nullptr); - glEnableVertexAttribArray(0); - - // Setup uvs - glBindBuffer(GL_ARRAY_BUFFER, m_quadVbos[1]); - glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), nullptr); - glEnableVertexAttribArray(1); - - glBindVertexArray(0); - - // Setup shared Metal/OpenGL pixel buffer and textures - m_NSGLContext = QOpenGLContext::currentContext()->nativeInterface<QNativeInterface::QCocoaGLContext>()->nativeContext(); - m_CGLPixelFormat = m_NSGLContext.pixelFormat.CGLPixelFormatObj; - - NSDictionary* cvBufferProperties = @{ - static_cast<NSString*>(kCVPixelBufferOpenGLCompatibilityKey) : @YES, - static_cast<NSString*>(kCVPixelBufferMetalCompatibilityKey): @YES, - }; - - CVPixelBufferCreate(kCFAllocatorDefault, static_cast<size_t>(m_targetSize.width()), - static_cast<size_t>(m_targetSize.height()), kCVPixelFormatType_32BGRA, - static_cast<CFDictionaryRef>(cvBufferProperties), &m_CVPixelBuffer); - - m_textureName = createGLTexture(reinterpret_cast<CGLContextObj>(m_NSGLContext.CGLContextObj), - m_CGLPixelFormat, m_CVGLTextureCache, m_CVPixelBuffer, - m_CVGLTexture); - m_metalTexture = createMetalTexture(m_metalDevice, m_CVMTLTextureCache, m_CVPixelBuffer, - MTLPixelFormatBGRA8Unorm, - static_cast<size_t>(m_targetSize.width()), - static_cast<size_t>(m_targetSize.height()), - m_CVMTLTexture); - - m_videoLayerRenderer = [CARenderer rendererWithMTLTexture:m_metalTexture options:nil]; - [m_videoLayerRenderer retain]; - } - } - - //Set/Change render source if needed - if (m_videoLayerRenderer.layer != layer) { - m_videoLayerRenderer.layer = layer; - m_videoLayerRenderer.bounds = layer.bounds; - } - - //Do we have FBO's already? - if ((!m_fbo[0] && !m_fbo[0]) || (m_fbo[0]->size() != m_targetSize)) { - delete m_fbo[0]; - delete m_fbo[1]; - m_fbo[0] = new QOpenGLFramebufferObject(m_targetSize); - m_fbo[1] = new QOpenGLFramebufferObject(m_targetSize); - } - - //Switch buffer target - m_currentBuffer = !m_currentBuffer; - return m_fbo[m_currentBuffer]; -} - -void AVFVideoFrameRenderer::renderLayerToFBO(AVPlayerLayer *layer, QOpenGLFramebufferObject *fbo) -{ - //Start Rendering - //NOTE: This rendering method will NOT work on iOS as there is no CARenderer in iOS - if (!fbo->bind()) { - qWarning("AVFVideoRender FBO failed to bind"); - return; - } - - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, m_targetSize.width(), m_targetSize.height()); - - if (m_useCoreProfile) { - CGLLockContext(m_NSGLContext.CGLContextObj); - m_shader->bind(); - glBindVertexArray(m_quadVao); - } else { - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - // Render to FBO with inverted Y - glOrtho(0.0, m_targetSize.width(), 0.0, m_targetSize.height(), 0.0, 1.0); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - } - - [m_videoLayerRenderer beginFrameAtTime:CACurrentMediaTime() timeStamp:nullptr]; - [m_videoLayerRenderer addUpdateRect:layer.bounds]; - [m_videoLayerRenderer render]; - [m_videoLayerRenderer endFrame]; - - if (m_useCoreProfile) { - glActiveTexture(0); - glBindTexture(GL_TEXTURE_RECTANGLE, m_textureName); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - glBindTexture(GL_TEXTURE_RECTANGLE, 0); - - glBindVertexArray(0); - - m_shader->release(); - - CGLFlushDrawable(m_NSGLContext.CGLContextObj); - CGLUnlockContext(m_NSGLContext.CGLContextObj); - } else { - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - } - - glFinish(); //Rendering needs to be done before passing texture to video frame - - fbo->release(); -} - -GLuint AVFVideoFrameRenderer::createGLTexture(CGLContextObj cglContextObj, CGLPixelFormatObj cglPixelFormtObj, CVOpenGLTextureCacheRef cvglTextureCache, - CVPixelBufferRef cvPixelBufferRef, CVOpenGLTextureRef cvOpenGLTextureRef) -{ - CVReturn cvret; - // Create an OpenGL CoreVideo texture cache from the pixel buffer. - cvret = CVOpenGLTextureCacheCreate( - kCFAllocatorDefault, - nil, - cglContextObj, - cglPixelFormtObj, - nil, - &cvglTextureCache); - - // Create a CVPixelBuffer-backed OpenGL texture image from the texture cache. - cvret = CVOpenGLTextureCacheCreateTextureFromImage( - kCFAllocatorDefault, - cvglTextureCache, - cvPixelBufferRef, - nil, - &cvOpenGLTextureRef); - - // Get an OpenGL texture name from the CVPixelBuffer-backed OpenGL texture image. - return CVOpenGLTextureGetName(cvOpenGLTextureRef); -} - -id<MTLTexture> AVFVideoFrameRenderer::createMetalTexture(id<MTLDevice> mtlDevice, CVMetalTextureCacheRef cvMetalTextureCacheRef, CVPixelBufferRef cvPixelBufferRef, - MTLPixelFormat pixelFormat, size_t width, size_t height, CVMetalTextureRef cvMetalTextureRef) -{ - CVReturn cvret; - // Create a Metal Core Video texture cache from the pixel buffer. - cvret = CVMetalTextureCacheCreate( - kCFAllocatorDefault, - nil, - mtlDevice, - nil, - &cvMetalTextureCacheRef); - - // Create a CoreVideo pixel buffer backed Metal texture image from the texture cache. - cvret = CVMetalTextureCacheCreateTextureFromImage( - kCFAllocatorDefault, - cvMetalTextureCacheRef, - cvPixelBufferRef, nil, - pixelFormat, - width, height, - 0, - &cvMetalTextureRef); - - // Get a Metal texture using the CoreVideo Metal texture reference. - return CVMetalTextureGetTexture(cvMetalTextureRef); -} diff --git a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer_ios.h b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer_ios.h deleted file mode 100644 index d1de1f511..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer_ios.h +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFVIDEOFRAMERENDERER_H -#define AVFVIDEOFRAMERENDERER_H - -#include <QtCore/QObject> -#include <QtGui/QImage> -#include <QtGui/QOpenGLContext> -#include <QtCore/QSize> - -#import "Metal/Metal.h" -#import "MetalKit/MetalKit.h" - -@class AVPlayerLayer; -@class AVPlayerItemVideoOutput; - -QT_BEGIN_NAMESPACE - -class QOpenGLContext; -class QOpenGLFramebufferObject; -class QOpenGLShaderProgram; -class QOffscreenSurface; -class QAbstractVideoSurface; - -typedef struct __CVBuffer *CVBufferRef; -typedef CVBufferRef CVImageBufferRef; -typedef CVImageBufferRef CVPixelBufferRef; -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) -typedef struct __CVOpenGLESTextureCache *CVOpenGLESTextureCacheRef; -typedef CVImageBufferRef CVOpenGLESTextureRef; -// helpers to avoid boring if def -typedef CVOpenGLESTextureCacheRef CVOGLTextureCacheRef; -typedef CVOpenGLESTextureRef CVOGLTextureRef; -#define CVOGLTextureGetTarget CVOpenGLESTextureGetTarget -#define CVOGLTextureGetName CVOpenGLESTextureGetName -#define CVOGLTextureCacheCreate CVOpenGLESTextureCacheCreate -#define CVOGLTextureCacheCreateTextureFromImage CVOpenGLESTextureCacheCreateTextureFromImage -#define CVOGLTextureCacheFlush CVOpenGLESTextureCacheFlush -#else -typedef struct __CVOpenGLTextureCache *CVOpenGLTextureCacheRef; -typedef CVImageBufferRef CVOpenGLTextureRef; -// helpers to avoid boring if def -typedef CVOpenGLTextureCacheRef CVOGLTextureCacheRef; -typedef CVOpenGLTextureRef CVOGLTextureRef; -#define CVOGLTextureGetTarget CVOpenGLTextureGetTarget -#define CVOGLTextureGetName CVOpenGLTextureGetName -#define CVOGLTextureCacheCreate CVOpenGLTextureCacheCreate -#define CVOGLTextureCacheCreateTextureFromImage CVOpenGLTextureCacheCreateTextureFromImage -#define CVOGLTextureCacheFlush CVOpenGLTextureCacheFlush -#endif - -class AVFVideoFrameRenderer : public QObject -{ -public: - AVFVideoFrameRenderer(QAbstractVideoSurface *surface, QObject *parent = nullptr); - - virtual ~AVFVideoFrameRenderer(); - - void setPlayerLayer(AVPlayerLayer *layer); - - quint64 renderLayerToTexture(AVPlayerLayer *layer); - quint64 renderLayerToMTLTexture(AVPlayerLayer *layer); - QImage renderLayerToImage(AVPlayerLayer *layer); - -private: - void initRenderer(); - CVPixelBufferRef copyPixelBufferFromLayer(AVPlayerLayer *layer, size_t& width, size_t& height); - CVOGLTextureRef createCacheTextureFromLayer(AVPlayerLayer *layer, size_t& width, size_t& height); - - QOpenGLContext *m_glContext; - QOffscreenSurface *m_offscreenSurface; - QAbstractVideoSurface *m_surface; - CVOGLTextureCacheRef m_textureCache; - AVPlayerItemVideoOutput* m_videoOutput; - bool m_isContextShared; - - id<MTLDevice> m_metalDevice = nil; - CVMetalTextureCacheRef m_metalTextureCache = nil; -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEOFRAMERENDERER_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer_ios.mm b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer_ios.mm deleted file mode 100644 index cbaa1aa11..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer_ios.mm +++ /dev/null @@ -1,307 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfvideoframerenderer_ios.h" - -#include <QtMultimedia/qabstractvideosurface.h> -#include <QtOpenGL/QOpenGLFramebufferObject> -#include <QtOpenGL/QOpenGLShaderProgram> -#include <QtGui/QOffscreenSurface> - -#ifdef QT_DEBUG_AVF -#include <QtCore/qdebug.h> -#endif - -#import <CoreVideo/CVBase.h> -#import <AVFoundation/AVFoundation.h> -QT_USE_NAMESPACE - -AVFVideoFrameRenderer::AVFVideoFrameRenderer(QAbstractVideoSurface *surface, QObject *parent) - : QObject(parent) - , m_glContext(nullptr) - , m_offscreenSurface(nullptr) - , m_surface(surface) - , m_textureCache(nullptr) - , m_videoOutput(nullptr) - , m_isContextShared(true) -{ -} - -AVFVideoFrameRenderer::~AVFVideoFrameRenderer() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - - [m_videoOutput release]; // sending to nil is fine - if (m_textureCache) - CFRelease(m_textureCache); - if (m_metalTextureCache) - CFRelease(m_metalTextureCache); - [m_metalDevice release]; - delete m_offscreenSurface; - delete m_glContext; -} - -void AVFVideoFrameRenderer::setPlayerLayer(AVPlayerLayer *layer) -{ - Q_UNUSED(layer); - if (m_videoOutput) { - [m_videoOutput release]; - m_videoOutput = nullptr; - // will be re-created in first call to copyPixelBufferFromLayer - } -} - -quint64 AVFVideoFrameRenderer::renderLayerToMTLTexture(AVPlayerLayer *layer) -{ - if (!m_metalDevice) - m_metalDevice = MTLCreateSystemDefaultDevice(); - - if (!m_metalTextureCache) { - CVReturn err = CVMetalTextureCacheCreate(kCFAllocatorDefault, nullptr, - m_metalDevice, nullptr, &m_metalTextureCache); - if (err) { - qWarning() << "Error at CVMetalTextureCacheCreate" << err; - return 0; - } - } - - size_t width = 0, height = 0; - CVPixelBufferRef pixelBuffer = copyPixelBufferFromLayer(layer, width, height); - - if (!pixelBuffer) - return 0; - - CVMetalTextureCacheFlush(m_metalTextureCache, 0); - - CVMetalTextureRef texture = nil; - CVReturn err = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, m_metalTextureCache, pixelBuffer, NULL, - MTLPixelFormatBGRA8Unorm_sRGB, width, height, 0, &texture); - - if (!texture || err) - qWarning("CVMetalTextureCacheCreateTextureFromImage failed (error: %d)", err); - - CVPixelBufferRelease(pixelBuffer); - quint64 tex = 0; - if (texture) { - tex = quint64(CVMetalTextureGetTexture(texture)); - CFRelease(texture); - } - - return tex; -} - -quint64 AVFVideoFrameRenderer::renderLayerToTexture(AVPlayerLayer *layer) -{ - initRenderer(); - - // If the glContext isn't shared, it doesn't make sense to return a texture for us - if (!m_isContextShared) - return 0; - - size_t dummyWidth = 0, dummyHeight = 0; - auto texture = createCacheTextureFromLayer(layer, dummyWidth, dummyHeight); - auto tex = quint64(CVOGLTextureGetName(texture)); - CFRelease(texture); - - return tex; -} - -static NSString* const AVF_PIXEL_FORMAT_KEY = (NSString*)kCVPixelBufferPixelFormatTypeKey; -static NSNumber* const AVF_PIXEL_FORMAT_VALUE = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; -static NSDictionary* const AVF_OUTPUT_SETTINGS = [NSDictionary dictionaryWithObject:AVF_PIXEL_FORMAT_VALUE forKey:AVF_PIXEL_FORMAT_KEY]; - - -CVPixelBufferRef AVFVideoFrameRenderer::copyPixelBufferFromLayer(AVPlayerLayer *layer, - size_t& width, size_t& height) -{ - //Is layer valid - if (!layer) { -#ifdef QT_DEBUG_AVF - qWarning("copyPixelBufferFromLayer: invalid layer"); -#endif - return nullptr; - } - - if (!m_videoOutput) { - m_videoOutput = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:AVF_OUTPUT_SETTINGS]; - [m_videoOutput setDelegate:nil queue:nil]; - AVPlayerItem * item = [[layer player] currentItem]; - [item addOutput:m_videoOutput]; - } - - CFTimeInterval currentCAFrameTime = CACurrentMediaTime(); - CMTime currentCMFrameTime = [m_videoOutput itemTimeForHostTime:currentCAFrameTime]; - // happens when buffering / loading - if (CMTimeCompare(currentCMFrameTime, kCMTimeZero) < 0) { - return nullptr; - } - - CVPixelBufferRef pixelBuffer = [m_videoOutput copyPixelBufferForItemTime:currentCMFrameTime - itemTimeForDisplay:nil]; - if (!pixelBuffer) { -#ifdef QT_DEBUG_AVF - qWarning("copyPixelBufferForItemTime returned nil"); - CMTimeShow(currentCMFrameTime); -#endif - return nullptr; - } - - width = CVPixelBufferGetWidth(pixelBuffer); - height = CVPixelBufferGetHeight(pixelBuffer); - return pixelBuffer; -} - -CVOGLTextureRef AVFVideoFrameRenderer::createCacheTextureFromLayer(AVPlayerLayer *layer, - size_t& width, size_t& height) -{ - CVPixelBufferRef pixelBuffer = copyPixelBufferFromLayer(layer, width, height); - - if (!pixelBuffer) - return nullptr; - - CVOGLTextureCacheFlush(m_textureCache, 0); - - CVOGLTextureRef texture = nullptr; - CVReturn err = CVOGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, m_textureCache, pixelBuffer, nullptr, - GL_TEXTURE_2D, GL_RGBA, - (GLsizei) width, (GLsizei) height, - GL_BGRA, GL_UNSIGNED_BYTE, 0, - &texture); - - if (!texture || err) { -#ifdef QT_DEBUG_AVF - qWarning("CVOGLTextureCacheCreateTextureFromImage failed (error: %d)", err); -#endif - } - - CVPixelBufferRelease(pixelBuffer); - - return texture; -} - -QImage AVFVideoFrameRenderer::renderLayerToImage(AVPlayerLayer *layer) -{ - size_t width = 0; - size_t height = 0; - CVPixelBufferRef pixelBuffer = copyPixelBufferFromLayer(layer, width, height); - - if (!pixelBuffer) - return QImage(); - - OSType pixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer); - if (pixelFormat != kCVPixelFormatType_32BGRA) { -#ifdef QT_DEBUG_AVF - qWarning("CVPixelBuffer format is not BGRA32 (got: %d)", static_cast<quint32>(pixelFormat)); -#endif - return QImage(); - } - - CVPixelBufferLockBaseAddress(pixelBuffer, 0); - char *data = (char *)CVPixelBufferGetBaseAddress(pixelBuffer); - size_t stride = CVPixelBufferGetBytesPerRow(pixelBuffer); - - // format here is not relevant, only using for storage - QImage img = QImage(width, height, QImage::Format_ARGB32); - for (size_t j = 0; j < height; j++) { - memcpy(img.scanLine(j), data, width * 4); - data += stride; - } - - CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); - CVPixelBufferRelease(pixelBuffer); - return img; -} - -void AVFVideoFrameRenderer::initRenderer() -{ - // even for using a texture directly, we need to be able to make a context current, - // so we need an offscreen, and we shouldn't assume we can make the surface context - // current on that offscreen, so use our own (sharing with it). Slightly - // excessive but no performance penalty and makes the QImage path easier to maintain - - //Make sure we have an OpenGL context to make current - if (!m_glContext) { - //Create OpenGL context and set share context from surface - QOpenGLContext *shareContext = nullptr; - if (m_surface) { - shareContext = qobject_cast<QOpenGLContext*>(m_surface->property("GLContext").value<QObject*>()); - } - - m_glContext = new QOpenGLContext(); - if (shareContext) { - m_glContext->setShareContext(shareContext); - m_isContextShared = true; - } else { -#ifdef QT_DEBUG_AVF - qWarning("failed to get Render Thread context"); -#endif - m_isContextShared = false; - } - if (!m_glContext->create()) { -#ifdef QT_DEBUG_AVF - qWarning("failed to create QOpenGLContext"); -#endif - return; - } - } - - if (!m_offscreenSurface) { - m_offscreenSurface = new QOffscreenSurface(); - m_offscreenSurface->setFormat(m_glContext->format()); - m_offscreenSurface->create(); - } - - //Need current context - m_glContext->makeCurrent(m_offscreenSurface); - - if (!m_textureCache) { - // Create a new open gl texture cache - CVReturn err = CVOGLTextureCacheCreate(kCFAllocatorDefault, nullptr, - [EAGLContext currentContext], - nullptr, &m_textureCache); - if (err) { - #ifdef QT_DEBUG_AVF - qWarning("Error at CVOGLTextureCacheCreate %d", err); - #endif - } - } - -} diff --git a/src/plugins/avfoundation/mediaplayer/avfvideooutput.h b/src/plugins/avfoundation/mediaplayer/avfvideooutput.h deleted file mode 100644 index d3bcfecf7..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideooutput.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFVIDEOOUTPUT_H -#define AVFVIDEOOUTPUT_H - -#include <QtCore/qobject.h> - -QT_BEGIN_NAMESPACE - -class AVFVideoOutput -{ -public: - virtual ~AVFVideoOutput() {} - virtual void setLayer(void *playerLayer) = 0; -}; - -#define AVFVideoOutput_iid \ - "org.qt-project.qt.AVFVideoOutput/5.0" -Q_DECLARE_INTERFACE(AVFVideoOutput, AVFVideoOutput_iid) - -QT_END_NAMESPACE - -#endif // AVFVIDEOOUTPUT_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideooutput.mm b/src/plugins/avfoundation/mediaplayer/avfvideooutput.mm deleted file mode 100644 index 327681f50..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideooutput.mm +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfvideooutput.h" - -QT_USE_NAMESPACE diff --git a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.h b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.h deleted file mode 100644 index c1a629944..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFVIDEORENDERERCONTROL_H -#define AVFVIDEORENDERERCONTROL_H - -#include <QtMultimedia/QVideoRendererControl> -#include <QtCore/QMutex> -#include <QtCore/QSize> - -#include "avfvideooutput.h" - -#import <CoreVideo/CVBase.h> - -QT_BEGIN_NAMESPACE - -class AVFDisplayLink; -class AVFVideoFrameRenderer; - -class AVFVideoRendererControl : public QVideoRendererControl, public AVFVideoOutput -{ - Q_OBJECT - Q_INTERFACES(AVFVideoOutput) -public: - explicit AVFVideoRendererControl(QObject *parent = nullptr); - virtual ~AVFVideoRendererControl(); - - QAbstractVideoSurface *surface() const override; - void setSurface(QAbstractVideoSurface *surface) override; - - void setLayer(void *playerLayer) override; - -private Q_SLOTS: - void updateVideoFrame(const CVTimeStamp &ts); - -Q_SIGNALS: - void surfaceChanged(QAbstractVideoSurface *surface); - -private: - void setupVideoOutput(); - - QMutex m_mutex; - QAbstractVideoSurface *m_surface; - - void *m_playerLayer; - - AVFVideoFrameRenderer *m_frameRenderer; - AVFDisplayLink *m_displayLink; - QSize m_nativeSize; - bool m_enableOpenGL; - bool m_enableMetal; -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEORENDERERCONTROL_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm deleted file mode 100644 index 6e5b6a15e..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm +++ /dev/null @@ -1,301 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfvideorenderercontrol.h" -#include "avfdisplaylink.h" - -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) -#include "avfvideoframerenderer_ios.h" -#else -#include "avfvideoframerenderer.h" -#endif - -#include <QtMultimedia/qabstractvideobuffer.h> -#include <QtMultimedia/qabstractvideosurface.h> -#include <QtMultimedia/qvideosurfaceformat.h> - -#include <private/qimagevideobuffer_p.h> - -#include <QtCore/qdebug.h> - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -class TextureVideoBuffer : public QAbstractVideoBuffer -{ -public: - TextureVideoBuffer(HandleType type, quint64 tex) - : QAbstractVideoBuffer(type) - , m_texture(tex) - {} - - virtual ~TextureVideoBuffer() - { - } - - MapMode mapMode() const { return NotMapped; } - MapData map(MapMode mode) override { return {}; } - void unmap() {} - - QVariant handle() const - { - return QVariant::fromValue<unsigned long long>(m_texture); - } - -private: - quint64 m_texture; -}; - -AVFVideoRendererControl::AVFVideoRendererControl(QObject *parent) - : QVideoRendererControl(parent) - , m_surface(nullptr) - , m_playerLayer(nullptr) - , m_frameRenderer(nullptr) - , m_enableOpenGL(false) - , m_enableMetal(false) - -{ - m_displayLink = new AVFDisplayLink(this); - connect(m_displayLink, SIGNAL(tick(CVTimeStamp)), SLOT(updateVideoFrame(CVTimeStamp))); -} - -AVFVideoRendererControl::~AVFVideoRendererControl() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - m_displayLink->stop(); - [static_cast<AVPlayerLayer*>(m_playerLayer) release]; -} - -QAbstractVideoSurface *AVFVideoRendererControl::surface() const -{ - return m_surface; -} - -void AVFVideoRendererControl::setSurface(QAbstractVideoSurface *surface) -{ -#ifdef QT_DEBUG_AVF - qDebug() << "Set video surface" << surface; -#endif - - //When we have a valid surface, we can setup a frame renderer - //and schedule surface updates with the display link. - if (surface == m_surface) - return; - - QMutexLocker locker(&m_mutex); - - if (m_surface && m_surface->isActive()) - m_surface->stop(); - - m_surface = surface; - - //If the surface changed, then the current frame renderer is no longer valid - delete m_frameRenderer; - m_frameRenderer = nullptr; - - //If there is now no surface to render too - if (m_surface == nullptr) { - m_displayLink->stop(); - return; - } - - //Surface changed, so we need a new frame renderer - m_frameRenderer = new AVFVideoFrameRenderer(m_surface, this); -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - if (m_playerLayer) { - m_frameRenderer->setPlayerLayer(static_cast<AVPlayerLayer*>(m_playerLayer)); - } -#endif - - auto checkHandleType = [this] { - m_enableOpenGL = m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).contains(QVideoFrame::Format_BGR32); - m_enableMetal = m_surface->supportedPixelFormats(QAbstractVideoBuffer::MTLTextureHandle).contains(QVideoFrame::Format_BGR32); - }; - checkHandleType(); - connect(m_surface, &QAbstractVideoSurface::supportedFormatsChanged, this, checkHandleType); - - //If we already have a layer, but changed surfaces start rendering again - if (m_playerLayer && !m_displayLink->isActive()) { - m_displayLink->start(); - } - -} - -void AVFVideoRendererControl::setLayer(void *playerLayer) -{ - if (m_playerLayer == playerLayer) - return; - - [static_cast<AVPlayerLayer*>(m_playerLayer) release]; - - m_playerLayer = [static_cast<AVPlayerLayer*>(playerLayer) retain]; - - //If there is an active surface, make sure it has been stopped so that - //we can update it's state with the new content. - if (m_surface && m_surface->isActive()) - m_surface->stop(); - -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - if (m_frameRenderer) { - m_frameRenderer->setPlayerLayer(static_cast<AVPlayerLayer*>(playerLayer)); - } -#endif - - //If there is no layer to render, stop scheduling updates - if (m_playerLayer == nullptr) { - m_displayLink->stop(); - return; - } - - setupVideoOutput(); - - //If we now have both a valid surface and layer, start scheduling updates - if (m_surface && !m_displayLink->isActive()) { - m_displayLink->start(); - } -} - -void AVFVideoRendererControl::updateVideoFrame(const CVTimeStamp &ts) -{ - Q_UNUSED(ts); - - AVPlayerLayer *playerLayer = static_cast<AVPlayerLayer*>(m_playerLayer); - - if (!playerLayer) { - qWarning("updateVideoFrame called without AVPlayerLayer (which shouldn't happen"); - return; - } - - if (!playerLayer.readyForDisplay || !m_surface) - return; - - if (m_enableMetal) { - quint64 tex = m_frameRenderer->renderLayerToMTLTexture(playerLayer); - if (tex == 0) - return; - - auto buffer = new TextureVideoBuffer(QAbstractVideoBuffer::MTLTextureHandle, tex); - QVideoFrame frame(buffer, m_nativeSize, QVideoFrame::Format_BGR32); - if (m_surface->isActive() && m_surface->surfaceFormat().pixelFormat() != frame.pixelFormat()) - m_surface->stop(); - - if (!m_surface->isActive()) { - QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), QAbstractVideoBuffer::MTLTextureHandle); -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - format.setScanLineDirection(QVideoSurfaceFormat::TopToBottom); -#else - format.setScanLineDirection(QVideoSurfaceFormat::BottomToTop); -#endif - if (!m_surface->start(format)) - qWarning("Failed to activate video surface"); - } - - if (m_surface->isActive()) - m_surface->present(frame); - - return; - } - - if (m_enableOpenGL) { - quint64 tex = m_frameRenderer->renderLayerToTexture(playerLayer); - //Make sure we got a valid texture - if (tex == 0) - return; - - QAbstractVideoBuffer *buffer = new TextureVideoBuffer(QAbstractVideoBuffer::GLTextureHandle, tex); - QVideoFrame frame = QVideoFrame(buffer, m_nativeSize, QVideoFrame::Format_BGR32); - - if (m_surface && frame.isValid()) { - if (m_surface->isActive() && m_surface->surfaceFormat().pixelFormat() != frame.pixelFormat()) - m_surface->stop(); - - if (!m_surface->isActive()) { - QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), QAbstractVideoBuffer::GLTextureHandle); -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - format.setScanLineDirection(QVideoSurfaceFormat::TopToBottom); -#else - format.setScanLineDirection(QVideoSurfaceFormat::BottomToTop); -#endif - if (!m_surface->start(format)) { - //Surface doesn't support GLTextureHandle - qWarning("Failed to activate video surface"); - } - } - - if (m_surface->isActive()) - m_surface->present(frame); - } - } else { - //fallback to rendering frames to QImages - QImage frameData = m_frameRenderer->renderLayerToImage(playerLayer); - - if (frameData.isNull()) { - return; - } - - QAbstractVideoBuffer *buffer = new QImageVideoBuffer(frameData); - QVideoFrame frame = QVideoFrame(buffer, m_nativeSize, QVideoFrame::Format_ARGB32); - if (m_surface && frame.isValid()) { - if (m_surface->isActive() && m_surface->surfaceFormat().pixelFormat() != frame.pixelFormat()) - m_surface->stop(); - - if (!m_surface->isActive()) { - QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), QAbstractVideoBuffer::NoHandle); - - if (!m_surface->start(format)) { - qWarning("Failed to activate video surface"); - } - } - - if (m_surface->isActive()) - m_surface->present(frame); - } - - } -} - -void AVFVideoRendererControl::setupVideoOutput() -{ - AVPlayerLayer *playerLayer = static_cast<AVPlayerLayer*>(m_playerLayer); - if (playerLayer) - m_nativeSize = QSize(playerLayer.bounds.size.width, playerLayer.bounds.size.height); -} diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidget.h b/src/plugins/avfoundation/mediaplayer/avfvideowidget.h deleted file mode 100644 index faf71f1a4..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideowidget.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFVIDEOWIDGET_H -#define AVFVIDEOWIDGET_H - -#include <QtWidgets/QWidget> - -@class AVPlayerLayer; -#if defined(Q_OS_OSX) -@class NSView; -#else -@class UIView; -#endif - -QT_BEGIN_NAMESPACE - -class AVFVideoWidget : public QWidget -{ -public: - AVFVideoWidget(QWidget *parent); - virtual ~AVFVideoWidget(); - - QSize sizeHint() const override; - Qt::AspectRatioMode aspectRatioMode() const; - void setAspectRatioMode(Qt::AspectRatioMode mode); - void setPlayerLayer(AVPlayerLayer *layer); - -protected: - void resizeEvent(QResizeEvent *) override; - void paintEvent(QPaintEvent *) override; - -private: - void updateAspectRatio(); - void updatePlayerLayerBounds(const QSize &size); - - QSize m_nativeSize; - Qt::AspectRatioMode m_aspectRatioMode; - AVPlayerLayer *m_playerLayer; -#if defined(Q_OS_OSX) - NSView *m_nativeView; -#else - UIView *m_nativeView; -#endif -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEOWIDGET_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm b/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm deleted file mode 100644 index 0987342b4..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm +++ /dev/null @@ -1,187 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfvideowidget.h" - -#import <AVFoundation/AVFoundation.h> -#import <QuartzCore/CATransaction.h> - -#if defined(Q_OS_MACOS) -#import <AppKit/AppKit.h> -#else -#import <UIKit/UIKit.h> -#endif - -#include <QtCore/QDebug> -#include <QtGui/QResizeEvent> -#include <QtGui/QPaintEvent> -#include <QtGui/QPainter> - -QT_USE_NAMESPACE - -AVFVideoWidget::AVFVideoWidget(QWidget *parent) - : QWidget(parent) - , m_aspectRatioMode(Qt::KeepAspectRatio) - , m_playerLayer(nullptr) - , m_nativeView(nullptr) -{ - setAutoFillBackground(false); -} - -AVFVideoWidget::~AVFVideoWidget() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - - if (m_playerLayer) { - [m_playerLayer removeFromSuperlayer]; - [m_playerLayer release]; - } -} - -QSize AVFVideoWidget::sizeHint() const -{ - return m_nativeSize; -} - -Qt::AspectRatioMode AVFVideoWidget::aspectRatioMode() const -{ - return m_aspectRatioMode; -} - -void AVFVideoWidget::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - if (m_aspectRatioMode != mode) { - m_aspectRatioMode = mode; - - updateAspectRatio(); - } -} - -void AVFVideoWidget::setPlayerLayer(AVPlayerLayer *layer) -{ - if (m_playerLayer == layer) - return; - - if (!m_nativeView) { - //make video widget a native window -#if defined(Q_OS_OSX) - m_nativeView = (NSView*)this->winId(); - [m_nativeView setWantsLayer:YES]; -#else - m_nativeView = (UIView*)this->winId(); -#endif - } - - if (m_playerLayer) { - [m_playerLayer removeFromSuperlayer]; - [m_playerLayer release]; - } - - m_playerLayer = layer; - - CALayer *nativeLayer = [m_nativeView layer]; - - if (layer) { - [layer retain]; - - m_nativeSize = QSize(m_playerLayer.bounds.size.width, - m_playerLayer.bounds.size.height); - - updateAspectRatio(); - [nativeLayer addSublayer:m_playerLayer]; - updatePlayerLayerBounds(this->size()); - } -#ifdef QT_DEBUG_AVF - NSArray *sublayers = [nativeLayer sublayers]; - qDebug() << "playerlayer: " << "at z:" << [m_playerLayer zPosition] - << " frame: " << m_playerLayer.frame.size.width << "x" << m_playerLayer.frame.size.height; - qDebug() << "superlayer: " << "at z:" << [nativeLayer zPosition] - << " frame: " << nativeLayer.frame.size.width << "x" << nativeLayer.frame.size.height; - int i = 0; - for (CALayer *layer in sublayers) { - qDebug() << "layer " << i << ": at z:" << [layer zPosition] - << " frame: " << layer.frame.size.width << "x" << layer.frame.size.height; - i++; - } -#endif - -} - -void AVFVideoWidget::resizeEvent(QResizeEvent *event) -{ - updatePlayerLayerBounds(event->size()); - QWidget::resizeEvent(event); -} - -void AVFVideoWidget::paintEvent(QPaintEvent *event) -{ - QPainter painter(this); - painter.fillRect(rect(), Qt::black); - - QWidget::paintEvent(event); -} - -void AVFVideoWidget::updateAspectRatio() -{ - if (m_playerLayer) { - switch (m_aspectRatioMode) { - case Qt::IgnoreAspectRatio: - [m_playerLayer setVideoGravity:AVLayerVideoGravityResize]; - break; - case Qt::KeepAspectRatio: - [m_playerLayer setVideoGravity:AVLayerVideoGravityResizeAspect]; - break; - case Qt::KeepAspectRatioByExpanding: - [m_playerLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; - break; - default: - break; - } - } -} - -void AVFVideoWidget::updatePlayerLayerBounds(const QSize &size) -{ - [CATransaction begin]; - [CATransaction setDisableActions: YES]; // disable animation/flicks - m_playerLayer.bounds = QRect(QPoint(0, 0), size).toCGRect(); - [CATransaction commit]; -} diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.h b/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.h deleted file mode 100644 index 22379d273..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFVIDEOWIDGETCONTROL_H -#define AVFVIDEOWIDGETCONTROL_H - -#include <qvideowidgetcontrol.h> -#include "avfvideooutput.h" - -@class AVPlayerLayer; - -QT_BEGIN_NAMESPACE - -class AVFVideoWidget; - -class AVFVideoWidgetControl : public QVideoWidgetControl, public AVFVideoOutput -{ - Q_OBJECT - Q_INTERFACES(AVFVideoOutput) -public: - AVFVideoWidgetControl(QObject *parent = nullptr); - virtual ~AVFVideoWidgetControl(); - - void setLayer(void *playerLayer) override; - - QWidget *videoWidget() override; - - bool isFullScreen() const override; - void setFullScreen(bool fullScreen) override; - - Qt::AspectRatioMode aspectRatioMode() const override; - void setAspectRatioMode(Qt::AspectRatioMode mode) override; - - int brightness() const override; - void setBrightness(int brightness) override; - - int contrast() const override; - void setContrast(int contrast) override; - - int hue() const override; - void setHue(int hue) override; - - int saturation() const override; - void setSaturation(int saturation) override; - -private: - AVFVideoWidget *m_videoWidget; - - bool m_fullscreen; - int m_brightness; - int m_contrast; - int m_hue; - int m_saturation; - -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEOWIDGETCONTROL_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm deleted file mode 100644 index 91ece817e..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfvideowidgetcontrol.h" -#include "avfvideowidget.h" - -#ifdef QT_DEBUG_AVF -#include <QtCore/QDebug> -#endif - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -AVFVideoWidgetControl::AVFVideoWidgetControl(QObject *parent) - : QVideoWidgetControl(parent) - , m_fullscreen(false) - , m_brightness(0) - , m_contrast(0) - , m_hue(0) - , m_saturation(0) -{ - m_videoWidget = new AVFVideoWidget(nullptr); -} - -AVFVideoWidgetControl::~AVFVideoWidgetControl() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - delete m_videoWidget; -} - -void AVFVideoWidgetControl::setLayer(void *playerLayer) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << playerLayer; -#endif - - m_videoWidget->setPlayerLayer(static_cast<AVPlayerLayer*>(playerLayer)); - -} - -QWidget *AVFVideoWidgetControl::videoWidget() -{ - return m_videoWidget; -} - -bool AVFVideoWidgetControl::isFullScreen() const -{ - return m_fullscreen; -} - -void AVFVideoWidgetControl::setFullScreen(bool fullScreen) -{ - m_fullscreen = fullScreen; -} - -Qt::AspectRatioMode AVFVideoWidgetControl::aspectRatioMode() const -{ - return m_videoWidget->aspectRatioMode(); -} - -void AVFVideoWidgetControl::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - m_videoWidget->setAspectRatioMode(mode); -} - -int AVFVideoWidgetControl::brightness() const -{ - return m_brightness; -} - -void AVFVideoWidgetControl::setBrightness(int brightness) -{ - m_brightness = brightness; -} - -int AVFVideoWidgetControl::contrast() const -{ - return m_contrast; -} - -void AVFVideoWidgetControl::setContrast(int contrast) -{ - m_contrast = contrast; -} - -int AVFVideoWidgetControl::hue() const -{ - return m_hue; -} - -void AVFVideoWidgetControl::setHue(int hue) -{ - m_hue = hue; -} - -int AVFVideoWidgetControl::saturation() const -{ - return m_saturation; -} - -void AVFVideoWidgetControl::setSaturation(int saturation) -{ - m_saturation = saturation; -} - -#include "moc_avfvideowidgetcontrol.cpp" diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.h b/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.h deleted file mode 100644 index 763656c6c..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AVFVIDEOWINDOWCONTROL_H -#define AVFVIDEOWINDOWCONTROL_H - -#include <QVideoWindowControl> - -@class AVPlayerLayer; -#if defined(Q_OS_OSX) -@class NSView; -typedef NSView NativeView; -#else -@class UIView; -typedef UIView NativeView; -#endif - -#include "avfvideooutput.h" - -QT_BEGIN_NAMESPACE - -class AVFVideoWindowControl : public QVideoWindowControl, public AVFVideoOutput -{ - Q_OBJECT - Q_INTERFACES(AVFVideoOutput) - -public: - AVFVideoWindowControl(QObject *parent = nullptr); - virtual ~AVFVideoWindowControl(); - - // QVideoWindowControl interface -public: - WId winId() const override; - void setWinId(WId id) override; - - QRect displayRect() const override; - void setDisplayRect(const QRect &rect) override; - - bool isFullScreen() const override; - void setFullScreen(bool fullScreen) override; - - void repaint() override; - QSize nativeSize() const override; - - Qt::AspectRatioMode aspectRatioMode() const override; - void setAspectRatioMode(Qt::AspectRatioMode mode) override; - - int brightness() const override; - void setBrightness(int brightness) override; - - int contrast() const override; - void setContrast(int contrast) override; - - int hue() const override; - void setHue(int hue) override; - - int saturation() const override; - void setSaturation(int saturation) override; - - // AVFVideoOutput interface - void setLayer(void *playerLayer) override; - -private: - void updateAspectRatio(); - void updatePlayerLayerBounds(); - - WId m_winId; - QRect m_displayRect; - bool m_fullscreen; - int m_brightness; - int m_contrast; - int m_hue; - int m_saturation; - Qt::AspectRatioMode m_aspectRatioMode; - QSize m_nativeSize; - AVPlayerLayer *m_playerLayer; - NativeView *m_nativeView; -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEOWINDOWCONTROL_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm deleted file mode 100644 index d61129ec9..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm +++ /dev/null @@ -1,255 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfvideowindowcontrol.h" - -#include <AVFoundation/AVFoundation.h> -#import <QuartzCore/CATransaction.h> - -#if QT_HAS_INCLUDE(<AppKit/AppKit.h>) -#include <AppKit/AppKit.h> -#endif - -#if QT_HAS_INCLUDE(<UIKit/UIKit.h>) -#include <UIKit/UIKit.h> -#endif - -QT_USE_NAMESPACE - -AVFVideoWindowControl::AVFVideoWindowControl(QObject *parent) - : QVideoWindowControl(parent) - , m_winId(0) - , m_fullscreen(false) - , m_brightness(0) - , m_contrast(0) - , m_hue(0) - , m_saturation(0) - , m_aspectRatioMode(Qt::IgnoreAspectRatio) - , m_playerLayer(nullptr) - , m_nativeView(nullptr) -{ -} - -AVFVideoWindowControl::~AVFVideoWindowControl() -{ - if (m_playerLayer) { - [m_playerLayer removeFromSuperlayer]; - [m_playerLayer release]; - } -} - -WId AVFVideoWindowControl::winId() const -{ - return m_winId; -} - -void AVFVideoWindowControl::setWinId(WId id) -{ - m_winId = id; - m_nativeView = (NativeView*)m_winId; -} - -QRect AVFVideoWindowControl::displayRect() const -{ - return m_displayRect; -} - -void AVFVideoWindowControl::setDisplayRect(const QRect &rect) -{ - if (m_displayRect != rect) { - m_displayRect = rect; - updatePlayerLayerBounds(); - } -} - -bool AVFVideoWindowControl::isFullScreen() const -{ - return m_fullscreen; -} - -void AVFVideoWindowControl::setFullScreen(bool fullScreen) -{ - if (m_fullscreen != fullScreen) { - m_fullscreen = fullScreen; - Q_EMIT QVideoWindowControl::fullScreenChanged(fullScreen); - } -} - -void AVFVideoWindowControl::repaint() -{ - if (m_playerLayer) - [m_playerLayer setNeedsDisplay]; -} - -QSize AVFVideoWindowControl::nativeSize() const -{ - return m_nativeSize; -} - -Qt::AspectRatioMode AVFVideoWindowControl::aspectRatioMode() const -{ - return m_aspectRatioMode; -} - -void AVFVideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - if (m_aspectRatioMode != mode) { - m_aspectRatioMode = mode; - updateAspectRatio(); - } -} - -int AVFVideoWindowControl::brightness() const -{ - return m_brightness; -} - -void AVFVideoWindowControl::setBrightness(int brightness) -{ - if (m_brightness != brightness) { - m_brightness = brightness; - Q_EMIT QVideoWindowControl::brightnessChanged(brightness); - } -} - -int AVFVideoWindowControl::contrast() const -{ - return m_contrast; -} - -void AVFVideoWindowControl::setContrast(int contrast) -{ - if (m_contrast != contrast) { - m_contrast = contrast; - Q_EMIT QVideoWindowControl::contrastChanged(contrast); - } -} - -int AVFVideoWindowControl::hue() const -{ - return m_hue; -} - -void AVFVideoWindowControl::setHue(int hue) -{ - if (m_hue != hue) { - m_hue = hue; - Q_EMIT QVideoWindowControl::hueChanged(hue); - } -} - -int AVFVideoWindowControl::saturation() const -{ - return m_saturation; -} - -void AVFVideoWindowControl::setSaturation(int saturation) -{ - if (m_saturation != saturation) { - m_saturation = saturation; - Q_EMIT QVideoWindowControl::saturationChanged(saturation); - } -} - -void AVFVideoWindowControl::setLayer(void *playerLayer) -{ - AVPlayerLayer *layer = static_cast<AVPlayerLayer*>(playerLayer); - if (m_playerLayer == layer) - return; - - if (!m_winId) { - qDebug("AVFVideoWindowControl: No video window"); - return; - } - -#if defined(Q_OS_OSX) - [m_nativeView setWantsLayer:YES]; -#endif - - if (m_playerLayer) { - [m_playerLayer removeFromSuperlayer]; - [m_playerLayer release]; - } - - m_playerLayer = layer; - - CALayer *nativeLayer = [m_nativeView layer]; - - if (layer) { - [layer retain]; - - m_nativeSize = QSize(m_playerLayer.bounds.size.width, - m_playerLayer.bounds.size.height); - - updateAspectRatio(); - [nativeLayer addSublayer:m_playerLayer]; - updatePlayerLayerBounds(); - } -} - -void AVFVideoWindowControl::updateAspectRatio() -{ - if (m_playerLayer) { - switch (m_aspectRatioMode) { - case Qt::IgnoreAspectRatio: - [m_playerLayer setVideoGravity:AVLayerVideoGravityResize]; - break; - case Qt::KeepAspectRatio: - [m_playerLayer setVideoGravity:AVLayerVideoGravityResizeAspect]; - break; - case Qt::KeepAspectRatioByExpanding: - [m_playerLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; - break; - default: - break; - } - } -} - -void AVFVideoWindowControl::updatePlayerLayerBounds() -{ - if (m_playerLayer) { - [CATransaction begin]; - [CATransaction setDisableActions: YES]; // disable animation/flicks - m_playerLayer.frame = m_displayRect.toCGRect(); - [CATransaction commit]; - } -} - -#include "moc_avfvideowindowcontrol.cpp" diff --git a/src/plugins/avfoundation/mediaplayer/mediaplayer.pro b/src/plugins/avfoundation/mediaplayer/mediaplayer.pro deleted file mode 100644 index 604866058..000000000 --- a/src/plugins/avfoundation/mediaplayer/mediaplayer.pro +++ /dev/null @@ -1,76 +0,0 @@ -TARGET = qavfmediaplayer - -#DEFINES += QT_DEBUG_AVF -# Avoid clash with a variable named `slots' in a Quartz header -CONFIG += no_keywords - -QT += opengl multimedia-private network - -LIBS += -framework CoreMedia -framework CoreVideo -framework QuartzCore -framework Metal - -QMAKE_USE += avfoundation - -HEADERS += \ - avfmediaplayercontrol.h \ - avfmediaplayermetadatacontrol.h \ - avfmediaplayerservice.h \ - avfmediaplayersession.h \ - avfmediaplayerserviceplugin.h \ - avfvideooutput.h \ - avfvideowindowcontrol.h - -OBJECTIVE_SOURCES += \ - avfmediaplayercontrol.mm \ - avfmediaplayermetadatacontrol.mm \ - avfmediaplayerservice.mm \ - avfmediaplayerserviceplugin.mm \ - avfmediaplayersession.mm \ - avfvideooutput.mm \ - avfvideowindowcontrol.mm - - qtHaveModule(widgets) { - QT += multimediawidgets-private - HEADERS += \ - avfvideowidgetcontrol.h \ - avfvideowidget.h - - OBJECTIVE_SOURCES += \ - avfvideowidgetcontrol.mm \ - avfvideowidget.mm - } - -ios|tvos { - qtConfig(opengl) { - HEADERS += \ - avfvideoframerenderer_ios.h \ - avfvideorenderercontrol.h \ - avfdisplaylink.h - - OBJECTIVE_SOURCES += \ - avfvideoframerenderer_ios.mm \ - avfvideorenderercontrol.mm \ - avfdisplaylink.mm - } - LIBS += -framework Foundation -} else { - LIBS += -framework AppKit - - qtConfig(opengl) { - HEADERS += \ - avfvideoframerenderer.h \ - avfvideorenderercontrol.h \ - avfdisplaylink.h - - OBJECTIVE_SOURCES += \ - avfvideoframerenderer.mm \ - avfvideorenderercontrol.mm \ - avfdisplaylink.mm - } -} - -OTHER_FILES += \ - avfmediaplayer.json - -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = AVFMediaPlayerServicePlugin -load(qt_plugin) diff --git a/src/plugins/common/evr.pri b/src/plugins/common/evr.pri deleted file mode 100644 index 2a1b383df..000000000 --- a/src/plugins/common/evr.pri +++ /dev/null @@ -1,20 +0,0 @@ -INCLUDEPATH += $$PWD/evr - -qtHaveModule(widgets): QT += widgets -QT += gui-private - -LIBS += -lmf -lmfplat -lmfuuid -ld3d9 -ldxva2 -lwinmm -levr - -HEADERS += \ - $$PWD/evr/evrvideowindowcontrol.h \ - $$PWD/evr/evrcustompresenter.h \ - $$PWD/evr/evrd3dpresentengine.h \ - $$PWD/evr/evrhelpers.h \ - $$PWD/evr/evrdefs.h - -SOURCES += \ - $$PWD/evr/evrvideowindowcontrol.cpp \ - $$PWD/evr/evrcustompresenter.cpp \ - $$PWD/evr/evrd3dpresentengine.cpp \ - $$PWD/evr/evrhelpers.cpp \ - $$PWD/evr/evrdefs.cpp diff --git a/src/plugins/common/evr/evrcustompresenter.cpp b/src/plugins/common/evr/evrcustompresenter.cpp deleted file mode 100644 index b2dd0426c..000000000 --- a/src/plugins/common/evr/evrcustompresenter.cpp +++ /dev/null @@ -1,2062 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "evrcustompresenter.h" - -#include "evrd3dpresentengine.h" -#include "evrhelpers.h" - -#include <QtCore/qmutex.h> -#include <QtCore/qvarlengtharray.h> -#include <QtCore/qrect.h> -#include <qabstractvideosurface.h> -#include <qthread.h> -#include <qcoreapplication.h> -#include <qmath.h> -#include <QtCore/qdebug.h> - -#include <mutex> - -#include <float.h> -#include <evcode.h> - -QT_BEGIN_NAMESPACE - -const static MFRatio g_DefaultFrameRate = { 30, 1 }; -static const DWORD SCHEDULER_TIMEOUT = 5000; -static const MFTIME ONE_SECOND = 10000000; -static const LONG ONE_MSEC = 1000; - -// Function declarations. -static HRESULT setDesiredSampleTime(IMFSample *sample, const LONGLONG& hnsSampleTime, const LONGLONG& hnsDuration); -static HRESULT clearDesiredSampleTime(IMFSample *sample); -static HRESULT setMixerSourceRect(IMFTransform *mixer, const MFVideoNormalizedRect& nrcSource); -static QVideoFrame::PixelFormat pixelFormatFromMediaType(IMFMediaType *type); - -static inline LONG MFTimeToMsec(const LONGLONG& time) -{ - return (LONG)(time / (ONE_SECOND / ONE_MSEC)); -} - -bool qt_evr_setCustomPresenter(IUnknown *evr, EVRCustomPresenter *presenter) -{ - if (!evr || !presenter) - return false; - - HRESULT result = E_FAIL; - - IMFVideoRenderer *renderer = NULL; - if (SUCCEEDED(evr->QueryInterface(IID_PPV_ARGS(&renderer)))) { - result = renderer->InitializeRenderer(NULL, presenter); - renderer->Release(); - } - - return result == S_OK; -} - -class PresentSampleEvent : public QEvent -{ -public: - PresentSampleEvent(IMFSample *sample) - : QEvent(QEvent::Type(EVRCustomPresenter::PresentSample)) - , m_sample(sample) - { - if (m_sample) - m_sample->AddRef(); - } - - ~PresentSampleEvent() override - { - if (m_sample) - m_sample->Release(); - } - - IMFSample *sample() const { return m_sample; } - -private: - IMFSample *m_sample; -}; - -Scheduler::Scheduler(EVRCustomPresenter *presenter) - : m_presenter(presenter) - , m_clock(NULL) - , m_threadID(0) - , m_schedulerThread(0) - , m_threadReadyEvent(0) - , m_flushEvent(0) - , m_playbackRate(1.0f) - , m_perFrameInterval(0) - , m_perFrame_1_4th(0) - , m_lastSampleTime(0) -{ -} - -Scheduler::~Scheduler() -{ - qt_evr_safe_release(&m_clock); - for (int i = 0; i < m_scheduledSamples.size(); ++i) - m_scheduledSamples[i]->Release(); - m_scheduledSamples.clear(); -} - -void Scheduler::setFrameRate(const MFRatio& fps) -{ - UINT64 AvgTimePerFrame = 0; - - // Convert to a duration. - MFFrameRateToAverageTimePerFrame(fps.Numerator, fps.Denominator, &AvgTimePerFrame); - - m_perFrameInterval = (MFTIME)AvgTimePerFrame; - - // Calculate 1/4th of this value, because we use it frequently. - m_perFrame_1_4th = m_perFrameInterval / 4; -} - -HRESULT Scheduler::startScheduler(IMFClock *clock) -{ - if (m_schedulerThread) - return E_UNEXPECTED; - - HRESULT hr = S_OK; - DWORD dwID = 0; - HANDLE hObjects[2]; - DWORD dwWait = 0; - - if (m_clock) - m_clock->Release(); - m_clock = clock; - if (m_clock) - m_clock->AddRef(); - - // Set a high the timer resolution (ie, short timer period). - timeBeginPeriod(1); - - // Create an event to wait for the thread to start. - m_threadReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - if (!m_threadReadyEvent) { - hr = HRESULT_FROM_WIN32(GetLastError()); - goto done; - } - - // Create an event to wait for flush commands to complete. - m_flushEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - if (!m_flushEvent) { - hr = HRESULT_FROM_WIN32(GetLastError()); - goto done; - } - - // Create the scheduler thread. - m_schedulerThread = CreateThread(NULL, 0, schedulerThreadProc, (LPVOID)this, 0, &dwID); - if (!m_schedulerThread) { - hr = HRESULT_FROM_WIN32(GetLastError()); - goto done; - } - - // Wait for the thread to signal the "thread ready" event. - hObjects[0] = m_threadReadyEvent; - hObjects[1] = m_schedulerThread; - dwWait = WaitForMultipleObjects(2, hObjects, FALSE, INFINITE); // Wait for EITHER of these handles. - if (WAIT_OBJECT_0 != dwWait) { - // The thread terminated early for some reason. This is an error condition. - CloseHandle(m_schedulerThread); - m_schedulerThread = NULL; - - hr = E_UNEXPECTED; - goto done; - } - - m_threadID = dwID; - -done: - // Regardless success/failure, we are done using the "thread ready" event. - if (m_threadReadyEvent) { - CloseHandle(m_threadReadyEvent); - m_threadReadyEvent = NULL; - } - return hr; -} - -HRESULT Scheduler::stopScheduler() -{ - if (!m_schedulerThread) - return S_OK; - - // Ask the scheduler thread to exit. - PostThreadMessage(m_threadID, Terminate, 0, 0); - - // Wait for the thread to exit. - WaitForSingleObject(m_schedulerThread, INFINITE); - - // Close handles. - CloseHandle(m_schedulerThread); - m_schedulerThread = NULL; - - CloseHandle(m_flushEvent); - m_flushEvent = NULL; - - // Discard samples. - m_mutex.lock(); - for (int i = 0; i < m_scheduledSamples.size(); ++i) - m_scheduledSamples[i]->Release(); - m_scheduledSamples.clear(); - m_mutex.unlock(); - - // Restore the timer resolution. - timeEndPeriod(1); - - return S_OK; -} - -HRESULT Scheduler::flush() -{ - if (m_schedulerThread) { - // Ask the scheduler thread to flush. - PostThreadMessage(m_threadID, Flush, 0 , 0); - - // Wait for the scheduler thread to signal the flush event, - // OR for the thread to terminate. - HANDLE objects[] = { m_flushEvent, m_schedulerThread }; - - WaitForMultipleObjects(ARRAYSIZE(objects), objects, FALSE, SCHEDULER_TIMEOUT); - } - - return S_OK; -} - -bool Scheduler::areSamplesScheduled() -{ - QMutexLocker locker(&m_mutex); - return m_scheduledSamples.count() > 0; -} - -HRESULT Scheduler::scheduleSample(IMFSample *sample, bool presentNow) -{ - if (!m_schedulerThread) - return MF_E_NOT_INITIALIZED; - - HRESULT hr = S_OK; - DWORD dwExitCode = 0; - - GetExitCodeThread(m_schedulerThread, &dwExitCode); - if (dwExitCode != STILL_ACTIVE) - return E_FAIL; - - if (presentNow || !m_clock) { - m_presenter->presentSample(sample); - } else { - // Queue the sample and ask the scheduler thread to wake up. - m_mutex.lock(); - sample->AddRef(); - m_scheduledSamples.enqueue(sample); - m_mutex.unlock(); - - if (SUCCEEDED(hr)) - PostThreadMessage(m_threadID, Schedule, 0, 0); - } - - return hr; -} - -HRESULT Scheduler::processSamplesInQueue(LONG *nextSleep) -{ - HRESULT hr = S_OK; - LONG wait = 0; - IMFSample *sample = NULL; - - // Process samples until the queue is empty or until the wait time > 0. - while (!m_scheduledSamples.isEmpty()) { - m_mutex.lock(); - sample = m_scheduledSamples.dequeue(); - m_mutex.unlock(); - - // Process the next sample in the queue. If the sample is not ready - // for presentation. the value returned in wait is > 0, which - // means the scheduler should sleep for that amount of time. - - hr = processSample(sample, &wait); - qt_evr_safe_release(&sample); - - if (FAILED(hr) || wait > 0) - break; - } - - // If the wait time is zero, it means we stopped because the queue is - // empty (or an error occurred). Set the wait time to infinite; this will - // make the scheduler thread sleep until it gets another thread message. - if (wait == 0) - wait = INFINITE; - - *nextSleep = wait; - return hr; -} - -HRESULT Scheduler::processSample(IMFSample *sample, LONG *pNextSleep) -{ - HRESULT hr = S_OK; - - LONGLONG hnsPresentationTime = 0; - LONGLONG hnsTimeNow = 0; - MFTIME hnsSystemTime = 0; - - bool presentNow = true; - LONG nextSleep = 0; - - if (m_clock) { - // Get the sample's time stamp. It is valid for a sample to - // have no time stamp. - hr = sample->GetSampleTime(&hnsPresentationTime); - - // Get the clock time. (But if the sample does not have a time stamp, - // we don't need the clock time.) - if (SUCCEEDED(hr)) - hr = m_clock->GetCorrelatedTime(0, &hnsTimeNow, &hnsSystemTime); - - // Calculate the time until the sample's presentation time. - // A negative value means the sample is late. - LONGLONG hnsDelta = hnsPresentationTime - hnsTimeNow; - if (m_playbackRate < 0) { - // For reverse playback, the clock runs backward. Therefore, the - // delta is reversed. - hnsDelta = - hnsDelta; - } - - if (hnsDelta < - m_perFrame_1_4th) { - // This sample is late. - presentNow = true; - } else if (hnsDelta > (3 * m_perFrame_1_4th)) { - // This sample is still too early. Go to sleep. - nextSleep = MFTimeToMsec(hnsDelta - (3 * m_perFrame_1_4th)); - - // Adjust the sleep time for the clock rate. (The presentation clock runs - // at m_fRate, but sleeping uses the system clock.) - if (m_playbackRate != 0) - nextSleep = (LONG)(nextSleep / qFabs(m_playbackRate)); - - // Don't present yet. - presentNow = false; - } - } - - if (presentNow) { - m_presenter->presentSample(sample); - } else { - // The sample is not ready yet. Return it to the queue. - m_mutex.lock(); - sample->AddRef(); - m_scheduledSamples.prepend(sample); - m_mutex.unlock(); - } - - *pNextSleep = nextSleep; - - return hr; -} - -DWORD WINAPI Scheduler::schedulerThreadProc(LPVOID parameter) -{ - Scheduler* scheduler = reinterpret_cast<Scheduler*>(parameter); - if (!scheduler) - return -1; - return scheduler->schedulerThreadProcPrivate(); -} - -DWORD Scheduler::schedulerThreadProcPrivate() -{ - HRESULT hr = S_OK; - MSG msg; - LONG wait = INFINITE; - bool exitThread = false; - - // Force the system to create a message queue for this thread. - // (See MSDN documentation for PostThreadMessage.) - PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); - - // Signal to the scheduler that the thread is ready. - SetEvent(m_threadReadyEvent); - - while (!exitThread) { - // Wait for a thread message OR until the wait time expires. - DWORD result = MsgWaitForMultipleObjects(0, NULL, FALSE, wait, QS_POSTMESSAGE); - - if (result == WAIT_TIMEOUT) { - // If we timed out, then process the samples in the queue - hr = processSamplesInQueue(&wait); - if (FAILED(hr)) - exitThread = true; - } - - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - bool processSamples = true; - - switch (msg.message) { - case Terminate: - exitThread = true; - break; - case Flush: - // Flushing: Clear the sample queue and set the event. - m_mutex.lock(); - for (int i = 0; i < m_scheduledSamples.size(); ++i) - m_scheduledSamples[i]->Release(); - m_scheduledSamples.clear(); - m_mutex.unlock(); - wait = INFINITE; - SetEvent(m_flushEvent); - break; - case Schedule: - // Process as many samples as we can. - if (processSamples) { - hr = processSamplesInQueue(&wait); - if (FAILED(hr)) - exitThread = true; - processSamples = (wait != (LONG)INFINITE); - } - break; - } - } - - } - - return (SUCCEEDED(hr) ? 0 : 1); -} - - -SamplePool::SamplePool() - : m_initialized(false) -{ -} - -SamplePool::~SamplePool() -{ - clear(); -} - -HRESULT SamplePool::getSample(IMFSample **sample) -{ - QMutexLocker locker(&m_mutex); - - if (!m_initialized) - return MF_E_NOT_INITIALIZED; - - if (m_videoSampleQueue.isEmpty()) - return MF_E_SAMPLEALLOCATOR_EMPTY; - - // Get a sample from the allocated queue. - - // It doesn't matter if we pull them from the head or tail of the list, - // but when we get it back, we want to re-insert it onto the opposite end. - // (see ReturnSample) - - IMFSample *taken = m_videoSampleQueue.takeFirst(); - - // Give the sample to the caller. - *sample = taken; - (*sample)->AddRef(); - - taken->Release(); - - return S_OK; -} - -HRESULT SamplePool::returnSample(IMFSample *sample) -{ - QMutexLocker locker(&m_mutex); - - if (!m_initialized) - return MF_E_NOT_INITIALIZED; - - m_videoSampleQueue.append(sample); - sample->AddRef(); - - return S_OK; -} - -HRESULT SamplePool::initialize(QList<IMFSample*> &samples) -{ - QMutexLocker locker(&m_mutex); - - if (m_initialized) - return MF_E_INVALIDREQUEST; - - // Move these samples into our allocated queue. - for (auto sample : qAsConst(samples)) { - sample->AddRef(); - m_videoSampleQueue.append(sample); - } - - m_initialized = true; - - for (auto sample : qAsConst(samples)) - sample->Release(); - samples.clear(); - return S_OK; -} - -HRESULT SamplePool::clear() -{ - QMutexLocker locker(&m_mutex); - - for (auto sample : qAsConst(m_videoSampleQueue)) - sample->Release(); - m_videoSampleQueue.clear(); - m_initialized = false; - - return S_OK; -} - - -EVRCustomPresenter::EVRCustomPresenter(QAbstractVideoSurface *surface) - : QObject() - , m_sampleFreeCB(this, &EVRCustomPresenter::onSampleFree) - , m_refCount(1) - , m_renderState(RenderShutdown) - , m_scheduler(this) - , m_tokenCounter(0) - , m_sampleNotify(false) - , m_repaint(false) - , m_prerolled(false) - , m_endStreaming(false) - , m_playbackRate(1.0f) - , m_presentEngine(new D3DPresentEngine) - , m_clock(0) - , m_mixer(0) - , m_mediaEventSink(0) - , m_mediaType(0) - , m_surface(0) - , m_canRenderToSurface(false) - , m_positionOffset(0) -{ - // Initial source rectangle = (0,0,1,1) - m_sourceRect.top = 0; - m_sourceRect.left = 0; - m_sourceRect.bottom = 1; - m_sourceRect.right = 1; - - setSurface(surface); -} - -EVRCustomPresenter::~EVRCustomPresenter() -{ - m_scheduler.flush(); - m_scheduler.stopScheduler(); - m_samplePool.clear(); - - qt_evr_safe_release(&m_clock); - qt_evr_safe_release(&m_mixer); - qt_evr_safe_release(&m_mediaEventSink); - qt_evr_safe_release(&m_mediaType); - - delete m_presentEngine; -} - -HRESULT EVRCustomPresenter::QueryInterface(REFIID riid, void ** ppvObject) -{ - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFGetService) { - *ppvObject = static_cast<IMFGetService*>(this); - } else if (riid == IID_IMFTopologyServiceLookupClient) { - *ppvObject = static_cast<IMFTopologyServiceLookupClient*>(this); - } else if (riid == IID_IMFVideoDeviceID) { - *ppvObject = static_cast<IMFVideoDeviceID*>(this); - } else if (riid == IID_IMFVideoPresenter) { - *ppvObject = static_cast<IMFVideoPresenter*>(this); - } else if (riid == IID_IMFRateSupport) { - *ppvObject = static_cast<IMFRateSupport*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(static_cast<IMFGetService*>(this)); - } else if (riid == IID_IMFClockStateSink) { - *ppvObject = static_cast<IMFClockStateSink*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -ULONG EVRCustomPresenter::AddRef() -{ - return InterlockedIncrement(&m_refCount); -} - -ULONG EVRCustomPresenter::Release() -{ - ULONG uCount = InterlockedDecrement(&m_refCount); - if (uCount == 0) - delete this; - return uCount; -} - -HRESULT EVRCustomPresenter::GetService(REFGUID guidService, REFIID riid, LPVOID *ppvObject) -{ - HRESULT hr = S_OK; - - if (!ppvObject) - return E_POINTER; - - // The only service GUID that we support is MR_VIDEO_RENDER_SERVICE. - if (guidService != mr_VIDEO_RENDER_SERVICE) - return MF_E_UNSUPPORTED_SERVICE; - - // First try to get the service interface from the D3DPresentEngine object. - hr = m_presentEngine->getService(guidService, riid, ppvObject); - if (FAILED(hr)) - // Next, check if this object supports the interface. - hr = QueryInterface(riid, ppvObject); - - return hr; -} - -HRESULT EVRCustomPresenter::GetDeviceID(IID* deviceID) -{ - if (!deviceID) - return E_POINTER; - - *deviceID = iid_IDirect3DDevice9; - - return S_OK; -} - -HRESULT EVRCustomPresenter::InitServicePointers(IMFTopologyServiceLookup *lookup) -{ - if (!lookup) - return E_POINTER; - - HRESULT hr = S_OK; - DWORD objectCount = 0; - - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - // Do not allow initializing when playing or paused. - if (isActive()) - return MF_E_INVALIDREQUEST; - - qt_evr_safe_release(&m_clock); - qt_evr_safe_release(&m_mixer); - qt_evr_safe_release(&m_mediaEventSink); - - // Ask for the clock. Optional, because the EVR might not have a clock. - objectCount = 1; - - lookup->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0, - mr_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_clock), - &objectCount - ); - - // Ask for the mixer. (Required.) - objectCount = 1; - - hr = lookup->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0, - mr_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_mixer), - &objectCount - ); - - if (FAILED(hr)) - return hr; - - // Make sure that we can work with this mixer. - hr = configureMixer(m_mixer); - if (FAILED(hr)) - return hr; - - // Ask for the EVR's event-sink interface. (Required.) - objectCount = 1; - - hr = lookup->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0, - mr_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_mediaEventSink), - &objectCount - ); - - if (SUCCEEDED(hr)) - m_renderState = RenderStopped; - - return hr; -} - -HRESULT EVRCustomPresenter::ReleaseServicePointers() -{ - // Enter the shut-down state. - m_mutex.lock(); - - m_renderState = RenderShutdown; - - m_mutex.unlock(); - - // Flush any samples that were scheduled. - flush(); - - // Clear the media type and release related resources. - setMediaType(NULL); - - // Release all services that were acquired from InitServicePointers. - qt_evr_safe_release(&m_clock); - qt_evr_safe_release(&m_mixer); - qt_evr_safe_release(&m_mediaEventSink); - - return S_OK; -} - -bool EVRCustomPresenter::isValid() const -{ - return m_presentEngine->isValid() && m_canRenderToSurface; -} - -HRESULT EVRCustomPresenter::ProcessMessage(MFVP_MESSAGE_TYPE message, ULONG_PTR param) -{ - HRESULT hr = S_OK; - - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - hr = checkShutdown(); - if (FAILED(hr)) - return hr; - - switch (message) { - // Flush all pending samples. - case MFVP_MESSAGE_FLUSH: - hr = flush(); - break; - - // Renegotiate the media type with the mixer. - case MFVP_MESSAGE_INVALIDATEMEDIATYPE: - hr = renegotiateMediaType(); - break; - - // The mixer received a new input sample. - case MFVP_MESSAGE_PROCESSINPUTNOTIFY: - hr = processInputNotify(); - break; - - // Streaming is about to start. - case MFVP_MESSAGE_BEGINSTREAMING: - hr = beginStreaming(); - break; - - // Streaming has ended. (The EVR has stopped.) - case MFVP_MESSAGE_ENDSTREAMING: - hr = endStreaming(); - break; - - // All input streams have ended. - case MFVP_MESSAGE_ENDOFSTREAM: - // Set the EOS flag. - m_endStreaming = true; - // Check if it's time to send the EC_COMPLETE event to the EVR. - hr = checkEndOfStream(); - break; - - // Frame-stepping is starting. - case MFVP_MESSAGE_STEP: - hr = prepareFrameStep(DWORD(param)); - break; - - // Cancels frame-stepping. - case MFVP_MESSAGE_CANCELSTEP: - hr = cancelFrameStep(); - break; - - default: - hr = E_INVALIDARG; // Unknown message. This case should never occur. - break; - } - - return hr; -} - -HRESULT EVRCustomPresenter::GetCurrentMediaType(IMFVideoMediaType **mediaType) -{ - HRESULT hr = S_OK; - - if (!mediaType) - return E_POINTER; - - *mediaType = NULL; - - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - hr = checkShutdown(); - if (FAILED(hr)) - return hr; - - if (!m_mediaType) - return MF_E_NOT_INITIALIZED; - - return m_mediaType->QueryInterface(IID_PPV_ARGS(mediaType)); -} - -HRESULT EVRCustomPresenter::OnClockStart(MFTIME, LONGLONG clockStartOffset) -{ - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - // We cannot start after shutdown. - HRESULT hr = checkShutdown(); - if (FAILED(hr)) - return hr; - - // Check if the clock is already active (not stopped). - if (isActive()) { - m_renderState = RenderStarted; - - // If the clock position changes while the clock is active, it - // is a seek request. We need to flush all pending samples. - if (clockStartOffset != PRESENTATION_CURRENT_POSITION) - flush(); - } else { - m_renderState = RenderStarted; - - // The clock has started from the stopped state. - - // Possibly we are in the middle of frame-stepping OR have samples waiting - // in the frame-step queue. Deal with these two cases first: - hr = startFrameStep(); - if (FAILED(hr)) - return hr; - } - - // Now try to get new output samples from the mixer. - processOutputLoop(); - - return hr; -} - -HRESULT EVRCustomPresenter::OnClockRestart(MFTIME) -{ - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - HRESULT hr = checkShutdown(); - if (FAILED(hr)) - return hr; - - // The EVR calls OnClockRestart only while paused. - - m_renderState = RenderStarted; - - // Possibly we are in the middle of frame-stepping OR we have samples waiting - // in the frame-step queue. Deal with these two cases first: - hr = startFrameStep(); - if (FAILED(hr)) - return hr; - - // Now resume the presentation loop. - processOutputLoop(); - - return hr; -} - -HRESULT EVRCustomPresenter::OnClockStop(MFTIME) -{ - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - HRESULT hr = checkShutdown(); - if (FAILED(hr)) - return hr; - - if (m_renderState != RenderStopped) { - m_renderState = RenderStopped; - flush(); - - // If we are in the middle of frame-stepping, cancel it now. - if (m_frameStep.state != FrameStepNone) - cancelFrameStep(); - } - - return S_OK; -} - -HRESULT EVRCustomPresenter::OnClockPause(MFTIME) -{ - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - // We cannot pause the clock after shutdown. - HRESULT hr = checkShutdown(); - - if (SUCCEEDED(hr)) - m_renderState = RenderPaused; - - return hr; -} - -HRESULT EVRCustomPresenter::OnClockSetRate(MFTIME, float rate) -{ - // Note: - // The presenter reports its maximum rate through the IMFRateSupport interface. - // Here, we assume that the EVR honors the maximum rate. - - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - HRESULT hr = checkShutdown(); - if (FAILED(hr)) - return hr; - - // If the rate is changing from zero (scrubbing) to non-zero, cancel the - // frame-step operation. - if ((m_playbackRate == 0.0f) && (rate != 0.0f)) { - cancelFrameStep(); - for (auto sample : qAsConst(m_frameStep.samples)) - sample->Release(); - m_frameStep.samples.clear(); - } - - m_playbackRate = rate; - - // Tell the scheduler about the new rate. - m_scheduler.setClockRate(rate); - - return S_OK; -} - -HRESULT EVRCustomPresenter::GetSlowestRate(MFRATE_DIRECTION, BOOL, float *rate) -{ - if (!rate) - return E_POINTER; - - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - HRESULT hr = checkShutdown(); - - if (SUCCEEDED(hr)) { - // There is no minimum playback rate, so the minimum is zero. - *rate = 0; - } - - return S_OK; -} - -HRESULT EVRCustomPresenter::GetFastestRate(MFRATE_DIRECTION direction, BOOL thin, float *rate) -{ - if (!rate) - return E_POINTER; - - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - float maxRate = 0.0f; - - HRESULT hr = checkShutdown(); - if (FAILED(hr)) - return hr; - - // Get the maximum *forward* rate. - maxRate = getMaxRate(thin); - - // For reverse playback, it's the negative of maxRate. - if (direction == MFRATE_REVERSE) - maxRate = -maxRate; - - *rate = maxRate; - - return S_OK; -} - -HRESULT EVRCustomPresenter::IsRateSupported(BOOL thin, float rate, float *nearestSupportedRate) -{ - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - float maxRate = 0.0f; - float nearestRate = rate; // If we support rate, that is the nearest. - - HRESULT hr = checkShutdown(); - if (FAILED(hr)) - return hr; - - // Find the maximum forward rate. - // Note: We have no minimum rate (that is, we support anything down to 0). - maxRate = getMaxRate(thin); - - if (qFabs(rate) > maxRate) { - // The (absolute) requested rate exceeds the maximum rate. - hr = MF_E_UNSUPPORTED_RATE; - - // The nearest supported rate is maxRate. - nearestRate = maxRate; - if (rate < 0) { - // Negative for reverse playback. - nearestRate = -nearestRate; - } - } - - // Return the nearest supported rate. - if (nearestSupportedRate) - *nearestSupportedRate = nearestRate; - - return hr; -} - -void EVRCustomPresenter::supportedFormatsChanged() -{ - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - m_canRenderToSurface = false; - m_presentEngine->setHint(D3DPresentEngine::RenderToTexture, false); - - // check if we can render to the surface (compatible formats) - if (m_surface) { - QList<QVideoFrame::PixelFormat> formats = m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle); - if (m_presentEngine->supportsTextureRendering() && formats.contains(QVideoFrame::Format_RGB32)) { - m_presentEngine->setHint(D3DPresentEngine::RenderToTexture, true); - m_canRenderToSurface = true; - } else { - formats = m_surface->supportedPixelFormats(QAbstractVideoBuffer::NoHandle); - for (QVideoFrame::PixelFormat format : qAsConst(formats)) { - if (SUCCEEDED(m_presentEngine->checkFormat(qt_evr_D3DFormatFromPixelFormat(format)))) { - m_canRenderToSurface = true; - break; - } - } - } - } - - // TODO: if media type already set, renegotiate? -} - -void EVRCustomPresenter::setSurface(QAbstractVideoSurface *surface) -{ - m_mutex.lock(); - - if (m_surface) { - disconnect(m_surface, &QAbstractVideoSurface::supportedFormatsChanged, - this, &EVRCustomPresenter::supportedFormatsChanged); - } - - m_surface = surface; - - if (m_surface) { - connect(m_surface, &QAbstractVideoSurface::supportedFormatsChanged, - this, &EVRCustomPresenter::supportedFormatsChanged); - } - - m_mutex.unlock(); - - supportedFormatsChanged(); -} - -HRESULT EVRCustomPresenter::configureMixer(IMFTransform *mixer) -{ - // Set the zoom rectangle (ie, the source clipping rectangle). - return setMixerSourceRect(mixer, m_sourceRect); -} - -HRESULT EVRCustomPresenter::renegotiateMediaType() -{ - HRESULT hr = S_OK; - bool foundMediaType = false; - - IMFMediaType *mixerType = NULL; - IMFMediaType *optimalType = NULL; - - if (!m_mixer) - return MF_E_INVALIDREQUEST; - - // Loop through all of the mixer's proposed output types. - DWORD typeIndex = 0; - while (!foundMediaType && (hr != MF_E_NO_MORE_TYPES)) { - qt_evr_safe_release(&mixerType); - qt_evr_safe_release(&optimalType); - - // Step 1. Get the next media type supported by mixer. - hr = m_mixer->GetOutputAvailableType(0, typeIndex++, &mixerType); - if (FAILED(hr)) - break; - - // From now on, if anything in this loop fails, try the next type, - // until we succeed or the mixer runs out of types. - - // Step 2. Check if we support this media type. - if (SUCCEEDED(hr)) - hr = isMediaTypeSupported(mixerType); - - // Step 3. Adjust the mixer's type to match our requirements. - if (SUCCEEDED(hr)) - hr = createOptimalVideoType(mixerType, &optimalType); - - // Step 4. Check if the mixer will accept this media type. - if (SUCCEEDED(hr)) - hr = m_mixer->SetOutputType(0, optimalType, MFT_SET_TYPE_TEST_ONLY); - - // Step 5. Try to set the media type on ourselves. - if (SUCCEEDED(hr)) - hr = setMediaType(optimalType); - - // Step 6. Set output media type on mixer. - if (SUCCEEDED(hr)) { - hr = m_mixer->SetOutputType(0, optimalType, 0); - - // If something went wrong, clear the media type. - if (FAILED(hr)) - setMediaType(NULL); - } - - if (SUCCEEDED(hr)) - foundMediaType = true; - } - - qt_evr_safe_release(&mixerType); - qt_evr_safe_release(&optimalType); - - return hr; -} - -HRESULT EVRCustomPresenter::flush() -{ - m_prerolled = false; - - // The scheduler might have samples that are waiting for - // their presentation time. Tell the scheduler to flush. - - // This call blocks until the scheduler threads discards all scheduled samples. - m_scheduler.flush(); - - // Flush the frame-step queue. - for (auto sample : qAsConst(m_frameStep.samples)) - sample->Release(); - m_frameStep.samples.clear(); - - if (m_renderState == RenderStopped && m_surface && m_surface->isActive()) { - // Repaint with black. - presentSample(NULL); - } - - return S_OK; -} - -HRESULT EVRCustomPresenter::processInputNotify() -{ - HRESULT hr = S_OK; - - // Set the flag that says the mixer has a new sample. - m_sampleNotify = true; - - if (!m_mediaType) { - // We don't have a valid media type yet. - hr = MF_E_TRANSFORM_TYPE_NOT_SET; - } else { - // Try to process an output sample. - processOutputLoop(); - } - return hr; -} - -HRESULT EVRCustomPresenter::beginStreaming() -{ - HRESULT hr = S_OK; - - // Start the scheduler thread. - hr = m_scheduler.startScheduler(m_clock); - - return hr; -} - -HRESULT EVRCustomPresenter::endStreaming() -{ - HRESULT hr = S_OK; - - // Stop the scheduler thread. - hr = m_scheduler.stopScheduler(); - - return hr; -} - -HRESULT EVRCustomPresenter::checkEndOfStream() -{ - if (!m_endStreaming) { - // The EVR did not send the MFVP_MESSAGE_ENDOFSTREAM message. - return S_OK; - } - - if (m_sampleNotify) { - // The mixer still has input. - return S_OK; - } - - if (m_scheduler.areSamplesScheduled()) { - // Samples are still scheduled for rendering. - return S_OK; - } - - // Everything is complete. Now we can tell the EVR that we are done. - notifyEvent(EC_COMPLETE, (LONG_PTR)S_OK, 0); - m_endStreaming = false; - - stopSurface(); - return S_OK; -} - -HRESULT EVRCustomPresenter::prepareFrameStep(DWORD steps) -{ - HRESULT hr = S_OK; - - // Cache the step count. - m_frameStep.steps += steps; - - // Set the frame-step state. - m_frameStep.state = FrameStepWaitingStart; - - // If the clock is are already running, we can start frame-stepping now. - // Otherwise, we will start when the clock starts. - if (m_renderState == RenderStarted) - hr = startFrameStep(); - - return hr; -} - -HRESULT EVRCustomPresenter::startFrameStep() -{ - HRESULT hr = S_OK; - IMFSample *sample = NULL; - - if (m_frameStep.state == FrameStepWaitingStart) { - // We have a frame-step request, and are waiting for the clock to start. - // Set the state to "pending," which means we are waiting for samples. - m_frameStep.state = FrameStepPending; - - // If the frame-step queue already has samples, process them now. - while (!m_frameStep.samples.isEmpty() && (m_frameStep.state == FrameStepPending)) { - sample = m_frameStep.samples.takeFirst(); - - hr = deliverFrameStepSample(sample); - if (FAILED(hr)) - goto done; - - qt_evr_safe_release(&sample); - - // We break from this loop when: - // (a) the frame-step queue is empty, or - // (b) the frame-step operation is complete. - } - } else if (m_frameStep.state == FrameStepNone) { - // We are not frame stepping. Therefore, if the frame-step queue has samples, - // we need to process them normally. - while (!m_frameStep.samples.isEmpty()) { - sample = m_frameStep.samples.takeFirst(); - - hr = deliverSample(sample, false); - if (FAILED(hr)) - goto done; - - qt_evr_safe_release(&sample); - } - } - -done: - qt_evr_safe_release(&sample); - return hr; -} - -HRESULT EVRCustomPresenter::completeFrameStep(IMFSample *sample) -{ - HRESULT hr = S_OK; - MFTIME sampleTime = 0; - MFTIME systemTime = 0; - - // Update our state. - m_frameStep.state = FrameStepComplete; - m_frameStep.sampleNoRef = 0; - - // Notify the EVR that the frame-step is complete. - notifyEvent(EC_STEP_COMPLETE, FALSE, 0); // FALSE = completed (not cancelled) - - // If we are scrubbing (rate == 0), also send the "scrub time" event. - if (isScrubbing()) { - // Get the time stamp from the sample. - hr = sample->GetSampleTime(&sampleTime); - if (FAILED(hr)) { - // No time stamp. Use the current presentation time. - if (m_clock) - m_clock->GetCorrelatedTime(0, &sampleTime, &systemTime); - - hr = S_OK; // (Not an error condition.) - } - - notifyEvent(EC_SCRUB_TIME, DWORD(sampleTime), DWORD(((sampleTime) >> 32) & 0xffffffff)); - } - return hr; -} - -HRESULT EVRCustomPresenter::cancelFrameStep() -{ - FrameStepState oldState = m_frameStep.state; - - m_frameStep.state = FrameStepNone; - m_frameStep.steps = 0; - m_frameStep.sampleNoRef = 0; - // Don't clear the frame-step queue yet, because we might frame step again. - - if (oldState > FrameStepNone && oldState < FrameStepComplete) { - // We were in the middle of frame-stepping when it was cancelled. - // Notify the EVR. - notifyEvent(EC_STEP_COMPLETE, TRUE, 0); // TRUE = cancelled - } - return S_OK; -} - -HRESULT EVRCustomPresenter::createOptimalVideoType(IMFMediaType *proposedType, IMFMediaType **optimalType) -{ - HRESULT hr = S_OK; - - RECT rcOutput; - ZeroMemory(&rcOutput, sizeof(rcOutput)); - - MFVideoArea displayArea; - ZeroMemory(&displayArea, sizeof(displayArea)); - - IMFMediaType *mtOptimal = NULL; - - UINT64 size; - int width; - int height; - - // Clone the proposed type. - - hr = MFCreateMediaType(&mtOptimal); - if (FAILED(hr)) - goto done; - - hr = proposedType->CopyAllItems(mtOptimal); - if (FAILED(hr)) - goto done; - - // Modify the new type. - - hr = proposedType->GetUINT64(MF_MT_FRAME_SIZE, &size); - width = int(HI32(size)); - height = int(LO32(size)); - rcOutput.left = 0; - rcOutput.top = 0; - rcOutput.right = width; - rcOutput.bottom = height; - - // Set the geometric aperture, and disable pan/scan. - displayArea = qt_evr_makeMFArea(0, 0, rcOutput.right, rcOutput.bottom); - - hr = mtOptimal->SetUINT32(MF_MT_PAN_SCAN_ENABLED, FALSE); - if (FAILED(hr)) - goto done; - - hr = mtOptimal->SetBlob(MF_MT_GEOMETRIC_APERTURE, reinterpret_cast<UINT8*>(&displayArea), - sizeof(displayArea)); - if (FAILED(hr)) - goto done; - - // Set the pan/scan aperture and the minimum display aperture. We don't care - // about them per se, but the mixer will reject the type if these exceed the - // frame dimentions. - hr = mtOptimal->SetBlob(MF_MT_PAN_SCAN_APERTURE, reinterpret_cast<UINT8*>(&displayArea), - sizeof(displayArea)); - if (FAILED(hr)) - goto done; - - hr = mtOptimal->SetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, reinterpret_cast<UINT8*>(&displayArea), - sizeof(displayArea)); - if (FAILED(hr)) - goto done; - - // Return the pointer to the caller. - *optimalType = mtOptimal; - (*optimalType)->AddRef(); - -done: - qt_evr_safe_release(&mtOptimal); - return hr; - -} - -HRESULT EVRCustomPresenter::setMediaType(IMFMediaType *mediaType) -{ - // Note: mediaType can be NULL (to clear the type) - - // Clearing the media type is allowed in any state (including shutdown). - if (!mediaType) { - stopSurface(); - qt_evr_safe_release(&m_mediaType); - releaseResources(); - return S_OK; - } - - MFRatio fps = { 0, 0 }; - QList<IMFSample*> sampleQueue; - - // Cannot set the media type after shutdown. - HRESULT hr = checkShutdown(); - if (FAILED(hr)) - goto done; - - // Check if the new type is actually different. - // Note: This function safely handles NULL input parameters. - if (qt_evr_areMediaTypesEqual(m_mediaType, mediaType)) - goto done; // Nothing more to do. - - // We're really changing the type. First get rid of the old type. - qt_evr_safe_release(&m_mediaType); - releaseResources(); - - // Initialize the presenter engine with the new media type. - // The presenter engine allocates the samples. - - hr = m_presentEngine->createVideoSamples(mediaType, sampleQueue); - if (FAILED(hr)) - goto done; - - // Mark each sample with our token counter. If this batch of samples becomes - // invalid, we increment the counter, so that we know they should be discarded. - for (auto sample : qAsConst(sampleQueue)) { - hr = sample->SetUINT32(MFSamplePresenter_SampleCounter, m_tokenCounter); - if (FAILED(hr)) - goto done; - } - - // Add the samples to the sample pool. - hr = m_samplePool.initialize(sampleQueue); - if (FAILED(hr)) - goto done; - - // Set the frame rate on the scheduler. - if (SUCCEEDED(qt_evr_getFrameRate(mediaType, &fps)) && (fps.Numerator != 0) && (fps.Denominator != 0)) { - m_scheduler.setFrameRate(fps); - } else { - // NOTE: The mixer's proposed type might not have a frame rate, in which case - // we'll use an arbitrary default. (Although it's unlikely the video source - // does not have a frame rate.) - m_scheduler.setFrameRate(g_DefaultFrameRate); - } - - // Store the media type. - m_mediaType = mediaType; - m_mediaType->AddRef(); - - startSurface(); - -done: - if (FAILED(hr)) - releaseResources(); - return hr; -} - -HRESULT EVRCustomPresenter::isMediaTypeSupported(IMFMediaType *proposed) -{ - D3DFORMAT d3dFormat = D3DFMT_UNKNOWN; - BOOL compressed = FALSE; - MFVideoInterlaceMode interlaceMode = MFVideoInterlace_Unknown; - MFVideoArea videoCropArea; - UINT32 width = 0, height = 0; - - // Validate the format. - HRESULT hr = qt_evr_getFourCC(proposed, reinterpret_cast<DWORD*>(&d3dFormat)); - if (FAILED(hr)) - return hr; - - QVideoFrame::PixelFormat pixelFormat = pixelFormatFromMediaType(proposed); - if (pixelFormat == QVideoFrame::Format_Invalid) - return MF_E_INVALIDMEDIATYPE; - - // When not rendering to texture, only accept pixel formats supported by the video surface - if (!m_presentEngine->isTextureRenderingEnabled() - && m_surface - && !m_surface->supportedPixelFormats().contains(pixelFormat)) { - return MF_E_INVALIDMEDIATYPE; - } - - // Reject compressed media types. - hr = proposed->IsCompressedFormat(&compressed); - if (FAILED(hr)) - return hr; - - if (compressed) - return MF_E_INVALIDMEDIATYPE; - - // The D3DPresentEngine checks whether surfaces can be created using this format - hr = m_presentEngine->checkFormat(d3dFormat); - if (FAILED(hr)) - return hr; - - // Reject interlaced formats. - hr = proposed->GetUINT32(MF_MT_INTERLACE_MODE, reinterpret_cast<UINT32*>(&interlaceMode)); - if (FAILED(hr)) - return hr; - - if (interlaceMode != MFVideoInterlace_Progressive) - return MF_E_INVALIDMEDIATYPE; - - hr = MFGetAttributeSize(proposed, MF_MT_FRAME_SIZE, &width, &height); - if (FAILED(hr)) - return hr; - - // Validate the various apertures (cropping regions) against the frame size. - // Any of these apertures may be unspecified in the media type, in which case - // we ignore it. We just want to reject invalid apertures. - - if (SUCCEEDED(proposed->GetBlob(MF_MT_PAN_SCAN_APERTURE, - reinterpret_cast<UINT8*>(&videoCropArea), - sizeof(videoCropArea), nullptr))) { - hr = qt_evr_validateVideoArea(videoCropArea, width, height); - } - if (SUCCEEDED(proposed->GetBlob(MF_MT_GEOMETRIC_APERTURE, - reinterpret_cast<UINT8*>(&videoCropArea), - sizeof(videoCropArea), nullptr))) { - hr = qt_evr_validateVideoArea(videoCropArea, width, height); - } - if (SUCCEEDED(proposed->GetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, - reinterpret_cast<UINT8*>(&videoCropArea), - sizeof(videoCropArea), nullptr))) { - hr = qt_evr_validateVideoArea(videoCropArea, width, height); - } - return hr; -} - -void EVRCustomPresenter::processOutputLoop() -{ - HRESULT hr = S_OK; - - // Process as many samples as possible. - while (hr == S_OK) { - // If the mixer doesn't have a new input sample, break from the loop. - if (!m_sampleNotify) { - hr = MF_E_TRANSFORM_NEED_MORE_INPUT; - break; - } - - // Try to process a sample. - hr = processOutput(); - - // NOTE: ProcessOutput can return S_FALSE to indicate it did not - // process a sample. If so, break out of the loop. - } - - if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { - // The mixer has run out of input data. Check for end-of-stream. - checkEndOfStream(); - } -} - -HRESULT EVRCustomPresenter::processOutput() -{ - HRESULT hr = S_OK; - DWORD status = 0; - LONGLONG mixerStartTime = 0, mixerEndTime = 0; - MFTIME systemTime = 0; - BOOL repaint = m_repaint; // Temporarily store this state flag. - - MFT_OUTPUT_DATA_BUFFER dataBuffer; - ZeroMemory(&dataBuffer, sizeof(dataBuffer)); - - IMFSample *sample = NULL; - - // If the clock is not running, we present the first sample, - // and then don't present any more until the clock starts. - - if ((m_renderState != RenderStarted) && !m_repaint && m_prerolled) - return S_FALSE; - - // Make sure we have a pointer to the mixer. - if (!m_mixer) - return MF_E_INVALIDREQUEST; - - // Try to get a free sample from the video sample pool. - hr = m_samplePool.getSample(&sample); - if (hr == MF_E_SAMPLEALLOCATOR_EMPTY) // No free samples. Try again when a sample is released. - return S_FALSE; - if (FAILED(hr)) - return hr; - - // From now on, we have a valid video sample pointer, where the mixer will - // write the video data. - - if (m_repaint) { - // Repaint request. Ask the mixer for the most recent sample. - setDesiredSampleTime(sample, m_scheduler.lastSampleTime(), m_scheduler.frameDuration()); - - m_repaint = false; // OK to clear this flag now. - } else { - // Not a repaint request. Clear the desired sample time; the mixer will - // give us the next frame in the stream. - clearDesiredSampleTime(sample); - - if (m_clock) { - // Latency: Record the starting time for ProcessOutput. - m_clock->GetCorrelatedTime(0, &mixerStartTime, &systemTime); - } - } - - // Now we are ready to get an output sample from the mixer. - dataBuffer.dwStreamID = 0; - dataBuffer.pSample = sample; - dataBuffer.dwStatus = 0; - - hr = m_mixer->ProcessOutput(0, 1, &dataBuffer, &status); - - if (FAILED(hr)) { - // Return the sample to the pool. - HRESULT hr2 = m_samplePool.returnSample(sample); - if (FAILED(hr2)) { - hr = hr2; - goto done; - } - // Handle some known error codes from ProcessOutput. - if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) { - // The mixer's format is not set. Negotiate a new format. - hr = renegotiateMediaType(); - } else if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { - // There was a dynamic media type change. Clear our media type. - setMediaType(NULL); - } else if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { - // The mixer needs more input. - // We have to wait for the mixer to get more input. - m_sampleNotify = false; - } - } else { - // We got an output sample from the mixer. - - if (m_clock && !repaint) { - // Latency: Record the ending time for the ProcessOutput operation, - // and notify the EVR of the latency. - - m_clock->GetCorrelatedTime(0, &mixerEndTime, &systemTime); - - LONGLONG latencyTime = mixerEndTime - mixerStartTime; - notifyEvent(EC_PROCESSING_LATENCY, reinterpret_cast<LONG_PTR>(&latencyTime), 0); - } - - // Set up notification for when the sample is released. - hr = trackSample(sample); - if (FAILED(hr)) - goto done; - - // Schedule the sample. - if ((m_frameStep.state == FrameStepNone) || repaint) { - hr = deliverSample(sample, repaint); - if (FAILED(hr)) - goto done; - } else { - // We are frame-stepping (and this is not a repaint request). - hr = deliverFrameStepSample(sample); - if (FAILED(hr)) - goto done; - } - - m_prerolled = true; // We have presented at least one sample now. - } - -done: - qt_evr_safe_release(&sample); - - // Important: Release any events returned from the ProcessOutput method. - qt_evr_safe_release(&dataBuffer.pEvents); - return hr; -} - -HRESULT EVRCustomPresenter::deliverSample(IMFSample *sample, bool repaint) -{ - // If we are not actively playing, OR we are scrubbing (rate = 0) OR this is a - // repaint request, then we need to present the sample immediately. Otherwise, - // schedule it normally. - - bool presentNow = ((m_renderState != RenderStarted) || isScrubbing() || repaint); - - HRESULT hr = m_scheduler.scheduleSample(sample, presentNow); - - if (FAILED(hr)) { - // Notify the EVR that we have failed during streaming. The EVR will notify the - // pipeline. - - notifyEvent(EC_ERRORABORT, hr, 0); - } - - return hr; -} - -HRESULT EVRCustomPresenter::deliverFrameStepSample(IMFSample *sample) -{ - HRESULT hr = S_OK; - IUnknown *unk = NULL; - - // For rate 0, discard any sample that ends earlier than the clock time. - if (isScrubbing() && m_clock && qt_evr_isSampleTimePassed(m_clock, sample)) { - // Discard this sample. - } else if (m_frameStep.state >= FrameStepScheduled) { - // A frame was already submitted. Put this sample on the frame-step queue, - // in case we are asked to step to the next frame. If frame-stepping is - // cancelled, this sample will be processed normally. - sample->AddRef(); - m_frameStep.samples.append(sample); - } else { - // We're ready to frame-step. - - // Decrement the number of steps. - if (m_frameStep.steps > 0) - m_frameStep.steps--; - - if (m_frameStep.steps > 0) { - // This is not the last step. Discard this sample. - } else if (m_frameStep.state == FrameStepWaitingStart) { - // This is the right frame, but the clock hasn't started yet. Put the - // sample on the frame-step queue. When the clock starts, the sample - // will be processed. - sample->AddRef(); - m_frameStep.samples.append(sample); - } else { - // This is the right frame *and* the clock has started. Deliver this sample. - hr = deliverSample(sample, false); - if (FAILED(hr)) - goto done; - - // Query for IUnknown so that we can identify the sample later. - // Per COM rules, an object always returns the same pointer when QI'ed for IUnknown. - hr = sample->QueryInterface(IID_PPV_ARGS(&unk)); - if (FAILED(hr)) - goto done; - - m_frameStep.sampleNoRef = reinterpret_cast<DWORD_PTR>(unk); // No add-ref. - - // NOTE: We do not AddRef the IUnknown pointer, because that would prevent the - // sample from invoking the OnSampleFree callback after the sample is presented. - // We use this IUnknown pointer purely to identify the sample later; we never - // attempt to dereference the pointer. - - m_frameStep.state = FrameStepScheduled; - } - } -done: - qt_evr_safe_release(&unk); - return hr; -} - -HRESULT EVRCustomPresenter::trackSample(IMFSample *sample) -{ - IMFTrackedSample *tracked = NULL; - - HRESULT hr = sample->QueryInterface(IID_PPV_ARGS(&tracked)); - - if (SUCCEEDED(hr)) - hr = tracked->SetAllocator(&m_sampleFreeCB, NULL); - - qt_evr_safe_release(&tracked); - return hr; -} - -void EVRCustomPresenter::releaseResources() -{ - // Increment the token counter to indicate that all existing video samples - // are "stale." As these samples get released, we'll dispose of them. - // - // Note: The token counter is required because the samples are shared - // between more than one thread, and they are returned to the presenter - // through an asynchronous callback (onSampleFree). Without the token, we - // might accidentally re-use a stale sample after the ReleaseResources - // method returns. - - m_tokenCounter++; - - flush(); - - m_samplePool.clear(); - - m_presentEngine->releaseResources(); -} - -HRESULT EVRCustomPresenter::onSampleFree(IMFAsyncResult *result) -{ - IUnknown *object = NULL; - IMFSample *sample = NULL; - IUnknown *unk = NULL; - UINT32 token; - - // Get the sample from the async result object. - HRESULT hr = result->GetObject(&object); - if (FAILED(hr)) - goto done; - - hr = object->QueryInterface(IID_PPV_ARGS(&sample)); - if (FAILED(hr)) - goto done; - - // If this sample was submitted for a frame-step, the frame step operation - // is complete. - - if (m_frameStep.state == FrameStepScheduled) { - // Query the sample for IUnknown and compare it to our cached value. - hr = sample->QueryInterface(IID_PPV_ARGS(&unk)); - if (FAILED(hr)) - goto done; - - if (m_frameStep.sampleNoRef == reinterpret_cast<DWORD_PTR>(unk)) { - // Notify the EVR. - hr = completeFrameStep(sample); - if (FAILED(hr)) - goto done; - } - - // Note: Although object is also an IUnknown pointer, it is not - // guaranteed to be the exact pointer value returned through - // QueryInterface. Therefore, the second QueryInterface call is - // required. - } - - m_mutex.lock(); - - token = MFGetAttributeUINT32(sample, MFSamplePresenter_SampleCounter, (UINT32)-1); - - if (token == m_tokenCounter) { - // Return the sample to the sample pool. - hr = m_samplePool.returnSample(sample); - if (SUCCEEDED(hr)) { - // A free sample is available. Process more data if possible. - processOutputLoop(); - } - } - - m_mutex.unlock(); - -done: - if (FAILED(hr)) - notifyEvent(EC_ERRORABORT, hr, 0); - qt_evr_safe_release(&object); - qt_evr_safe_release(&sample); - qt_evr_safe_release(&unk); - return hr; -} - -float EVRCustomPresenter::getMaxRate(bool thin) -{ - // Non-thinned: - // If we have a valid frame rate and a monitor refresh rate, the maximum - // playback rate is equal to the refresh rate. Otherwise, the maximum rate - // is unbounded (FLT_MAX). - - // Thinned: The maximum rate is unbounded. - - float maxRate = FLT_MAX; - MFRatio fps = { 0, 0 }; - UINT monitorRateHz = 0; - - if (!thin && m_mediaType) { - qt_evr_getFrameRate(m_mediaType, &fps); - monitorRateHz = m_presentEngine->refreshRate(); - - if (fps.Denominator && fps.Numerator && monitorRateHz) { - // Max Rate = Refresh Rate / Frame Rate - maxRate = (float)MulDiv(monitorRateHz, fps.Denominator, fps.Numerator); - } - } - - return maxRate; -} - -bool EVRCustomPresenter::event(QEvent *e) -{ - switch (int(e->type())) { - case StartSurface: - startSurface(); - return true; - case StopSurface: - stopSurface(); - return true; - case PresentSample: - presentSample(static_cast<PresentSampleEvent *>(e)->sample()); - return true; - default: - break; - } - return QObject::event(e); -} - -void EVRCustomPresenter::startSurface() -{ - if (thread() != QThread::currentThread()) { - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StartSurface))); - return; - } - - if (!m_surface || m_surface->isActive()) - return; - - QVideoSurfaceFormat format = m_presentEngine->videoSurfaceFormat(); - if (!format.isValid()) - return; - - m_surface->start(format); -} - -void EVRCustomPresenter::stopSurface() -{ - if (thread() != QThread::currentThread()) { - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StopSurface))); - return; - } - - if (!m_surface || !m_surface->isActive()) - return; - - m_surface->stop(); -} - -void EVRCustomPresenter::presentSample(IMFSample *sample) -{ - if (thread() != QThread::currentThread()) { - QCoreApplication::postEvent(this, new PresentSampleEvent(sample)); - return; - } - - if (!m_surface || !m_presentEngine->videoSurfaceFormat().isValid()) - return; - - QVideoFrame frame = m_presentEngine->makeVideoFrame(sample); - - // Since start/end times are related to a position when the clock is started, - // to have times from the beginning, need to adjust it by adding seeked position. - if (m_positionOffset) { - if (frame.startTime()) - frame.setStartTime(frame.startTime() + m_positionOffset); - if (frame.endTime()) - frame.setEndTime(frame.endTime() + m_positionOffset); - } - - if (!m_surface->isActive() || m_surface->surfaceFormat() != m_presentEngine->videoSurfaceFormat()) { - m_surface->stop(); - if (!m_surface->start(m_presentEngine->videoSurfaceFormat())) - return; - } - - m_surface->present(frame); -} - -void EVRCustomPresenter::positionChanged(qint64 position) -{ - m_positionOffset = position * 1000; -} - -HRESULT setDesiredSampleTime(IMFSample *sample, const LONGLONG &sampleTime, const LONGLONG &duration) -{ - if (!sample) - return E_POINTER; - - HRESULT hr = S_OK; - IMFDesiredSample *desired = NULL; - - hr = sample->QueryInterface(IID_PPV_ARGS(&desired)); - if (SUCCEEDED(hr)) - desired->SetDesiredSampleTimeAndDuration(sampleTime, duration); - - qt_evr_safe_release(&desired); - return hr; -} - -HRESULT clearDesiredSampleTime(IMFSample *sample) -{ - if (!sample) - return E_POINTER; - - HRESULT hr = S_OK; - - IMFDesiredSample *desired = NULL; - IUnknown *unkSwapChain = NULL; - - // We store some custom attributes on the sample, so we need to cache them - // and reset them. - // - // This works around the fact that IMFDesiredSample::Clear() removes all of the - // attributes from the sample. - - UINT32 counter = MFGetAttributeUINT32(sample, MFSamplePresenter_SampleCounter, (UINT32)-1); - - hr = sample->QueryInterface(IID_PPV_ARGS(&desired)); - if (SUCCEEDED(hr)) { - desired->Clear(); - - hr = sample->SetUINT32(MFSamplePresenter_SampleCounter, counter); - if (FAILED(hr)) - goto done; - } - -done: - qt_evr_safe_release(&unkSwapChain); - qt_evr_safe_release(&desired); - return hr; -} - -HRESULT setMixerSourceRect(IMFTransform *mixer, const MFVideoNormalizedRect &sourceRect) -{ - if (!mixer) - return E_POINTER; - - IMFAttributes *attributes = NULL; - - HRESULT hr = mixer->GetAttributes(&attributes); - if (SUCCEEDED(hr)) { - hr = attributes->SetBlob(video_ZOOM_RECT, reinterpret_cast<const UINT8*>(&sourceRect), - sizeof(sourceRect)); - attributes->Release(); - } - return hr; -} - -static QVideoFrame::PixelFormat pixelFormatFromMediaType(IMFMediaType *type) -{ - GUID majorType; - if (FAILED(type->GetMajorType(&majorType))) - return QVideoFrame::Format_Invalid; - if (majorType != MFMediaType_Video) - return QVideoFrame::Format_Invalid; - - GUID subtype; - if (FAILED(type->GetGUID(MF_MT_SUBTYPE, &subtype))) - return QVideoFrame::Format_Invalid; - - if (subtype == MFVideoFormat_RGB32) - return QVideoFrame::Format_RGB32; - if (subtype == MFVideoFormat_ARGB32) - return QVideoFrame::Format_ARGB32; - if (subtype == MFVideoFormat_RGB24) - return QVideoFrame::Format_RGB24; - if (subtype == MFVideoFormat_RGB565) - return QVideoFrame::Format_RGB565; - if (subtype == MFVideoFormat_RGB555) - return QVideoFrame::Format_RGB555; - if (subtype == MFVideoFormat_AYUV) - return QVideoFrame::Format_AYUV444; - if (subtype == MFVideoFormat_I420) - return QVideoFrame::Format_YUV420P; - if (subtype == MFVideoFormat_UYVY) - return QVideoFrame::Format_UYVY; - if (subtype == MFVideoFormat_YV12) - return QVideoFrame::Format_YV12; - if (subtype == MFVideoFormat_NV12) - return QVideoFrame::Format_NV12; - - return QVideoFrame::Format_Invalid; -} - -QT_END_NAMESPACE diff --git a/src/plugins/common/evr/evrcustompresenter.h b/src/plugins/common/evr/evrcustompresenter.h deleted file mode 100644 index c1c21580e..000000000 --- a/src/plugins/common/evr/evrcustompresenter.h +++ /dev/null @@ -1,377 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef EVRCUSTOMPRESENTER_H -#define EVRCUSTOMPRESENTER_H - -#include <QObject> -#include <qmutex.h> -#include <qqueue.h> -#include <qevent.h> -#include <qvideosurfaceformat.h> - -#include "evrdefs.h" - -QT_BEGIN_NAMESPACE - -class EVRCustomPresenter; -class D3DPresentEngine; - -class QAbstractVideoSurface; - -template<class T> -class AsyncCallback : public IMFAsyncCallback -{ - Q_DISABLE_COPY(AsyncCallback) -public: - typedef HRESULT (T::*InvokeFn)(IMFAsyncResult *asyncResult); - - AsyncCallback(T *parent, InvokeFn fn) : m_parent(parent), m_invokeFn(fn) - { - } - - // IUnknown - STDMETHODIMP QueryInterface(REFIID iid, void** ppv) override - { - if (!ppv) - return E_POINTER; - - if (iid == __uuidof(IUnknown)) { - *ppv = static_cast<IUnknown*>(static_cast<IMFAsyncCallback*>(this)); - } else if (iid == __uuidof(IMFAsyncCallback)) { - *ppv = static_cast<IMFAsyncCallback*>(this); - } else { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - - STDMETHODIMP_(ULONG) AddRef() override { - // Delegate to parent class. - return m_parent->AddRef(); - } - STDMETHODIMP_(ULONG) Release() override { - // Delegate to parent class. - return m_parent->Release(); - } - - // IMFAsyncCallback methods - STDMETHODIMP GetParameters(DWORD*, DWORD*) override - { - // Implementation of this method is optional. - return E_NOTIMPL; - } - - STDMETHODIMP Invoke(IMFAsyncResult* asyncResult) override - { - return (m_parent->*m_invokeFn)(asyncResult); - } - - T *m_parent; - InvokeFn m_invokeFn; -}; - -class Scheduler -{ - Q_DISABLE_COPY(Scheduler) -public: - enum ScheduleEvent - { - Terminate = WM_USER, - Schedule = WM_USER + 1, - Flush = WM_USER + 2 - }; - - Scheduler(EVRCustomPresenter *presenter); - ~Scheduler(); - - void setFrameRate(const MFRatio &fps); - void setClockRate(float rate) { m_playbackRate = rate; } - - const LONGLONG &lastSampleTime() const { return m_lastSampleTime; } - const LONGLONG &frameDuration() const { return m_perFrameInterval; } - - HRESULT startScheduler(IMFClock *clock); - HRESULT stopScheduler(); - - HRESULT scheduleSample(IMFSample *sample, bool presentNow); - HRESULT processSamplesInQueue(LONG *nextSleep); - HRESULT processSample(IMFSample *sample, LONG *nextSleep); - HRESULT flush(); - - bool areSamplesScheduled(); - - // ThreadProc for the scheduler thread. - static DWORD WINAPI schedulerThreadProc(LPVOID parameter); - -private: - DWORD schedulerThreadProcPrivate(); - - EVRCustomPresenter *m_presenter; - - QQueue<IMFSample*> m_scheduledSamples; // Samples waiting to be presented. - - IMFClock *m_clock; // Presentation clock. Can be NULL. - - DWORD m_threadID; - HANDLE m_schedulerThread; - HANDLE m_threadReadyEvent; - HANDLE m_flushEvent; - - float m_playbackRate; - MFTIME m_perFrameInterval; // Duration of each frame. - LONGLONG m_perFrame_1_4th; // 1/4th of the frame duration. - MFTIME m_lastSampleTime; // Most recent sample time. - - QMutex m_mutex; -}; - -class SamplePool -{ - Q_DISABLE_COPY(SamplePool) -public: - SamplePool(); - ~SamplePool(); - - HRESULT initialize(QList<IMFSample*> &samples); - HRESULT clear(); - - HRESULT getSample(IMFSample **sample); - HRESULT returnSample(IMFSample *sample); - -private: - QMutex m_mutex; - QList<IMFSample*> m_videoSampleQueue; - bool m_initialized; -}; - -class EVRCustomPresenter - : public QObject - , public IMFVideoDeviceID - , public IMFVideoPresenter // Inherits IMFClockStateSink - , public IMFRateSupport - , public IMFGetService - , public IMFTopologyServiceLookupClient -{ - Q_DISABLE_COPY(EVRCustomPresenter) -public: - // Defines the state of the presenter. - enum RenderState - { - RenderStarted = 1, - RenderStopped, - RenderPaused, - RenderShutdown // Initial state. - }; - - // Defines the presenter's state with respect to frame-stepping. - enum FrameStepState - { - FrameStepNone, // Not frame stepping. - FrameStepWaitingStart, // Frame stepping, but the clock is not started. - FrameStepPending, // Clock is started. Waiting for samples. - FrameStepScheduled, // Submitted a sample for rendering. - FrameStepComplete // Sample was rendered. - }; - - enum PresenterEvents - { - StartSurface = QEvent::User, - StopSurface = QEvent::User + 1, - PresentSample = QEvent::User + 2 - }; - - EVRCustomPresenter(QAbstractVideoSurface *surface = 0); - ~EVRCustomPresenter() override; - - bool isValid() const; - - // IUnknown methods - STDMETHODIMP QueryInterface(REFIID riid, void ** ppv) override; - STDMETHODIMP_(ULONG) AddRef() override; - STDMETHODIMP_(ULONG) Release() override; - - // IMFGetService methods - STDMETHODIMP GetService(REFGUID guidService, REFIID riid, LPVOID *ppvObject) override; - - // IMFVideoPresenter methods - STDMETHODIMP ProcessMessage(MFVP_MESSAGE_TYPE message, ULONG_PTR param) override; - STDMETHODIMP GetCurrentMediaType(IMFVideoMediaType** mediaType) override; - - // IMFClockStateSink methods - STDMETHODIMP OnClockStart(MFTIME systemTime, LONGLONG clockStartOffset) override; - STDMETHODIMP OnClockStop(MFTIME systemTime) override; - STDMETHODIMP OnClockPause(MFTIME systemTime) override; - STDMETHODIMP OnClockRestart(MFTIME systemTime) override; - STDMETHODIMP OnClockSetRate(MFTIME systemTime, float rate) override; - - // IMFRateSupport methods - STDMETHODIMP GetSlowestRate(MFRATE_DIRECTION direction, BOOL thin, float *rate) override; - STDMETHODIMP GetFastestRate(MFRATE_DIRECTION direction, BOOL thin, float *rate) override; - STDMETHODIMP IsRateSupported(BOOL thin, float rate, float *nearestSupportedRate) override; - - // IMFVideoDeviceID methods - STDMETHODIMP GetDeviceID(IID* deviceID) override; - - // IMFTopologyServiceLookupClient methods - STDMETHODIMP InitServicePointers(IMFTopologyServiceLookup *lookup) override; - STDMETHODIMP ReleaseServicePointers() override; - - void supportedFormatsChanged(); - void setSurface(QAbstractVideoSurface *surface); - - void startSurface(); - void stopSurface(); - void presentSample(IMFSample *sample); - - bool event(QEvent *) override; - -public Q_SLOTS: - void positionChanged(qint64 position); - -private: - HRESULT checkShutdown() const - { - if (m_renderState == RenderShutdown) - return MF_E_SHUTDOWN; - else - return S_OK; - } - - // The "active" state is started or paused. - inline bool isActive() const - { - return ((m_renderState == RenderStarted) || (m_renderState == RenderPaused)); - } - - // Scrubbing occurs when the frame rate is 0. - inline bool isScrubbing() const { return m_playbackRate == 0.0f; } - - // Send an event to the EVR through its IMediaEventSink interface. - void notifyEvent(long eventCode, LONG_PTR param1, LONG_PTR param2) - { - if (m_mediaEventSink) - m_mediaEventSink->Notify(eventCode, param1, param2); - } - - float getMaxRate(bool thin); - - // Mixer operations - HRESULT configureMixer(IMFTransform *mixer); - - // Formats - HRESULT createOptimalVideoType(IMFMediaType* proposed, IMFMediaType **optimal); - HRESULT setMediaType(IMFMediaType *mediaType); - HRESULT isMediaTypeSupported(IMFMediaType *mediaType); - - // Message handlers - HRESULT flush(); - HRESULT renegotiateMediaType(); - HRESULT processInputNotify(); - HRESULT beginStreaming(); - HRESULT endStreaming(); - HRESULT checkEndOfStream(); - - // Managing samples - void processOutputLoop(); - HRESULT processOutput(); - HRESULT deliverSample(IMFSample *sample, bool repaint); - HRESULT trackSample(IMFSample *sample); - void releaseResources(); - - // Frame-stepping - HRESULT prepareFrameStep(DWORD steps); - HRESULT startFrameStep(); - HRESULT deliverFrameStepSample(IMFSample *sample); - HRESULT completeFrameStep(IMFSample *sample); - HRESULT cancelFrameStep(); - - // Callback when a video sample is released. - HRESULT onSampleFree(IMFAsyncResult *result); - AsyncCallback<EVRCustomPresenter> m_sampleFreeCB; - - // Holds information related to frame-stepping. - struct FrameStep - { - FrameStepState state = FrameStepNone; - QList<IMFSample*> samples; - DWORD steps = 0; - DWORD_PTR sampleNoRef = 0; - }; - - long m_refCount; - - RenderState m_renderState; - FrameStep m_frameStep; - - QRecursiveMutex m_mutex; - - // Samples and scheduling - Scheduler m_scheduler; // Manages scheduling of samples. - SamplePool m_samplePool; // Pool of allocated samples. - DWORD m_tokenCounter; // Counter. Incremented whenever we create new samples. - - // Rendering state - bool m_sampleNotify; // Did the mixer signal it has an input sample? - bool m_repaint; // Do we need to repaint the last sample? - bool m_prerolled; // Have we presented at least one sample? - bool m_endStreaming; // Did we reach the end of the stream (EOS)? - - MFVideoNormalizedRect m_sourceRect; - float m_playbackRate; - - D3DPresentEngine *m_presentEngine; // Rendering engine. (Never null if the constructor succeeds.) - - IMFClock *m_clock; // The EVR's clock. - IMFTransform *m_mixer; // The EVR's mixer. - IMediaEventSink *m_mediaEventSink; // The EVR's event-sink interface. - IMFMediaType *m_mediaType; // Output media type - - QAbstractVideoSurface *m_surface; - bool m_canRenderToSurface; - qint64 m_positionOffset; // Seek position in microseconds. -}; - -bool qt_evr_setCustomPresenter(IUnknown *evr, EVRCustomPresenter *presenter); - -QT_END_NAMESPACE - -#endif // EVRCUSTOMPRESENTER_H diff --git a/src/plugins/common/evr/evrd3dpresentengine.cpp b/src/plugins/common/evr/evrd3dpresentengine.cpp deleted file mode 100644 index 51f8b1a39..000000000 --- a/src/plugins/common/evr/evrd3dpresentengine.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "evrd3dpresentengine.h" - -#include "evrhelpers.h" - -#include <qabstractvideobuffer.h> -#include <QAbstractVideoSurface> -#include <qvideoframe.h> -#include <QDebug> -#include <qthread.h> -#include <QOffscreenSurface> - -static const int PRESENTER_BUFFER_COUNT = 3; - -QT_BEGIN_NAMESPACE - -class IMFSampleVideoBuffer: public QAbstractVideoBuffer -{ -public: - IMFSampleVideoBuffer(D3DPresentEngine *engine, IMFSample *sample, QAbstractVideoBuffer::HandleType handleType) - : QAbstractVideoBuffer(handleType) - , m_engine(engine) - , m_sample(sample) - , m_surface(0) - , m_mapMode(NotMapped) - { - if (m_sample) { - m_sample->AddRef(); - - IMFMediaBuffer *buffer; - if (SUCCEEDED(m_sample->GetBufferByIndex(0, &buffer))) { - MFGetService(buffer, - mr_BUFFER_SERVICE, - iid_IDirect3DSurface9, - reinterpret_cast<void **>(&m_surface)); - buffer->Release(); - } - } - } - - ~IMFSampleVideoBuffer() override - { - if (m_surface) { - if (m_mapMode != NotMapped) - m_surface->UnlockRect(); - m_surface->Release(); - } - if (m_sample) - m_sample->Release(); - } - - QVariant handle() const override; - - MapMode mapMode() const override { return m_mapMode; } - MapData map(MapMode mode) override; - void unmap() override; - -private: - mutable D3DPresentEngine *m_engine; - IMFSample *m_sample; - IDirect3DSurface9 *m_surface; - MapMode m_mapMode; - mutable unsigned int m_textureId = 0; -}; - -IMFSampleVideoBuffer::MapData IMFSampleVideoBuffer::map(MapMode mode) -{ - if (!m_surface || m_mapMode != NotMapped) - return {}; - - D3DSURFACE_DESC desc; - if (FAILED(m_surface->GetDesc(&desc))) - return {}; - - D3DLOCKED_RECT rect; - if (FAILED(m_surface->LockRect(&rect, NULL, mode == ReadOnly ? D3DLOCK_READONLY : 0))) - return {}; - - m_mapMode = mode; - - MapData mapData; - mapData.nBytes = (int)(rect.Pitch * desc.Height); - mapData.nPlanes = 1; - mapData.bytesPerLine[0] = (int)rect.Pitch; - mapData.data[0] = reinterpret_cast<uchar *>(rect.pBits); - return mapData; -} - -void IMFSampleVideoBuffer::unmap() -{ - if (m_mapMode == NotMapped) - return; - - m_mapMode = NotMapped; - m_surface->UnlockRect(); -} - -QVariant IMFSampleVideoBuffer::handle() const -{ - return m_textureId; -} - - -D3DPresentEngine::D3DPresentEngine() - : m_deviceResetToken(0) - , m_D3D9(0) - , m_device(0) - , m_deviceManager(0) - , m_useTextureRendering(false) -{ - ZeroMemory(&m_displayMode, sizeof(m_displayMode)); - - HRESULT hr = initializeD3D(); - - if (SUCCEEDED(hr)) { - hr = createD3DDevice(); - if (FAILED(hr)) - qWarning("Failed to create D3D device"); - } else { - qWarning("Failed to initialize D3D"); - } -} - -D3DPresentEngine::~D3DPresentEngine() -{ - releaseResources(); - - qt_evr_safe_release(&m_device); - qt_evr_safe_release(&m_deviceManager); - qt_evr_safe_release(&m_D3D9); -} - -HRESULT D3DPresentEngine::initializeD3D() -{ - HRESULT hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_D3D9); - - if (SUCCEEDED(hr)) - hr = DXVA2CreateDirect3DDeviceManager9(&m_deviceResetToken, &m_deviceManager); - - return hr; -} - -HRESULT D3DPresentEngine::createD3DDevice() -{ - HRESULT hr = S_OK; - HWND hwnd = NULL; - UINT uAdapterID = D3DADAPTER_DEFAULT; - DWORD vp = 0; - - D3DCAPS9 ddCaps; - ZeroMemory(&ddCaps, sizeof(ddCaps)); - - IDirect3DDevice9Ex* device = NULL; - - if (!m_D3D9 || !m_deviceManager) - return MF_E_NOT_INITIALIZED; - - hwnd = ::GetShellWindow(); - - D3DPRESENT_PARAMETERS pp; - ZeroMemory(&pp, sizeof(pp)); - - pp.BackBufferWidth = 1; - pp.BackBufferHeight = 1; - pp.BackBufferFormat = D3DFMT_UNKNOWN; - pp.BackBufferCount = 1; - pp.Windowed = TRUE; - pp.SwapEffect = D3DSWAPEFFECT_DISCARD; - pp.BackBufferFormat = D3DFMT_UNKNOWN; - pp.hDeviceWindow = hwnd; - pp.Flags = D3DPRESENTFLAG_VIDEO; - pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - - hr = m_D3D9->GetDeviceCaps(uAdapterID, D3DDEVTYPE_HAL, &ddCaps); - if (FAILED(hr)) - goto done; - - if (ddCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) - vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; - else - vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; - - hr = m_D3D9->CreateDeviceEx( - uAdapterID, - D3DDEVTYPE_HAL, - pp.hDeviceWindow, - vp | D3DCREATE_NOWINDOWCHANGES | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, - &pp, - NULL, - &device - ); - if (FAILED(hr)) - goto done; - - hr = m_D3D9->GetAdapterDisplayMode(uAdapterID, &m_displayMode); - if (FAILED(hr)) - goto done; - - hr = m_deviceManager->ResetDevice(device, m_deviceResetToken); - if (FAILED(hr)) - goto done; - - qt_evr_safe_release(&m_device); - - m_device = device; - m_device->AddRef(); - -done: - qt_evr_safe_release(&device); - return hr; -} - -bool D3DPresentEngine::isValid() const -{ - return m_device != NULL; -} - -void D3DPresentEngine::releaseResources() -{ - m_surfaceFormat = QVideoSurfaceFormat(); -} - -HRESULT D3DPresentEngine::getService(REFGUID, REFIID riid, void** ppv) -{ - HRESULT hr = S_OK; - - if (riid == __uuidof(IDirect3DDeviceManager9)) { - if (m_deviceManager == NULL) { - hr = MF_E_UNSUPPORTED_SERVICE; - } else { - *ppv = m_deviceManager; - m_deviceManager->AddRef(); - } - } else { - hr = MF_E_UNSUPPORTED_SERVICE; - } - - return hr; -} - -HRESULT D3DPresentEngine::checkFormat(D3DFORMAT format) -{ - if (!m_D3D9 || !m_device) - return E_FAIL; - - HRESULT hr = S_OK; - - D3DDISPLAYMODE mode; - D3DDEVICE_CREATION_PARAMETERS params; - - hr = m_device->GetCreationParameters(¶ms); - if (FAILED(hr)) - return hr; - - UINT uAdapter = params.AdapterOrdinal; - D3DDEVTYPE type = params.DeviceType; - - hr = m_D3D9->GetAdapterDisplayMode(uAdapter, &mode); - if (FAILED(hr)) - return hr; - - hr = m_D3D9->CheckDeviceFormat(uAdapter, type, mode.Format, - D3DUSAGE_RENDERTARGET, - D3DRTYPE_SURFACE, - format); - - if (m_useTextureRendering && format != D3DFMT_X8R8G8B8 && format != D3DFMT_A8R8G8B8) { - // The texture is always in RGB32 so the d3d driver must support conversion from the - // requested format to RGB32. - hr = m_D3D9->CheckDeviceFormatConversion(uAdapter, type, format, D3DFMT_X8R8G8B8); - } - - return hr; -} - -bool D3DPresentEngine::supportsTextureRendering() const -{ - return false; -} - -void D3DPresentEngine::setHint(Hint hint, bool enable) -{ - if (hint == RenderToTexture) - m_useTextureRendering = enable && supportsTextureRendering(); -} - -HRESULT D3DPresentEngine::createVideoSamples(IMFMediaType *format, QList<IMFSample*> &videoSampleQueue) -{ - if (!format) - return MF_E_UNEXPECTED; - - HRESULT hr = S_OK; - - IDirect3DSurface9 *surface = NULL; - IMFSample *videoSample = NULL; - - releaseResources(); - - UINT32 width = 0, height = 0; - hr = MFGetAttributeSize(format, MF_MT_FRAME_SIZE, &width, &height); - if (FAILED(hr)) - return hr; - - DWORD d3dFormat = 0; - hr = qt_evr_getFourCC(format, &d3dFormat); - if (FAILED(hr)) - return hr; - - // Create the video samples. - for (int i = 0; i < PRESENTER_BUFFER_COUNT; i++) { - hr = m_device->CreateRenderTarget(width, height, - (D3DFORMAT)d3dFormat, - D3DMULTISAMPLE_NONE, - 0, - TRUE, - &surface, NULL); - if (FAILED(hr)) - goto done; - - hr = MFCreateVideoSampleFromSurface(surface, &videoSample); - if (FAILED(hr)) - goto done; - - videoSample->AddRef(); - videoSampleQueue.append(videoSample); - - qt_evr_safe_release(&videoSample); - qt_evr_safe_release(&surface); - } - -done: - if (SUCCEEDED(hr)) { - m_surfaceFormat = QVideoSurfaceFormat(QSize(width, height), - m_useTextureRendering ? QVideoFrame::Format_RGB32 - : qt_evr_pixelFormatFromD3DFormat(d3dFormat), - m_useTextureRendering ? QAbstractVideoBuffer::GLTextureHandle - : QAbstractVideoBuffer::NoHandle); - UINT32 horizontal = 1, vertical = 1; - hr = MFGetAttributeRatio(format, MF_MT_PIXEL_ASPECT_RATIO, &horizontal, &vertical); - if (SUCCEEDED(hr)) - m_surfaceFormat.setPixelAspectRatio(horizontal, vertical); - } else { - releaseResources(); - } - - qt_evr_safe_release(&videoSample); - qt_evr_safe_release(&surface); - return hr; -} - -QVideoFrame D3DPresentEngine::makeVideoFrame(IMFSample *sample) -{ - if (!sample) - return QVideoFrame(); - - QVideoFrame frame(new IMFSampleVideoBuffer(this, sample, m_surfaceFormat.handleType()), - m_surfaceFormat.frameSize(), - m_surfaceFormat.pixelFormat()); - - // WMF uses 100-nanosecond units, Qt uses microseconds - LONGLONG startTime = 0; - auto hr = sample->GetSampleTime(&startTime); - if (SUCCEEDED(hr)) { - frame.setStartTime(startTime * 0.1); - - LONGLONG duration = -1; - if (SUCCEEDED(sample->GetSampleDuration(&duration))) - frame.setEndTime((startTime + duration) * 0.1); - } - - return frame; -} - -QT_END_NAMESPACE diff --git a/src/plugins/common/evr/evrd3dpresentengine.h b/src/plugins/common/evr/evrd3dpresentengine.h deleted file mode 100644 index eb2def7b2..000000000 --- a/src/plugins/common/evr/evrd3dpresentengine.h +++ /dev/null @@ -1,152 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef EVRD3DPRESENTENGINE_H -#define EVRD3DPRESENTENGINE_H - -#include <QMutex> -#include <QVideoSurfaceFormat> - -#include <d3d9.h> - -struct IDirect3D9Ex; -struct IDirect3DDevice9Ex; -struct IDirect3DDeviceManager9; -struct IDirect3DSurface9; -struct IDirect3DTexture9; -struct IMFSample; -struct IMFMediaType; - -// Randomly generated GUIDs -static const GUID MFSamplePresenter_SampleCounter = -{ 0xb0bb83cc, 0xf10f, 0x4e2e, { 0xaa, 0x2b, 0x29, 0xea, 0x5e, 0x92, 0xef, 0x85 } }; - -QT_BEGIN_NAMESPACE - -class QAbstractVideoSurface; - -#ifdef MAYBE_ANGLE - -class OpenGLResources; - -class EGLWrapper -{ - Q_DISABLE_COPY(EGLWrapper) -public: - EGLWrapper(); - - __eglMustCastToProperFunctionPointerType getProcAddress(const char *procname); - EGLSurface createPbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); - EGLBoolean destroySurface(EGLDisplay dpy, EGLSurface surface); - EGLBoolean bindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer); - EGLBoolean releaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer); - -private: - typedef __eglMustCastToProperFunctionPointerType (EGLAPIENTRYP EglGetProcAddress)(const char *procname); - typedef EGLSurface (EGLAPIENTRYP EglCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); - typedef EGLBoolean (EGLAPIENTRYP EglDestroySurface)(EGLDisplay dpy, EGLSurface surface); - typedef EGLBoolean (EGLAPIENTRYP EglBindTexImage)(EGLDisplay dpy, EGLSurface surface, EGLint buffer); - typedef EGLBoolean (EGLAPIENTRYP EglReleaseTexImage)(EGLDisplay dpy, EGLSurface surface, EGLint buffer); - - EglGetProcAddress m_eglGetProcAddress; - EglCreatePbufferSurface m_eglCreatePbufferSurface; - EglDestroySurface m_eglDestroySurface; - EglBindTexImage m_eglBindTexImage; - EglReleaseTexImage m_eglReleaseTexImage; -}; - -#endif // MAYBE_ANGLE - -class D3DPresentEngine -{ - Q_DISABLE_COPY(D3DPresentEngine) -public: - enum Hint - { - RenderToTexture - }; - - D3DPresentEngine(); - virtual ~D3DPresentEngine(); - - bool isValid() const; - void setHint(Hint hint, bool enable = true); - - HRESULT getService(REFGUID guidService, REFIID riid, void** ppv); - HRESULT checkFormat(D3DFORMAT format); - UINT refreshRate() const { return m_displayMode.RefreshRate; } - - bool supportsTextureRendering() const; - bool isTextureRenderingEnabled() const { return m_useTextureRendering; } - - HRESULT createVideoSamples(IMFMediaType *format, QList<IMFSample*>& videoSampleQueue); - QVideoSurfaceFormat videoSurfaceFormat() const { return m_surfaceFormat; } - QVideoFrame makeVideoFrame(IMFSample* sample); - - void releaseResources(); - -private: - HRESULT initializeD3D(); - HRESULT createD3DDevice(); - - - UINT m_deviceResetToken; - D3DDISPLAYMODE m_displayMode; - - IDirect3D9Ex *m_D3D9; - IDirect3DDevice9Ex *m_device; - IDirect3DDeviceManager9 *m_deviceManager; - - QVideoSurfaceFormat m_surfaceFormat; - - bool m_useTextureRendering; - -#ifdef MAYBE_ANGLE - unsigned int updateTexture(IDirect3DSurface9 *src); - - OpenGLResources *m_glResources; - IDirect3DTexture9 *m_texture; -#endif - - friend class IMFSampleVideoBuffer; -}; - -QT_END_NAMESPACE - -#endif // EVRD3DPRESENTENGINE_H diff --git a/src/plugins/common/evr/evrdefs.cpp b/src/plugins/common/evr/evrdefs.cpp deleted file mode 100644 index e143ada0b..000000000 --- a/src/plugins/common/evr/evrdefs.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "evrdefs.h" - -const CLSID clsid_EnhancedVideoRenderer = { 0xfa10746c, 0x9b63, 0x4b6c, {0xbc, 0x49, 0xfc, 0x30, 0xe, 0xa5, 0xf2, 0x56} }; -const GUID mr_VIDEO_RENDER_SERVICE = { 0x1092a86c, 0xab1a, 0x459a, {0xa3, 0x36, 0x83, 0x1f, 0xbc, 0x4d, 0x11, 0xff} }; -const GUID mr_VIDEO_MIXER_SERVICE = { 0x73cd2fc, 0x6cf4, 0x40b7, {0x88, 0x59, 0xe8, 0x95, 0x52, 0xc8, 0x41, 0xf8} }; -const GUID mr_BUFFER_SERVICE = { 0xa562248c, 0x9ac6, 0x4ffc, {0x9f, 0xba, 0x3a, 0xf8, 0xf8, 0xad, 0x1a, 0x4d} }; -const GUID video_ZOOM_RECT = { 0x7aaa1638, 0x1b7f, 0x4c93, {0xbd, 0x89, 0x5b, 0x9c, 0x9f, 0xb6, 0xfc, 0xf0} }; -const GUID iid_IDirect3DDevice9 = { 0xd0223b96, 0xbf7a, 0x43fd, {0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb} }; -const GUID iid_IDirect3DSurface9 = { 0xcfbaf3a, 0x9ff6, 0x429a, {0x99, 0xb3, 0xa2, 0x79, 0x6a, 0xf8, 0xb8, 0x9b} }; diff --git a/src/plugins/common/evr/evrdefs.h b/src/plugins/common/evr/evrdefs.h deleted file mode 100644 index 4f3dd832a..000000000 --- a/src/plugins/common/evr/evrdefs.h +++ /dev/null @@ -1,353 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef EVRDEFS_H -#define EVRDEFS_H - -#include <d3d9.h> -#include <evr9.h> -#include <evr.h> -#include <dxva2api.h> -#include <mfapi.h> -#include <mfidl.h> -#include <mferror.h> - -extern const CLSID clsid_EnhancedVideoRenderer; -extern const GUID mr_VIDEO_RENDER_SERVICE; -extern const GUID mr_VIDEO_MIXER_SERVICE; -extern const GUID mr_BUFFER_SERVICE; -extern const GUID video_ZOOM_RECT; -extern const GUID iid_IDirect3DDevice9; -extern const GUID iid_IDirect3DSurface9; - -// The following is required to compile with MinGW - -extern "C" { -HRESULT WINAPI MFCreateVideoSampleFromSurface(IUnknown *pUnkSurface, IMFSample **ppSample); -HRESULT WINAPI Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex**); -} - -#ifndef PRESENTATION_CURRENT_POSITION -#define PRESENTATION_CURRENT_POSITION 0x7fffffffffffffff -#endif - -#ifndef MF_E_SHUTDOWN -#define MF_E_SHUTDOWN ((HRESULT)0xC00D3E85L) -#endif - -#ifndef MF_E_SAMPLEALLOCATOR_EMPTY -#define MF_E_SAMPLEALLOCATOR_EMPTY ((HRESULT)0xC00D4A3EL) -#endif - -#ifndef MF_E_TRANSFORM_STREAM_CHANGE -#define MF_E_TRANSFORM_STREAM_CHANGE ((HRESULT)0xC00D6D61L) -#endif - -#ifndef MF_E_TRANSFORM_NEED_MORE_INPUT -#define MF_E_TRANSFORM_NEED_MORE_INPUT ((HRESULT)0xC00D6D72L) -#endif - -#if defined(__GNUC__) && !defined(_MFVideoNormalizedRect_) -#define _MFVideoNormalizedRect_ -typedef struct MFVideoNormalizedRect { - float left; - float top; - float right; - float bottom; -} MFVideoNormalizedRect; -#endif - -#include <initguid.h> - -#ifndef __IMFGetService_INTERFACE_DEFINED__ -#define __IMFGetService_INTERFACE_DEFINED__ -DEFINE_GUID(IID_IMFGetService, 0xfa993888, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7); -MIDL_INTERFACE("fa993888-4383-415a-a930-dd472a8cf6f7") -IMFGetService : public IUnknown -{ - virtual HRESULT STDMETHODCALLTYPE GetService(REFGUID, REFIID, LPVOID *) = 0; -}; -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IMFGetService, 0xfa993888, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7) -#endif -#endif // __IMFGetService_INTERFACE_DEFINED__ - -#ifndef __IMFVideoDisplayControl_INTERFACE_DEFINED__ -#define __IMFVideoDisplayControl_INTERFACE_DEFINED__ -typedef enum MFVideoAspectRatioMode -{ - MFVideoARMode_None = 0, - MFVideoARMode_PreservePicture = 0x1, - MFVideoARMode_PreservePixel = 0x2, - MFVideoARMode_NonLinearStretch = 0x4, - MFVideoARMode_Mask = 0x7 -} MFVideoAspectRatioMode; - -DEFINE_GUID(IID_IMFVideoDisplayControl, 0xa490b1e4, 0xab84, 0x4d31, 0xa1,0xb2, 0x18,0x1e,0x03,0xb1,0x07,0x7a); -MIDL_INTERFACE("a490b1e4-ab84-4d31-a1b2-181e03b1077a") -IMFVideoDisplayControl : public IUnknown -{ - virtual HRESULT STDMETHODCALLTYPE GetNativeVideoSize(SIZE *, SIZE *) = 0; - virtual HRESULT STDMETHODCALLTYPE GetIdealVideoSize(SIZE *, SIZE *) = 0; - virtual HRESULT STDMETHODCALLTYPE SetVideoPosition(const MFVideoNormalizedRect *, const LPRECT) = 0; - virtual HRESULT STDMETHODCALLTYPE GetVideoPosition(MFVideoNormalizedRect *, LPRECT) = 0; - virtual HRESULT STDMETHODCALLTYPE SetAspectRatioMode(DWORD) = 0; - virtual HRESULT STDMETHODCALLTYPE GetAspectRatioMode(DWORD *) = 0; - virtual HRESULT STDMETHODCALLTYPE SetVideoWindow(HWND) = 0; - virtual HRESULT STDMETHODCALLTYPE GetVideoWindow(HWND *) = 0; - virtual HRESULT STDMETHODCALLTYPE RepaintVideo(void) = 0; - virtual HRESULT STDMETHODCALLTYPE GetCurrentImage(BITMAPINFOHEADER *, BYTE **, DWORD *, LONGLONG *) = 0; - virtual HRESULT STDMETHODCALLTYPE SetBorderColor(COLORREF) = 0; - virtual HRESULT STDMETHODCALLTYPE GetBorderColor(COLORREF *) = 0; - virtual HRESULT STDMETHODCALLTYPE SetRenderingPrefs(DWORD) = 0; - virtual HRESULT STDMETHODCALLTYPE GetRenderingPrefs(DWORD *) = 0; - virtual HRESULT STDMETHODCALLTYPE SetFullscreen(BOOL) = 0; - virtual HRESULT STDMETHODCALLTYPE GetFullscreen(BOOL *) = 0; -}; -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IMFVideoDisplayControl, 0xa490b1e4, 0xab84, 0x4d31, 0xa1,0xb2, 0x18,0x1e,0x03,0xb1,0x07,0x7a) -#endif -#endif // __IMFVideoDisplayControl_INTERFACE_DEFINED__ - -#ifndef __IMFVideoProcessor_INTERFACE_DEFINED__ -#define __IMFVideoProcessor_INTERFACE_DEFINED__ -DEFINE_GUID(IID_IMFVideoProcessor, 0x6AB0000C, 0xFECE, 0x4d1f, 0xA2,0xAC, 0xA9,0x57,0x35,0x30,0x65,0x6E); -MIDL_INTERFACE("6AB0000C-FECE-4d1f-A2AC-A9573530656E") -IMFVideoProcessor : public IUnknown -{ - virtual HRESULT STDMETHODCALLTYPE GetAvailableVideoProcessorModes(UINT *, GUID **) = 0; - virtual HRESULT STDMETHODCALLTYPE GetVideoProcessorCaps(LPGUID, DXVA2_VideoProcessorCaps *) = 0; - virtual HRESULT STDMETHODCALLTYPE GetVideoProcessorMode(LPGUID) = 0; - virtual HRESULT STDMETHODCALLTYPE SetVideoProcessorMode(LPGUID) = 0; - virtual HRESULT STDMETHODCALLTYPE GetProcAmpRange(DWORD, DXVA2_ValueRange *) = 0; - virtual HRESULT STDMETHODCALLTYPE GetProcAmpValues(DWORD, DXVA2_ProcAmpValues *) = 0; - virtual HRESULT STDMETHODCALLTYPE SetProcAmpValues(DWORD, DXVA2_ProcAmpValues *) = 0; - virtual HRESULT STDMETHODCALLTYPE GetFilteringRange(DWORD, DXVA2_ValueRange *) = 0; - virtual HRESULT STDMETHODCALLTYPE GetFilteringValue(DWORD, DXVA2_Fixed32 *) = 0; - virtual HRESULT STDMETHODCALLTYPE SetFilteringValue(DWORD, DXVA2_Fixed32 *) = 0; - virtual HRESULT STDMETHODCALLTYPE GetBackgroundColor(COLORREF *) = 0; - virtual HRESULT STDMETHODCALLTYPE SetBackgroundColor(COLORREF) = 0; -}; -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IMFVideoProcessor, 0x6AB0000C, 0xFECE, 0x4d1f, 0xA2,0xAC, 0xA9,0x57,0x35,0x30,0x65,0x6E) -#endif -#endif // __IMFVideoProcessor_INTERFACE_DEFINED__ - -#ifndef __IMFVideoDeviceID_INTERFACE_DEFINED__ -#define __IMFVideoDeviceID_INTERFACE_DEFINED__ -DEFINE_GUID(IID_IMFVideoDeviceID, 0xA38D9567, 0x5A9C, 0x4f3c, 0xB2,0x93, 0x8E,0xB4,0x15,0xB2,0x79,0xBA); -MIDL_INTERFACE("A38D9567-5A9C-4f3c-B293-8EB415B279BA") -IMFVideoDeviceID : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE GetDeviceID(IID *pDeviceID) = 0; -}; -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IMFVideoDeviceID, 0xA38D9567, 0x5A9C, 0x4f3c, 0xB2,0x93, 0x8E,0xB4,0x15,0xB2,0x79,0xBA) -#endif -#endif // __IMFVideoDeviceID_INTERFACE_DEFINED__ - -#ifndef __IMFClockStateSink_INTERFACE_DEFINED__ -#define __IMFClockStateSink_INTERFACE_DEFINED__ -DEFINE_GUID(IID_IMFClockStateSink, 0xF6696E82, 0x74F7, 0x4f3d, 0xA1,0x78, 0x8A,0x5E,0x09,0xC3,0x65,0x9F); -MIDL_INTERFACE("F6696E82-74F7-4f3d-A178-8A5E09C3659F") -IMFClockStateSink : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset) = 0; - virtual HRESULT STDMETHODCALLTYPE OnClockStop(MFTIME hnsSystemTime) = 0; - virtual HRESULT STDMETHODCALLTYPE OnClockPause(MFTIME hnsSystemTime) = 0; - virtual HRESULT STDMETHODCALLTYPE OnClockRestart(MFTIME hnsSystemTime) = 0; - virtual HRESULT STDMETHODCALLTYPE OnClockSetRate(MFTIME hnsSystemTime, float flRate) = 0; -}; -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IMFClockStateSink, 0xF6696E82, 0x74F7, 0x4f3d, 0xA1,0x78, 0x8A,0x5E,0x09,0xC3,0x65,0x9F) -#endif -#endif // __IMFClockStateSink_INTERFACE_DEFINED__ - -#ifndef __IMFVideoPresenter_INTERFACE_DEFINED__ -#define __IMFVideoPresenter_INTERFACE_DEFINED__ -typedef enum MFVP_MESSAGE_TYPE -{ - MFVP_MESSAGE_FLUSH = 0, - MFVP_MESSAGE_INVALIDATEMEDIATYPE = 0x1, - MFVP_MESSAGE_PROCESSINPUTNOTIFY = 0x2, - MFVP_MESSAGE_BEGINSTREAMING = 0x3, - MFVP_MESSAGE_ENDSTREAMING = 0x4, - MFVP_MESSAGE_ENDOFSTREAM = 0x5, - MFVP_MESSAGE_STEP = 0x6, - MFVP_MESSAGE_CANCELSTEP = 0x7 -} MFVP_MESSAGE_TYPE; - -DEFINE_GUID(IID_IMFVideoPresenter, 0x29AFF080, 0x182A, 0x4a5d, 0xAF,0x3B, 0x44,0x8F,0x3A,0x63,0x46,0xCB); -MIDL_INTERFACE("29AFF080-182A-4a5d-AF3B-448F3A6346CB") -IMFVideoPresenter : public IMFClockStateSink -{ -public: - virtual HRESULT STDMETHODCALLTYPE ProcessMessage(MFVP_MESSAGE_TYPE eMessage, ULONG_PTR ulParam) = 0; - virtual HRESULT STDMETHODCALLTYPE GetCurrentMediaType(IMFVideoMediaType **ppMediaType) = 0; -}; -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IMFVideoPresenter, 0x29AFF080, 0x182A, 0x4a5d, 0xAF,0x3B, 0x44,0x8F,0x3A,0x63,0x46,0xCB) -#endif -#endif // __IMFVideoPresenter_INTERFACE_DEFINED__ - -#ifndef __IMFRateSupport_INTERFACE_DEFINED__ -#define __IMFRateSupport_INTERFACE_DEFINED__ -DEFINE_GUID(IID_IMFRateSupport, 0x0a9ccdbc, 0xd797, 0x4563, 0x96,0x67, 0x94,0xec,0x5d,0x79,0x29,0x2d); -MIDL_INTERFACE("0a9ccdbc-d797-4563-9667-94ec5d79292d") -IMFRateSupport : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE GetSlowestRate(MFRATE_DIRECTION eDirection, BOOL fThin, float *pflRate) = 0; - virtual HRESULT STDMETHODCALLTYPE GetFastestRate(MFRATE_DIRECTION eDirection, BOOL fThin, float *pflRate) = 0; - virtual HRESULT STDMETHODCALLTYPE IsRateSupported(BOOL fThin, float flRate, float *pflNearestSupportedRate) = 0; -}; -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IMFRateSupport, 0x0a9ccdbc, 0xd797, 0x4563, 0x96,0x67, 0x94,0xec,0x5d,0x79,0x29,0x2d) -#endif -#endif // __IMFRateSupport_INTERFACE_DEFINED__ - -#ifndef __IMFTopologyServiceLookup_INTERFACE_DEFINED__ -#define __IMFTopologyServiceLookup_INTERFACE_DEFINED__ -typedef enum _MF_SERVICE_LOOKUP_TYPE -{ - MF_SERVICE_LOOKUP_UPSTREAM = 0, - MF_SERVICE_LOOKUP_UPSTREAM_DIRECT = (MF_SERVICE_LOOKUP_UPSTREAM + 1), - MF_SERVICE_LOOKUP_DOWNSTREAM = (MF_SERVICE_LOOKUP_UPSTREAM_DIRECT + 1), - MF_SERVICE_LOOKUP_DOWNSTREAM_DIRECT = (MF_SERVICE_LOOKUP_DOWNSTREAM + 1), - MF_SERVICE_LOOKUP_ALL = (MF_SERVICE_LOOKUP_DOWNSTREAM_DIRECT + 1), - MF_SERVICE_LOOKUP_GLOBAL = (MF_SERVICE_LOOKUP_ALL + 1) -} MF_SERVICE_LOOKUP_TYPE; - -DEFINE_GUID(IID_IMFTopologyServiceLookup, 0xfa993889, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7); -MIDL_INTERFACE("fa993889-4383-415a-a930-dd472a8cf6f7") -IMFTopologyServiceLookup : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE LookupService(MF_SERVICE_LOOKUP_TYPE Type, - DWORD dwIndex, - REFGUID guidService, - REFIID riid, - LPVOID *ppvObjects, - DWORD *pnObjects) = 0; -}; -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IMFTopologyServiceLookup, 0xfa993889, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7) -#endif -#endif // __IMFTopologyServiceLookup_INTERFACE_DEFINED__ - -#ifndef __IMFTopologyServiceLookupClient_INTERFACE_DEFINED__ -#define __IMFTopologyServiceLookupClient_INTERFACE_DEFINED__ -DEFINE_GUID(IID_IMFTopologyServiceLookupClient, 0xfa99388a, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7); -MIDL_INTERFACE("fa99388a-4383-415a-a930-dd472a8cf6f7") -IMFTopologyServiceLookupClient : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE InitServicePointers(IMFTopologyServiceLookup *pLookup) = 0; - virtual HRESULT STDMETHODCALLTYPE ReleaseServicePointers(void) = 0; -}; -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IMFTopologyServiceLookupClient, 0xfa99388a, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7) -#endif -#endif // __IMFTopologyServiceLookupClient_INTERFACE_DEFINED__ - -#ifndef __IMediaEventSink_INTERFACE_DEFINED__ -#define __IMediaEventSink_INTERFACE_DEFINED__ -DEFINE_GUID(IID_IMediaEventSink, 0x56a868a2, 0x0ad4, 0x11ce, 0xb0,0x3a, 0x00,0x20,0xaf,0x0b,0xa7,0x70); -MIDL_INTERFACE("56a868a2-0ad4-11ce-b03a-0020af0ba770") -IMediaEventSink : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE Notify(long EventCode, LONG_PTR EventParam1, LONG_PTR EventParam2) = 0; -}; -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IMediaEventSink, 0x56a868a2, 0x0ad4, 0x11ce, 0xb0,0x3a, 0x00,0x20,0xaf,0x0b,0xa7,0x70) -#endif -#endif // __IMediaEventSink_INTERFACE_DEFINED__ - -#ifndef __IMFVideoRenderer_INTERFACE_DEFINED__ -#define __IMFVideoRenderer_INTERFACE_DEFINED__ -DEFINE_GUID(IID_IMFVideoRenderer, 0xDFDFD197, 0xA9CA, 0x43d8, 0xB3,0x41, 0x6A,0xF3,0x50,0x37,0x92,0xCD); -MIDL_INTERFACE("DFDFD197-A9CA-43d8-B341-6AF3503792CD") -IMFVideoRenderer : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE InitializeRenderer(IMFTransform *pVideoMixer, - IMFVideoPresenter *pVideoPresenter) = 0; -}; -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IMFVideoRenderer, 0xDFDFD197, 0xA9CA, 0x43d8, 0xB3,0x41, 0x6A,0xF3,0x50,0x37,0x92,0xCD) -#endif -#endif // __IMFVideoRenderer_INTERFACE_DEFINED__ - -#ifndef __IMFTrackedSample_INTERFACE_DEFINED__ -#define __IMFTrackedSample_INTERFACE_DEFINED__ -DEFINE_GUID(IID_IMFTrackedSample, 0x245BF8E9, 0x0755, 0x40f7, 0x88,0xA5, 0xAE,0x0F,0x18,0xD5,0x5E,0x17); -MIDL_INTERFACE("245BF8E9-0755-40f7-88A5-AE0F18D55E17") -IMFTrackedSample : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE SetAllocator(IMFAsyncCallback *pSampleAllocator, IUnknown *pUnkState) = 0; -}; -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IMFTrackedSample, 0x245BF8E9, 0x0755, 0x40f7, 0x88,0xA5, 0xAE,0x0F,0x18,0xD5,0x5E,0x17) -#endif -#endif // __IMFTrackedSample_INTERFACE_DEFINED__ - -#ifndef __IMFDesiredSample_INTERFACE_DEFINED__ -#define __IMFDesiredSample_INTERFACE_DEFINED__ -DEFINE_GUID(IID_IMFDesiredSample, 0x56C294D0, 0x753E, 0x4260, 0x8D,0x61, 0xA3,0xD8,0x82,0x0B,0x1D,0x54); -MIDL_INTERFACE("56C294D0-753E-4260-8D61-A3D8820B1D54") -IMFDesiredSample : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE GetDesiredSampleTimeAndDuration(LONGLONG *phnsSampleTime, - LONGLONG *phnsSampleDuration) = 0; - virtual void STDMETHODCALLTYPE SetDesiredSampleTimeAndDuration(LONGLONG hnsSampleTime, - LONGLONG hnsSampleDuration) = 0; - virtual void STDMETHODCALLTYPE Clear( void) = 0; -}; -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IMFDesiredSample, 0x56C294D0, 0x753E, 0x4260, 0x8D,0x61, 0xA3,0xD8,0x82,0x0B,0x1D,0x54) -#endif -#endif - -#endif // EVRDEFS_H - diff --git a/src/plugins/common/evr/evrhelpers.cpp b/src/plugins/common/evr/evrhelpers.cpp deleted file mode 100644 index a315f1a73..000000000 --- a/src/plugins/common/evr/evrhelpers.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "evrhelpers.h" - -#ifndef D3DFMT_YV12 -#define D3DFMT_YV12 (D3DFORMAT)MAKEFOURCC ('Y', 'V', '1', '2') -#endif -#ifndef D3DFMT_NV12 -#define D3DFMT_NV12 (D3DFORMAT)MAKEFOURCC ('N', 'V', '1', '2') -#endif - -QT_BEGIN_NAMESPACE - -HRESULT qt_evr_getFourCC(IMFMediaType *type, DWORD *fourCC) -{ - if (!fourCC) - return E_POINTER; - - HRESULT hr = S_OK; - GUID guidSubType = GUID_NULL; - - if (SUCCEEDED(hr)) - hr = type->GetGUID(MF_MT_SUBTYPE, &guidSubType); - - if (SUCCEEDED(hr)) - *fourCC = guidSubType.Data1; - - return hr; -} - -bool qt_evr_areMediaTypesEqual(IMFMediaType *type1, IMFMediaType *type2) -{ - if (!type1 && !type2) - return true; - if (!type1 || !type2) - return false; - - DWORD dwFlags = 0; - HRESULT hr = type1->IsEqual(type2, &dwFlags); - - return (hr == S_OK); -} - -HRESULT qt_evr_validateVideoArea(const MFVideoArea& area, UINT32 width, UINT32 height) -{ - float fOffsetX = qt_evr_MFOffsetToFloat(area.OffsetX); - float fOffsetY = qt_evr_MFOffsetToFloat(area.OffsetY); - - if ( ((LONG)fOffsetX + area.Area.cx > (LONG)width) || - ((LONG)fOffsetY + area.Area.cy > (LONG)height) ) { - return MF_E_INVALIDMEDIATYPE; - } - return S_OK; -} - -bool qt_evr_isSampleTimePassed(IMFClock *clock, IMFSample *sample) -{ - if (!sample || !clock) - return false; - - HRESULT hr = S_OK; - MFTIME hnsTimeNow = 0; - MFTIME hnsSystemTime = 0; - MFTIME hnsSampleStart = 0; - MFTIME hnsSampleDuration = 0; - - hr = clock->GetCorrelatedTime(0, &hnsTimeNow, &hnsSystemTime); - - if (SUCCEEDED(hr)) - hr = sample->GetSampleTime(&hnsSampleStart); - - if (SUCCEEDED(hr)) - hr = sample->GetSampleDuration(&hnsSampleDuration); - - if (SUCCEEDED(hr)) { - if (hnsSampleStart + hnsSampleDuration < hnsTimeNow) - return true; - } - - return false; -} - -QVideoFrame::PixelFormat qt_evr_pixelFormatFromD3DFormat(DWORD format) -{ - switch (format) { - case D3DFMT_R8G8B8: - return QVideoFrame::Format_RGB24; - case D3DFMT_A8R8G8B8: - return QVideoFrame::Format_ARGB32; - case D3DFMT_X8R8G8B8: - return QVideoFrame::Format_RGB32; - case D3DFMT_R5G6B5: - return QVideoFrame::Format_RGB565; - case D3DFMT_X1R5G5B5: - return QVideoFrame::Format_RGB555; - case D3DFMT_A8: - return QVideoFrame::Format_Y8; - case D3DFMT_A8B8G8R8: - return QVideoFrame::Format_BGRA32; - case D3DFMT_X8B8G8R8: - return QVideoFrame::Format_BGR32; - case D3DFMT_UYVY: - return QVideoFrame::Format_UYVY; - case D3DFMT_YUY2: - return QVideoFrame::Format_YUYV; - case D3DFMT_NV12: - return QVideoFrame::Format_NV12; - case D3DFMT_YV12: - return QVideoFrame::Format_YV12; - case D3DFMT_UNKNOWN: - default: - return QVideoFrame::Format_Invalid; - } -} - -D3DFORMAT qt_evr_D3DFormatFromPixelFormat(QVideoFrame::PixelFormat format) -{ - switch (format) { - case QVideoFrame::Format_RGB24: - return D3DFMT_R8G8B8; - case QVideoFrame::Format_ARGB32: - return D3DFMT_A8R8G8B8; - case QVideoFrame::Format_RGB32: - return D3DFMT_X8R8G8B8; - case QVideoFrame::Format_RGB565: - return D3DFMT_R5G6B5; - case QVideoFrame::Format_RGB555: - return D3DFMT_X1R5G5B5; - case QVideoFrame::Format_Y8: - return D3DFMT_A8; - case QVideoFrame::Format_BGRA32: - return D3DFMT_A8B8G8R8; - case QVideoFrame::Format_BGR32: - return D3DFMT_X8B8G8R8; - case QVideoFrame::Format_UYVY: - return D3DFMT_UYVY; - case QVideoFrame::Format_YUYV: - return D3DFMT_YUY2; - case QVideoFrame::Format_NV12: - return D3DFMT_NV12; - case QVideoFrame::Format_YV12: - return D3DFMT_YV12; - case QVideoFrame::Format_Invalid: - default: - return D3DFMT_UNKNOWN; - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/common/evr/evrhelpers.h b/src/plugins/common/evr/evrhelpers.h deleted file mode 100644 index b5bdf5ead..000000000 --- a/src/plugins/common/evr/evrhelpers.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef EVRHELPERS_H -#define EVRHELPERS_H - -#include "evrdefs.h" -#include <qvideoframe.h> - -QT_BEGIN_NAMESPACE - -template<class T> -static inline void qt_evr_safe_release(T **unk) -{ - if (*unk) { - (*unk)->Release(); - *unk = NULL; - } -} - -HRESULT qt_evr_getFourCC(IMFMediaType *type, DWORD *fourCC); - -bool qt_evr_areMediaTypesEqual(IMFMediaType *type1, IMFMediaType *type2); - -HRESULT qt_evr_validateVideoArea(const MFVideoArea& area, UINT32 width, UINT32 height); - -bool qt_evr_isSampleTimePassed(IMFClock *clock, IMFSample *sample); - -inline float qt_evr_MFOffsetToFloat(const MFOffset& offset) -{ - return offset.value + (float(offset.fract) / 65536); -} - -inline MFOffset qt_evr_makeMFOffset(float v) -{ - MFOffset offset; - offset.value = short(v); - offset.fract = WORD(65536 * (v-offset.value)); - return offset; -} - -inline MFVideoArea qt_evr_makeMFArea(float x, float y, DWORD width, DWORD height) -{ - MFVideoArea area; - area.OffsetX = qt_evr_makeMFOffset(x); - area.OffsetY = qt_evr_makeMFOffset(y); - area.Area.cx = width; - area.Area.cy = height; - return area; -} - -inline HRESULT qt_evr_getFrameRate(IMFMediaType *pType, MFRatio *pRatio) -{ - return MFGetAttributeRatio(pType, MF_MT_FRAME_RATE, - reinterpret_cast<UINT32*>(&pRatio->Numerator), - reinterpret_cast<UINT32*>(&pRatio->Denominator)); -} - -QVideoFrame::PixelFormat qt_evr_pixelFormatFromD3DFormat(DWORD format); -D3DFORMAT qt_evr_D3DFormatFromPixelFormat(QVideoFrame::PixelFormat format); - -QT_END_NAMESPACE - -#endif // EVRHELPERS_H - diff --git a/src/plugins/common/evr/evrvideowindowcontrol.cpp b/src/plugins/common/evr/evrvideowindowcontrol.cpp deleted file mode 100644 index 95f63c2e7..000000000 --- a/src/plugins/common/evr/evrvideowindowcontrol.cpp +++ /dev/null @@ -1,362 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "evrvideowindowcontrol.h" - -#ifndef QT_NO_WIDGETS -#include <qwidget.h> -#endif - -EvrVideoWindowControl::EvrVideoWindowControl(QObject *parent) - : QVideoWindowControl(parent) - , m_windowId(0) - , m_windowColor(RGB(0, 0, 0)) - , m_dirtyValues(0) - , m_aspectRatioMode(Qt::KeepAspectRatio) - , m_brightness(0) - , m_contrast(0) - , m_hue(0) - , m_saturation(0) - , m_fullScreen(false) - , m_displayControl(0) - , m_processor(0) -{ -} - -EvrVideoWindowControl::~EvrVideoWindowControl() -{ - clear(); -} - -bool EvrVideoWindowControl::setEvr(IUnknown *evr) -{ - clear(); - - if (!evr) - return true; - - IMFGetService *service = NULL; - - if (SUCCEEDED(evr->QueryInterface(IID_PPV_ARGS(&service))) - && SUCCEEDED(service->GetService(mr_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_displayControl)))) { - - service->GetService(mr_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_processor)); - - setWinId(m_windowId); - setDisplayRect(m_displayRect); - setAspectRatioMode(m_aspectRatioMode); - m_dirtyValues = DXVA2_ProcAmp_Brightness | DXVA2_ProcAmp_Contrast | DXVA2_ProcAmp_Hue | DXVA2_ProcAmp_Saturation; - applyImageControls(); - } - - if (service) - service->Release(); - - return m_displayControl != NULL; -} - -void EvrVideoWindowControl::clear() -{ - if (m_displayControl) - m_displayControl->Release(); - m_displayControl = NULL; - - if (m_processor) - m_processor->Release(); - m_processor = NULL; -} - -WId EvrVideoWindowControl::winId() const -{ - return m_windowId; -} - -void EvrVideoWindowControl::setWinId(WId id) -{ - m_windowId = id; - -#ifndef QT_NO_WIDGETS - if (QWidget *widget = QWidget::find(m_windowId)) { - const QColor color = widget->palette().color(QPalette::Window); - - m_windowColor = RGB(color.red(), color.green(), color.blue()); - } -#endif - - if (m_displayControl) - m_displayControl->SetVideoWindow(HWND(m_windowId)); -} - -QRect EvrVideoWindowControl::displayRect() const -{ - return m_displayRect; -} - -void EvrVideoWindowControl::setDisplayRect(const QRect &rect) -{ - m_displayRect = rect; - - if (m_displayControl) { - RECT displayRect = { rect.left(), rect.top(), rect.right() + 1, rect.bottom() + 1 }; - QSize sourceSize = nativeSize(); - - RECT sourceRect = { 0, 0, sourceSize.width(), sourceSize.height() }; - - if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) { - QSize clippedSize = rect.size(); - clippedSize.scale(sourceRect.right, sourceRect.bottom, Qt::KeepAspectRatio); - - sourceRect.left = (sourceRect.right - clippedSize.width()) / 2; - sourceRect.top = (sourceRect.bottom - clippedSize.height()) / 2; - sourceRect.right = sourceRect.left + clippedSize.width(); - sourceRect.bottom = sourceRect.top + clippedSize.height(); - } - - if (sourceSize.width() > 0 && sourceSize.height() > 0) { - MFVideoNormalizedRect sourceNormRect; - sourceNormRect.left = float(sourceRect.left) / float(sourceRect.right); - sourceNormRect.top = float(sourceRect.top) / float(sourceRect.bottom); - sourceNormRect.right = float(sourceRect.right) / float(sourceRect.right); - sourceNormRect.bottom = float(sourceRect.bottom) / float(sourceRect.bottom); - m_displayControl->SetVideoPosition(&sourceNormRect, &displayRect); - } else { - m_displayControl->SetVideoPosition(NULL, &displayRect); - } - - // To refresh content immediately. - repaint(); - } -} - -bool EvrVideoWindowControl::isFullScreen() const -{ - return m_fullScreen; -} - -void EvrVideoWindowControl::setFullScreen(bool fullScreen) -{ - if (m_fullScreen == fullScreen) - return; - emit fullScreenChanged(m_fullScreen = fullScreen); -} - -void EvrVideoWindowControl::repaint() -{ - QSize size = nativeSize(); - if (size.width() > 0 && size.height() > 0 - && m_displayControl - && SUCCEEDED(m_displayControl->RepaintVideo())) { - return; - } - - PAINTSTRUCT paint; - if (HDC dc = ::BeginPaint(HWND(m_windowId), &paint)) { - HPEN pen = ::CreatePen(PS_SOLID, 1, m_windowColor); - HBRUSH brush = ::CreateSolidBrush(m_windowColor); - ::SelectObject(dc, pen); - ::SelectObject(dc, brush); - - ::Rectangle( - dc, - m_displayRect.left(), - m_displayRect.top(), - m_displayRect.right() + 1, - m_displayRect.bottom() + 1); - - ::DeleteObject(pen); - ::DeleteObject(brush); - ::EndPaint(HWND(m_windowId), &paint); - } -} - -QSize EvrVideoWindowControl::nativeSize() const -{ - QSize size; - if (m_displayControl) { - SIZE sourceSize; - if (SUCCEEDED(m_displayControl->GetNativeVideoSize(&sourceSize, 0))) - size = QSize(sourceSize.cx, sourceSize.cy); - } - return size; -} - -Qt::AspectRatioMode EvrVideoWindowControl::aspectRatioMode() const -{ - return m_aspectRatioMode; -} - -void EvrVideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - m_aspectRatioMode = mode; - - if (m_displayControl) { - switch (mode) { - case Qt::IgnoreAspectRatio: - //comment from MSDN: Do not maintain the aspect ratio of the video. Stretch the video to fit the output rectangle. - m_displayControl->SetAspectRatioMode(MFVideoARMode_None); - break; - case Qt::KeepAspectRatio: - //comment from MSDN: Preserve the aspect ratio of the video by letterboxing or within the output rectangle. - m_displayControl->SetAspectRatioMode(MFVideoARMode_PreservePicture); - break; - case Qt::KeepAspectRatioByExpanding: - //for this mode, more adjustment will be done in setDisplayRect - m_displayControl->SetAspectRatioMode(MFVideoARMode_PreservePicture); - break; - default: - break; - } - setDisplayRect(m_displayRect); - } -} - -int EvrVideoWindowControl::brightness() const -{ - return m_brightness; -} - -void EvrVideoWindowControl::setBrightness(int brightness) -{ - if (m_brightness == brightness) - return; - - m_brightness = brightness; - - m_dirtyValues |= DXVA2_ProcAmp_Brightness; - - applyImageControls(); - - emit brightnessChanged(brightness); -} - -int EvrVideoWindowControl::contrast() const -{ - return m_contrast; -} - -void EvrVideoWindowControl::setContrast(int contrast) -{ - if (m_contrast == contrast) - return; - - m_contrast = contrast; - - m_dirtyValues |= DXVA2_ProcAmp_Contrast; - - applyImageControls(); - - emit contrastChanged(contrast); -} - -int EvrVideoWindowControl::hue() const -{ - return m_hue; -} - -void EvrVideoWindowControl::setHue(int hue) -{ - if (m_hue == hue) - return; - - m_hue = hue; - - m_dirtyValues |= DXVA2_ProcAmp_Hue; - - applyImageControls(); - - emit hueChanged(hue); -} - -int EvrVideoWindowControl::saturation() const -{ - return m_saturation; -} - -void EvrVideoWindowControl::setSaturation(int saturation) -{ - if (m_saturation == saturation) - return; - - m_saturation = saturation; - - m_dirtyValues |= DXVA2_ProcAmp_Saturation; - - applyImageControls(); - - emit saturationChanged(saturation); -} - -void EvrVideoWindowControl::applyImageControls() -{ - if (m_processor) { - DXVA2_ProcAmpValues values; - if (m_dirtyValues & DXVA2_ProcAmp_Brightness) { - values.Brightness = scaleProcAmpValue(DXVA2_ProcAmp_Brightness, m_brightness); - } - if (m_dirtyValues & DXVA2_ProcAmp_Contrast) { - values.Contrast = scaleProcAmpValue(DXVA2_ProcAmp_Contrast, m_contrast); - } - if (m_dirtyValues & DXVA2_ProcAmp_Hue) { - values.Hue = scaleProcAmpValue(DXVA2_ProcAmp_Hue, m_hue); - } - if (m_dirtyValues & DXVA2_ProcAmp_Saturation) { - values.Saturation = scaleProcAmpValue(DXVA2_ProcAmp_Saturation, m_saturation); - } - - if (SUCCEEDED(m_processor->SetProcAmpValues(m_dirtyValues, &values))) { - m_dirtyValues = 0; - } - } -} - -DXVA2_Fixed32 EvrVideoWindowControl::scaleProcAmpValue(DWORD prop, int value) const -{ - float scaledValue = 0.0; - - DXVA2_ValueRange range; - if (SUCCEEDED(m_processor->GetProcAmpRange(prop, &range))) { - scaledValue = DXVA2FixedToFloat(range.DefaultValue); - if (value > 0) - scaledValue += float(value) * (DXVA2FixedToFloat(range.MaxValue) - DXVA2FixedToFloat(range.DefaultValue)) / 100; - else if (value < 0) - scaledValue -= float(value) * (DXVA2FixedToFloat(range.MinValue) - DXVA2FixedToFloat(range.DefaultValue)) / 100; - } - - return DXVA2FloatToFixed(scaledValue); -} diff --git a/src/plugins/common/evr/evrvideowindowcontrol.h b/src/plugins/common/evr/evrvideowindowcontrol.h deleted file mode 100644 index ce3b7746f..000000000 --- a/src/plugins/common/evr/evrvideowindowcontrol.h +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef EVRVIDEOWINDOWCONTROL_H -#define EVRVIDEOWINDOWCONTROL_H - -#include "qvideowindowcontrol.h" - -#include "evrdefs.h" - -QT_BEGIN_NAMESPACE - -class EvrVideoWindowControl : public QVideoWindowControl -{ - Q_OBJECT -public: - EvrVideoWindowControl(QObject *parent = 0); - ~EvrVideoWindowControl() override; - - bool setEvr(IUnknown *evr); - - WId winId() const override; - void setWinId(WId id) override; - - QRect displayRect() const override; - void setDisplayRect(const QRect &rect) override; - - bool isFullScreen() const override; - void setFullScreen(bool fullScreen) override; - - void repaint() override; - - QSize nativeSize() const override; - - Qt::AspectRatioMode aspectRatioMode() const override; - void setAspectRatioMode(Qt::AspectRatioMode mode) override; - - int brightness() const override; - void setBrightness(int brightness) override; - - int contrast() const override; - void setContrast(int contrast) override; - - int hue() const override; - void setHue(int hue) override; - - int saturation() const override; - void setSaturation(int saturation) override; - - void applyImageControls(); - -private: - void clear(); - DXVA2_Fixed32 scaleProcAmpValue(DWORD prop, int value) const; - - WId m_windowId; - COLORREF m_windowColor; - DWORD m_dirtyValues; - Qt::AspectRatioMode m_aspectRatioMode; - QRect m_displayRect; - int m_brightness; - int m_contrast; - int m_hue; - int m_saturation; - bool m_fullScreen; - - IMFVideoDisplayControl *m_displayControl; - IMFVideoProcessor *m_processor; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/gstreamer/CMakeLists.txt b/src/plugins/gstreamer/CMakeLists.txt deleted file mode 100644 index 6684057b7..000000000 --- a/src/plugins/gstreamer/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Generated from gstreamer.pro. - -add_subdirectory(audiodecoder) -add_subdirectory(camerabin) -add_subdirectory(mediaplayer) -#add_subdirectory(mediacapture) diff --git a/src/plugins/gstreamer/audiodecoder/CMakeLists.txt b/src/plugins/gstreamer/audiodecoder/CMakeLists.txt deleted file mode 100644 index 019cd5a48..000000000 --- a/src/plugins/gstreamer/audiodecoder/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# Generated from audiodecoder.pro. - -##################################################################### -## QGstreamerAudioDecoderServicePlugin Plugin: -##################################################################### - -qt_internal_add_plugin(QGstreamerAudioDecoderServicePlugin - OUTPUT_NAME gstaudiodecoder - TYPE mediaservice - SOURCES - qgstreameraudiodecodercontrol.cpp qgstreameraudiodecodercontrol.h - qgstreameraudiodecoderservice.cpp qgstreameraudiodecoderservice.h - qgstreameraudiodecoderserviceplugin.cpp qgstreameraudiodecoderserviceplugin.h - INCLUDE_DIRECTORIES - ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC_LIBRARIES - Qt::Core - Qt::CorePrivate - Qt::Gui - Qt::MultimediaPrivate - Qt::Network - gstreamer - Qt::MultimediaPrivate -) - -#### Keys ignored in scope 1:.:.:audiodecoder.pro:<TRUE>: -# OTHER_FILES = "audiodecoder.json" - -## Scopes: -##################################################################### - -qt_internal_extend_target(QGstreamerAudioDecoderServicePlugin CONDITION TARGET Qt::Widgets - DEFINES - HAVE_WIDGETS - PUBLIC_LIBRARIES - Qt::MultimediaWidgetsPrivate - Qt::Widgets -) - -qt_internal_extend_target(QGstreamerAudioDecoderServicePlugin CONDITION QT_FEATURE_gstreamer_app - PUBLIC_LIBRARIES - gstreamer_app -) diff --git a/src/plugins/gstreamer/audiodecoder/audiodecoder.json b/src/plugins/gstreamer/audiodecoder/audiodecoder.json deleted file mode 100644 index 4314f2efa..000000000 --- a/src/plugins/gstreamer/audiodecoder/audiodecoder.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["gstreameraudiodecode"], - "Services": ["org.qt-project.qt.audiodecode"] -} diff --git a/src/plugins/gstreamer/audiodecoder/audiodecoder.pro b/src/plugins/gstreamer/audiodecoder/audiodecoder.pro deleted file mode 100644 index 7e61beccc..000000000 --- a/src/plugins/gstreamer/audiodecoder/audiodecoder.pro +++ /dev/null @@ -1,22 +0,0 @@ -TARGET = gstaudiodecoder - -include(../common.pri) - -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/qgstreameraudiodecoderservice.h \ - $$PWD/qgstreameraudiodecodercontrol.h \ - $$PWD/qgstreameraudiodecoderserviceplugin.h - -SOURCES += \ - $$PWD/qgstreameraudiodecoderservice.cpp \ - $$PWD/qgstreameraudiodecodercontrol.cpp \ - $$PWD/qgstreameraudiodecoderserviceplugin.cpp - -OTHER_FILES += \ - audiodecoder.json - -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = QGstreamerAudioDecoderServicePlugin -load(qt_plugin) diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodercontrol.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodercontrol.cpp deleted file mode 100644 index 439a6b957..000000000 --- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodercontrol.cpp +++ /dev/null @@ -1,599 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//#define DEBUG_DECODER - -#include "qgstreameraudiodecodercontrol.h" -#include <private/qgstreamerbushelper_p.h> - -#include <private/qgstutils_p.h> - -#include <gst/gstvalue.h> -#include <gst/base/gstbasesrc.h> - -#include <QtCore/qdatetime.h> -#include <QtCore/qdebug.h> -#include <QtCore/qsize.h> -#include <QtCore/qtimer.h> -#include <QtCore/qdebug.h> -#include <QtCore/qdir.h> -#include <QtCore/qstandardpaths.h> -#include <QtCore/qurl.h> - -#define MAX_BUFFERS_IN_QUEUE 4 - -QT_BEGIN_NAMESPACE - -typedef enum { - GST_PLAY_FLAG_VIDEO = 0x00000001, - GST_PLAY_FLAG_AUDIO = 0x00000002, - GST_PLAY_FLAG_TEXT = 0x00000004, - GST_PLAY_FLAG_VIS = 0x00000008, - GST_PLAY_FLAG_SOFT_VOLUME = 0x00000010, - GST_PLAY_FLAG_NATIVE_AUDIO = 0x00000020, - GST_PLAY_FLAG_NATIVE_VIDEO = 0x00000040, - GST_PLAY_FLAG_DOWNLOAD = 0x00000080, - GST_PLAY_FLAG_BUFFERING = 0x000000100 -} GstPlayFlags; - -QGstreamerAudioDecoderControl::QGstreamerAudioDecoderControl(QObject *parent) - : QAudioDecoderControl(parent), - m_state(QAudioDecoder::StoppedState), - m_pendingState(QAudioDecoder::StoppedState), - m_busHelper(0), - m_bus(0), - m_playbin(0), - m_outputBin(0), - m_audioConvert(0), - m_appSink(0), -#if QT_CONFIG(gstreamer_app) - m_appSrc(0), -#endif - mDevice(0), - m_buffersAvailable(0), - m_position(-1), - m_duration(-1), - m_durationQueries(0) -{ - // Create pipeline here - m_playbin = gst_element_factory_make("playbin", NULL); - - if (m_playbin != 0) { - // Sort out messages - m_bus = gst_element_get_bus(m_playbin); - m_busHelper = new QGstreamerBusHelper(m_bus, this); - m_busHelper->installMessageFilter(this); - - // Set the rest of the pipeline up - setAudioFlags(true); - - m_audioConvert = gst_element_factory_make("audioconvert", NULL); - - m_outputBin = gst_bin_new("audio-output-bin"); - gst_bin_add(GST_BIN(m_outputBin), m_audioConvert); - - // add ghostpad - GstPad *pad = gst_element_get_static_pad(m_audioConvert, "sink"); - Q_ASSERT(pad); - gst_element_add_pad(GST_ELEMENT(m_outputBin), gst_ghost_pad_new("sink", pad)); - gst_object_unref(GST_OBJECT(pad)); - - g_object_set(G_OBJECT(m_playbin), "audio-sink", m_outputBin, NULL); -#if QT_CONFIG(gstreamer_app) - g_signal_connect(G_OBJECT(m_playbin), "deep-notify::source", (GCallback) &QGstreamerAudioDecoderControl::configureAppSrcElement, (gpointer)this); -#endif - - // Set volume to 100% - gdouble volume = 1.0; - g_object_set(G_OBJECT(m_playbin), "volume", volume, NULL); - } -} - -QGstreamerAudioDecoderControl::~QGstreamerAudioDecoderControl() -{ - if (m_playbin) { - stop(); - - delete m_busHelper; -#if QT_CONFIG(gstreamer_app) - delete m_appSrc; -#endif - gst_object_unref(GST_OBJECT(m_bus)); - gst_object_unref(GST_OBJECT(m_playbin)); - } -} - -#if QT_CONFIG(gstreamer_app) -void QGstreamerAudioDecoderControl::configureAppSrcElement(GObject* object, GObject *orig, GParamSpec *pspec, QGstreamerAudioDecoderControl* self) -{ - Q_UNUSED(object); - Q_UNUSED(pspec); - - // In case we switch from appsrc to not - if (!self->appsrc()) - return; - - GstElement *appsrc; - g_object_get(orig, "source", &appsrc, NULL); - - if (!self->appsrc()->setup(appsrc)) - qWarning()<<"Could not setup appsrc element"; - - g_object_unref(G_OBJECT(appsrc)); -} -#endif - -bool QGstreamerAudioDecoderControl::processBusMessage(const QGstreamerMessage &message) -{ - GstMessage* gm = message.rawMessage(); - if (gm) { - if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_DURATION) { - updateDuration(); - } else if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_playbin)) { - switch (GST_MESSAGE_TYPE(gm)) { - case GST_MESSAGE_STATE_CHANGED: - { - GstState oldState; - GstState newState; - GstState pending; - - gst_message_parse_state_changed(gm, &oldState, &newState, &pending); - -#ifdef DEBUG_DECODER - QStringList states; - states << "GST_STATE_VOID_PENDING" << "GST_STATE_NULL" << "GST_STATE_READY" << "GST_STATE_PAUSED" << "GST_STATE_PLAYING"; - - qDebug() << QString("state changed: old: %1 new: %2 pending: %3") \ - .arg(states[oldState]) \ - .arg(states[newState]) \ - .arg(states[pending]) << "internal" << m_state; -#endif - - QAudioDecoder::State prevState = m_state; - - switch (newState) { - case GST_STATE_VOID_PENDING: - case GST_STATE_NULL: - m_state = QAudioDecoder::StoppedState; - break; - case GST_STATE_READY: - m_state = QAudioDecoder::StoppedState; - break; - case GST_STATE_PLAYING: - m_state = QAudioDecoder::DecodingState; - break; - case GST_STATE_PAUSED: - m_state = QAudioDecoder::DecodingState; - - //gstreamer doesn't give a reliable indication the duration - //information is ready, GST_MESSAGE_DURATION is not sent by most elements - //the duration is queried up to 5 times with increasing delay - m_durationQueries = 5; - updateDuration(); - break; - } - - if (prevState != m_state) - emit stateChanged(m_state); - } - break; - - case GST_MESSAGE_EOS: - m_pendingState = m_state = QAudioDecoder::StoppedState; - emit finished(); - emit stateChanged(m_state); - break; - - case GST_MESSAGE_ERROR: { - GError *err; - gchar *debug; - gst_message_parse_error(gm, &err, &debug); - if (err->domain == GST_STREAM_ERROR && err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND) - processInvalidMedia(QAudioDecoder::FormatError, tr("Cannot play stream of type: <unknown>")); - else - processInvalidMedia(QAudioDecoder::ResourceError, QString::fromUtf8(err->message)); - qWarning() << "Error:" << QString::fromUtf8(err->message); - g_error_free(err); - g_free(debug); - } - break; - case GST_MESSAGE_WARNING: - { - GError *err; - gchar *debug; - gst_message_parse_warning (gm, &err, &debug); - qWarning() << "Warning:" << QString::fromUtf8(err->message); - g_error_free (err); - g_free (debug); - } - break; -#ifdef DEBUG_DECODER - case GST_MESSAGE_INFO: - { - GError *err; - gchar *debug; - gst_message_parse_info (gm, &err, &debug); - qDebug() << "Info:" << QString::fromUtf8(err->message); - g_error_free (err); - g_free (debug); - } - break; -#endif - default: - break; - } - } else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ERROR) { - GError *err; - gchar *debug; - gst_message_parse_error(gm, &err, &debug); - QAudioDecoder::Error qerror = QAudioDecoder::ResourceError; - if (err->domain == GST_STREAM_ERROR) { - switch (err->code) { - case GST_STREAM_ERROR_DECRYPT: - case GST_STREAM_ERROR_DECRYPT_NOKEY: - qerror = QAudioDecoder::AccessDeniedError; - break; - case GST_STREAM_ERROR_FORMAT: - case GST_STREAM_ERROR_DEMUX: - case GST_STREAM_ERROR_DECODE: - case GST_STREAM_ERROR_WRONG_TYPE: - case GST_STREAM_ERROR_TYPE_NOT_FOUND: - case GST_STREAM_ERROR_CODEC_NOT_FOUND: - qerror = QAudioDecoder::FormatError; - break; - default: - break; - } - } else if (err->domain == GST_CORE_ERROR) { - switch (err->code) { - case GST_CORE_ERROR_MISSING_PLUGIN: - qerror = QAudioDecoder::FormatError; - break; - default: - break; - } - } - - processInvalidMedia(qerror, QString::fromUtf8(err->message)); - g_error_free(err); - g_free(debug); - } - } - - return false; -} - -QString QGstreamerAudioDecoderControl::sourceFilename() const -{ - return mSource; -} - -void QGstreamerAudioDecoderControl::setSourceFilename(const QString &fileName) -{ - stop(); - mDevice = 0; -#if QT_CONFIG(gstreamer_app) - if (m_appSrc) - m_appSrc->deleteLater(); - m_appSrc = 0; -#endif - - bool isSignalRequired = (mSource != fileName); - mSource = fileName; - if (isSignalRequired) - emit sourceChanged(); -} - -QIODevice *QGstreamerAudioDecoderControl::sourceDevice() const -{ - return mDevice; -} - -void QGstreamerAudioDecoderControl::setSourceDevice(QIODevice *device) -{ - stop(); - mSource.clear(); - bool isSignalRequired = (mDevice != device); - mDevice = device; - if (isSignalRequired) - emit sourceChanged(); -} - -void QGstreamerAudioDecoderControl::start() -{ - if (!m_playbin) { - processInvalidMedia(QAudioDecoder::ResourceError, "Playbin element is not valid"); - return; - } - - addAppSink(); - - if (!mSource.isEmpty()) { - g_object_set(G_OBJECT(m_playbin), "uri", QUrl::fromLocalFile(mSource).toEncoded().constData(), NULL); - } else if (mDevice) { -#if QT_CONFIG(gstreamer_app) - // make sure we can read from device - if (!mDevice->isOpen() || !mDevice->isReadable()) { - processInvalidMedia(QAudioDecoder::AccessDeniedError, "Unable to read from specified device"); - return; - } - - if (!m_appSrc) - m_appSrc = new QGstAppSrc(this); - m_appSrc->setStream(mDevice); - - g_object_set(G_OBJECT(m_playbin), "uri", "appsrc://", NULL); -#endif - } else { - return; - } - - // Set audio format - if (m_appSink) { - if (mFormat.isValid()) { - setAudioFlags(false); - GstCaps *caps = QGstUtils::capsForAudioFormat(mFormat); - gst_app_sink_set_caps(m_appSink, caps); - gst_caps_unref(caps); - } else { - // We want whatever the native audio format is - setAudioFlags(true); - gst_app_sink_set_caps(m_appSink, NULL); - } - } - - m_pendingState = QAudioDecoder::DecodingState; - if (gst_element_set_state(m_playbin, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { - qWarning() << "GStreamer; Unable to start decoding process"; - m_pendingState = m_state = QAudioDecoder::StoppedState; - - emit stateChanged(m_state); - } -} - -void QGstreamerAudioDecoderControl::stop() -{ - if (m_playbin) { - gst_element_set_state(m_playbin, GST_STATE_NULL); - removeAppSink(); - - QAudioDecoder::State oldState = m_state; - m_pendingState = m_state = QAudioDecoder::StoppedState; - - // GStreamer thread is stopped. Can safely access m_buffersAvailable - if (m_buffersAvailable != 0) { - m_buffersAvailable = 0; - emit bufferAvailableChanged(false); - } - - if (m_position != -1) { - m_position = -1; - emit positionChanged(m_position); - } - - if (m_duration != -1) { - m_duration = -1; - emit durationChanged(m_duration); - } - - if (oldState != m_state) - emit stateChanged(m_state); - } -} - -QAudioFormat QGstreamerAudioDecoderControl::audioFormat() const -{ - return mFormat; -} - -void QGstreamerAudioDecoderControl::setAudioFormat(const QAudioFormat &format) -{ - if (mFormat != format) { - mFormat = format; - emit formatChanged(mFormat); - } -} - -QAudioBuffer QGstreamerAudioDecoderControl::read() -{ - QAudioBuffer audioBuffer; - - int buffersAvailable; - { - QMutexLocker locker(&m_buffersMutex); - buffersAvailable = m_buffersAvailable; - - // need to decrement before pulling a buffer - // to make sure assert in QGstreamerAudioDecoderControl::new_buffer works - m_buffersAvailable--; - } - - - if (buffersAvailable) { - if (buffersAvailable == 1) - emit bufferAvailableChanged(false); - - const char* bufferData = 0; - int bufferSize = 0; - - GstSample *sample = gst_app_sink_pull_sample(m_appSink); - GstBuffer *buffer = gst_sample_get_buffer(sample); - GstMapInfo mapInfo; - gst_buffer_map(buffer, &mapInfo, GST_MAP_READ); - bufferData = (const char*)mapInfo.data; - bufferSize = mapInfo.size; - QAudioFormat format = QGstUtils::audioFormatForSample(sample); - - if (format.isValid()) { - // XXX At the moment we have to copy data from GstBuffer into QAudioBuffer. - // We could improve performance by implementing QAbstractAudioBuffer for GstBuffer. - qint64 position = getPositionFromBuffer(buffer); - audioBuffer = QAudioBuffer(QByteArray((const char*)bufferData, bufferSize), format, position); - position /= 1000; // convert to milliseconds - if (position != m_position) { - m_position = position; - emit positionChanged(m_position); - } - } - gst_buffer_unmap(buffer, &mapInfo); - gst_sample_unref(sample); - } - - return audioBuffer; -} - -bool QGstreamerAudioDecoderControl::bufferAvailable() const -{ - QMutexLocker locker(&m_buffersMutex); - return m_buffersAvailable > 0; -} - -qint64 QGstreamerAudioDecoderControl::position() const -{ - return m_position; -} - -qint64 QGstreamerAudioDecoderControl::duration() const -{ - return m_duration; -} - -void QGstreamerAudioDecoderControl::processInvalidMedia(QAudioDecoder::Error errorCode, const QString& errorString) -{ - stop(); - emit error(int(errorCode), errorString); -} - -GstFlowReturn QGstreamerAudioDecoderControl::new_sample(GstAppSink *, gpointer user_data) -{ - // "Note that the preroll buffer will also be returned as the first buffer when calling gst_app_sink_pull_buffer()." - QGstreamerAudioDecoderControl *control = reinterpret_cast<QGstreamerAudioDecoderControl*>(user_data); - - int buffersAvailable; - { - QMutexLocker locker(&control->m_buffersMutex); - buffersAvailable = control->m_buffersAvailable; - control->m_buffersAvailable++; - Q_ASSERT(control->m_buffersAvailable <= MAX_BUFFERS_IN_QUEUE); - } - - if (!buffersAvailable) - QMetaObject::invokeMethod(control, "bufferAvailableChanged", Qt::QueuedConnection, Q_ARG(bool, true)); - QMetaObject::invokeMethod(control, "bufferReady", Qt::QueuedConnection); - return GST_FLOW_OK; -} - -void QGstreamerAudioDecoderControl::setAudioFlags(bool wantNativeAudio) -{ - int flags = 0; - if (m_playbin) { - g_object_get(G_OBJECT(m_playbin), "flags", &flags, NULL); - // make sure not to use GST_PLAY_FLAG_NATIVE_AUDIO unless desired - // it prevents audio format conversion - flags &= ~(GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_NATIVE_VIDEO | GST_PLAY_FLAG_TEXT | GST_PLAY_FLAG_VIS | GST_PLAY_FLAG_NATIVE_AUDIO); - flags |= GST_PLAY_FLAG_AUDIO; - if (wantNativeAudio) - flags |= GST_PLAY_FLAG_NATIVE_AUDIO; - g_object_set(G_OBJECT(m_playbin), "flags", flags, NULL); - } -} - -void QGstreamerAudioDecoderControl::addAppSink() -{ - if (m_appSink) - return; - - m_appSink = (GstAppSink*)gst_element_factory_make("appsink", NULL); - - GstAppSinkCallbacks callbacks; - memset(&callbacks, 0, sizeof(callbacks)); - callbacks.new_sample = &new_sample; - gst_app_sink_set_callbacks(m_appSink, &callbacks, this, NULL); - gst_app_sink_set_max_buffers(m_appSink, MAX_BUFFERS_IN_QUEUE); - gst_base_sink_set_sync(GST_BASE_SINK(m_appSink), FALSE); - - gst_bin_add(GST_BIN(m_outputBin), GST_ELEMENT(m_appSink)); - gst_element_link(m_audioConvert, GST_ELEMENT(m_appSink)); -} - -void QGstreamerAudioDecoderControl::removeAppSink() -{ - if (!m_appSink) - return; - - gst_element_unlink(m_audioConvert, GST_ELEMENT(m_appSink)); - gst_bin_remove(GST_BIN(m_outputBin), GST_ELEMENT(m_appSink)); - - m_appSink = 0; -} - -void QGstreamerAudioDecoderControl::updateDuration() -{ - gint64 gstDuration = 0; - int duration = -1; - - if (m_playbin && qt_gst_element_query_duration(m_playbin, GST_FORMAT_TIME, &gstDuration)) - duration = gstDuration / 1000000; - - if (m_duration != duration) { - m_duration = duration; - emit durationChanged(m_duration); - } - - if (m_duration > 0) - m_durationQueries = 0; - - if (m_durationQueries > 0) { - //increase delay between duration requests - int delay = 25 << (5 - m_durationQueries); - QTimer::singleShot(delay, this, SLOT(updateDuration())); - m_durationQueries--; - } -} - -qint64 QGstreamerAudioDecoderControl::getPositionFromBuffer(GstBuffer* buffer) -{ - qint64 position = GST_BUFFER_TIMESTAMP(buffer); - if (position >= 0) - position = position / G_GINT64_CONSTANT(1000); // microseconds - else - position = -1; - return position; -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodercontrol.h b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodercontrol.h deleted file mode 100644 index 9e94088a8..000000000 --- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodercontrol.h +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERAUDIODECODERCONTROL_H -#define QGSTREAMERAUDIODECODERCONTROL_H - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include <QObject> -#include <QtCore/qmutex.h> -#include "qaudiodecodercontrol.h" -#include <private/qgstreamerbushelper_p.h> -#include "qaudiodecoder.h" - -#if QT_CONFIG(gstreamer_app) -#include <private/qgstappsrc_p.h> -#endif - -#include <gst/gst.h> -#include <gst/app/gstappsink.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerBusHelper; -class QGstreamerMessage; - -class QGstreamerAudioDecoderControl - : public QAudioDecoderControl, - public QGstreamerBusMessageFilter -{ -Q_OBJECT -Q_INTERFACES(QGstreamerBusMessageFilter) - -public: - QGstreamerAudioDecoderControl(QObject *parent); - virtual ~QGstreamerAudioDecoderControl(); - - // QAudioDecoder interface - QAudioDecoder::State state() const override { return m_state; } - - QString sourceFilename() const override; - void setSourceFilename(const QString &fileName) override; - - QIODevice *sourceDevice() const override; - void setSourceDevice(QIODevice *device) override; - - void start() override; - void stop() override; - - QAudioFormat audioFormat() const override; - void setAudioFormat(const QAudioFormat &format) override; - - QAudioBuffer read() override; - bool bufferAvailable() const override; - - qint64 position() const override; - qint64 duration() const override; - - // GStreamerBusMessageFilter interface - bool processBusMessage(const QGstreamerMessage &message) override; - - QGstreamerBusHelper *bus() const { return m_busHelper; } - QAudioDecoder::State pendingState() const { return m_pendingState; } - -#if QT_CONFIG(gstreamer_app) - QGstAppSrc *appsrc() const { return m_appSrc; } - static void configureAppSrcElement(GObject*, GObject*, GParamSpec*, QGstreamerAudioDecoderControl *_this); -#endif - - static GstFlowReturn new_sample(GstAppSink *sink, gpointer user_data); - -private slots: - void updateDuration(); - -private: - void setAudioFlags(bool wantNativeAudio); - void addAppSink(); - void removeAppSink(); - - void processInvalidMedia(QAudioDecoder::Error errorCode, const QString& errorString); - static qint64 getPositionFromBuffer(GstBuffer* buffer); - - QAudioDecoder::State m_state; - QAudioDecoder::State m_pendingState; - QGstreamerBusHelper *m_busHelper; - GstBus *m_bus; - GstElement *m_playbin; - GstElement *m_outputBin; - GstElement *m_audioConvert; - GstAppSink *m_appSink; - -#if QT_CONFIG(gstreamer_app) - QGstAppSrc *m_appSrc; -#endif - - QString mSource; - QIODevice *mDevice; // QWeakPointer perhaps - QAudioFormat mFormat; - - mutable QMutex m_buffersMutex; - int m_buffersAvailable; - - qint64 m_position; - qint64 m_duration; - - int m_durationQueries; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERPLAYERSESSION_H diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderservice.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderservice.cpp deleted file mode 100644 index 125ba4d1c..000000000 --- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderservice.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qvariant.h> -#include <QtCore/qdebug.h> - -#include "qgstreameraudiodecoderservice.h" -#include "qgstreameraudiodecodercontrol.h" - -QT_BEGIN_NAMESPACE - -QGstreamerAudioDecoderService::QGstreamerAudioDecoderService(QObject *parent) - : QMediaService(parent) -{ - m_control = new QGstreamerAudioDecoderControl(this); -} - -QGstreamerAudioDecoderService::~QGstreamerAudioDecoderService() -{ -} - -QObject *QGstreamerAudioDecoderService::requestControl(const char *name) -{ - if (qstrcmp(name, QAudioDecoderControl_iid) == 0) - return m_control; - - return 0; -} - -void QGstreamerAudioDecoderService::releaseControl(QObject *control) -{ - Q_UNUSED(control); -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderservice.h b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderservice.h deleted file mode 100644 index defa5345c..000000000 --- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderservice.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERAUDIODECODERSERVICE_H -#define QGSTREAMERAUDIODECODERSERVICE_H - -#include <QtCore/qobject.h> -#include <QtCore/qiodevice.h> - -#include <qmediaservice.h> - -QT_BEGIN_NAMESPACE -class QGstreamerAudioDecoderControl; -class QGstreamerAudioDecoderControl; - -class QGstreamerAudioDecoderService : public QMediaService -{ - Q_OBJECT -public: - QGstreamerAudioDecoderService(QObject *parent = 0); - ~QGstreamerAudioDecoderService(); - - QObject *requestControl(const char *name) override; - void releaseControl(QObject *control) override; - -private: - QGstreamerAudioDecoderControl *m_control; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp deleted file mode 100644 index d9e6a2a38..000000000 --- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreameraudiodecoderserviceplugin.h" - -#include "qgstreameraudiodecoderservice.h" -#include <private/qgstutils_p.h> - -#include <QtCore/qstring.h> -#include <QtCore/qdebug.h> -#include <QtCore/QDir> -#include <QtCore/QDebug> - -// #define QT_SUPPORTEDMIMETYPES_DEBUG - -QMediaService* QGstreamerAudioDecoderServicePlugin::create(const QString &key) -{ - QGstUtils::initializeGst(); - - if (key == QLatin1String(Q_MEDIASERVICE_AUDIODECODER)) - return new QGstreamerAudioDecoderService; - - qWarning() << "Gstreamer audio decoder service plugin: unsupported key:" << key; - return 0; -} - -void QGstreamerAudioDecoderServicePlugin::release(QMediaService *service) -{ - delete service; -} - -QMultimedia::SupportEstimate QGstreamerAudioDecoderServicePlugin::hasSupport(const QString &mimeType, - const QStringList &codecs) const -{ - if (m_supportedMimeTypeSet.isEmpty()) - updateSupportedMimeTypes(); - - return QGstUtils::hasSupport(mimeType, codecs, m_supportedMimeTypeSet); -} - -static bool isDecoderOrDemuxer(GstElementFactory *factory) -{ - return gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_DEMUXER) - || gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_DECODER - | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO); -} - -void QGstreamerAudioDecoderServicePlugin::updateSupportedMimeTypes() const -{ - m_supportedMimeTypeSet = QGstUtils::supportedMimeTypes(isDecoderOrDemuxer); -} - -QStringList QGstreamerAudioDecoderServicePlugin::supportedMimeTypes() const -{ - return QStringList(); -} - diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.h b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.h deleted file mode 100644 index d1b96043b..000000000 --- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERAUDIODECODERSERVICEPLUGIN_H -#define QGSTREAMERAUDIODECODERSERVICEPLUGIN_H - -#include <qmediaserviceproviderplugin.h> -#include <QtCore/qset.h> -#include <QtCore/QObject> - -QT_BEGIN_NAMESPACE - -class QGstreamerAudioDecoderServicePlugin - : public QMediaServiceProviderPlugin - , public QMediaServiceSupportedFormatsInterface -{ - Q_OBJECT - Q_INTERFACES(QMediaServiceSupportedFormatsInterface) - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "audiodecoder.json") - -public: - QMediaService* create(const QString &key) override; - void release(QMediaService *service) override; - - QMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList &codecs) const override; - QStringList supportedMimeTypes() const override; - -private: - void updateSupportedMimeTypes() const; - - mutable QSet<QString> m_supportedMimeTypeSet; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERAUDIODECODERSERVICEPLUGIN_H diff --git a/src/plugins/gstreamer/camerabin/CMakeLists.txt b/src/plugins/gstreamer/camerabin/CMakeLists.txt deleted file mode 100644 index 2ef2f7572..000000000 --- a/src/plugins/gstreamer/camerabin/CMakeLists.txt +++ /dev/null @@ -1,73 +0,0 @@ -# Generated from camerabin.pro. - -##################################################################### -## CameraBinServicePlugin Plugin: -##################################################################### - -qt_internal_add_plugin(CameraBinServicePlugin - OUTPUT_NAME gstcamerabin - TYPE mediaservice - SOURCES - camerabinaudioencoder.cpp camerabinaudioencoder.h - camerabincapturebufferformat.cpp camerabincapturebufferformat.h - camerabincapturedestination.cpp camerabincapturedestination.h - camerabincontainer.cpp camerabincontainer.h - camerabincontrol.cpp camerabincontrol.h - camerabinimagecapture.cpp camerabinimagecapture.h - camerabinimageencoder.cpp camerabinimageencoder.h - camerabinimageprocessing.cpp camerabinimageprocessing.h - camerabinmetadata.cpp camerabinmetadata.h - camerabinrecorder.cpp camerabinrecorder.h - camerabinservice.cpp camerabinservice.h - camerabinserviceplugin.cpp camerabinserviceplugin.h - camerabinsession.cpp camerabinsession.h - camerabinvideoencoder.cpp camerabinvideoencoder.h - camerabinzoom.cpp camerabinzoom.h - INCLUDE_DIRECTORIES - ${CMAKE_CURRENT_SOURCE_DIR} - /src/multimedia - camerabin - PUBLIC_LIBRARIES - Qt::Core - Qt::CorePrivate - Qt::Gui - Qt::MultimediaPrivate - Qt::Network - gstreamer - Qt::MultimediaPrivate -) - -#### Keys ignored in scope 1:.:.:camerabin.pro:<TRUE>: -# OTHER_FILES = "camerabin.json" - -## Scopes: -##################################################################### - -qt_internal_extend_target(CameraBinServicePlugin CONDITION QT_FEATURE_gstreamer_photography - SOURCES - camerabinexposure.cpp camerabinexposure.h - camerabinfocus.cpp camerabinfocus.h - camerabinlocks.cpp camerabinlocks.h - DEFINES - GST_USE_UNSTABLE_API - PUBLIC_LIBRARIES - gstreamer_photography -) - -qt_internal_extend_target(CameraBinServicePlugin CONDITION QT_FEATURE_linux_v4l - SOURCES - camerabinv4limageprocessing.cpp camerabinv4limageprocessing.h -) - -qt_internal_extend_target(CameraBinServicePlugin CONDITION TARGET Qt::Widgets - DEFINES - HAVE_WIDGETS - PUBLIC_LIBRARIES - Qt::MultimediaWidgetsPrivate - Qt::Widgets -) - -qt_internal_extend_target(CameraBinServicePlugin CONDITION QT_FEATURE_gstreamer_app - PUBLIC_LIBRARIES - gstreamer_app -) diff --git a/src/plugins/gstreamer/camerabin/camerabin.json b/src/plugins/gstreamer/camerabin/camerabin.json deleted file mode 100644 index 3246b4683..000000000 --- a/src/plugins/gstreamer/camerabin/camerabin.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["gstreamercamerabin"], - "Services": ["org.qt-project.qt.camera"] -} diff --git a/src/plugins/gstreamer/camerabin/camerabin.pro b/src/plugins/gstreamer/camerabin/camerabin.pro deleted file mode 100644 index 0623dbc2b..000000000 --- a/src/plugins/gstreamer/camerabin/camerabin.pro +++ /dev/null @@ -1,69 +0,0 @@ -TARGET = gstcamerabin - -QT += multimedia-private - -include(../common.pri) - -INCLUDEPATH += $$PWD \ - $${SOURCE_DIR}/src/multimedia - -INCLUDEPATH += camerabin - - -HEADERS += \ - $$PWD/camerabinserviceplugin.h \ - $$PWD/camerabinservice.h \ - $$PWD/camerabinsession.h \ - $$PWD/camerabincontrol.h \ - $$PWD/camerabinaudioencoder.h \ - $$PWD/camerabinimageencoder.h \ - $$PWD/camerabinrecorder.h \ - $$PWD/camerabincontainer.h \ - $$PWD/camerabinimagecapture.h \ - $$PWD/camerabinimageprocessing.h \ - $$PWD/camerabinmetadata.h \ - $$PWD/camerabinvideoencoder.h \ - -SOURCES += \ - $$PWD/camerabinserviceplugin.cpp \ - $$PWD/camerabinservice.cpp \ - $$PWD/camerabinsession.cpp \ - $$PWD/camerabincontrol.cpp \ - $$PWD/camerabinaudioencoder.cpp \ - $$PWD/camerabincontainer.cpp \ - $$PWD/camerabinimagecapture.cpp \ - $$PWD/camerabinimageencoder.cpp \ - $$PWD/camerabinimageprocessing.cpp \ - $$PWD/camerabinmetadata.cpp \ - $$PWD/camerabinrecorder.cpp \ - $$PWD/camerabinvideoencoder.cpp \ - -qtConfig(gstreamer_photography) { - HEADERS += \ - $$PWD/camerabinfocus.h \ - $$PWD/camerabinexposure.h \ - - SOURCES += \ - $$PWD/camerabinexposure.cpp \ - $$PWD/camerabinfocus.cpp \ - - QMAKE_USE += gstreamer_photography - DEFINES += GST_USE_UNSTABLE_API #prevents warnings because of unstable photography API -} - -qtConfig(gstreamer_gl): QMAKE_USE += gstreamer_gl - -qtConfig(linux_v4l) { - HEADERS += \ - $$PWD/camerabinv4limageprocessing.h - - SOURCES += \ - $$PWD/camerabinv4limageprocessing.cpp -} - -OTHER_FILES += \ - camerabin.json - -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = CameraBinServicePlugin -load(qt_plugin) diff --git a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp deleted file mode 100644 index 9a26016de..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include "camerabinaudioencoder.h" -#include "camerabincontainer.h" -#include <private/qgstutils_p.h> - -#include <QtCore/qdebug.h> - -QT_BEGIN_NAMESPACE - -CameraBinAudioEncoder::CameraBinAudioEncoder(QObject *parent) - :QAudioEncoderSettingsControl(parent) -#if QT_CONFIG(gstreamer_encodingprofiles) - , m_codecs(QGstCodecsInfo::AudioEncoder) -#endif -{ -} - -CameraBinAudioEncoder::~CameraBinAudioEncoder() -{ -} - -QStringList CameraBinAudioEncoder::supportedAudioCodecs() const -{ -#if QT_CONFIG(gstreamer_encodingprofiles) - return m_codecs.supportedCodecs(); -#else - return QStringList(); -#endif -} - -QString CameraBinAudioEncoder::codecDescription(const QString &codecName) const -{ -#if QT_CONFIG(gstreamer_encodingprofiles) - return m_codecs.codecDescription(codecName); -#else - Q_UNUSED(codecName); - return QString(); -#endif -} - -QList<int> CameraBinAudioEncoder::supportedSampleRates(const QAudioEncoderSettings &, bool *) const -{ - //TODO check element caps to find actual values - - return QList<int>(); -} - -QAudioEncoderSettings CameraBinAudioEncoder::audioSettings() const -{ - return m_audioSettings; -} - -void CameraBinAudioEncoder::setAudioSettings(const QAudioEncoderSettings &settings) -{ - if (m_audioSettings != settings) { - m_audioSettings = settings; - m_actualAudioSettings = settings; - emit settingsChanged(); - } -} - -QAudioEncoderSettings CameraBinAudioEncoder::actualAudioSettings() const -{ - return m_actualAudioSettings; -} - -void CameraBinAudioEncoder::setActualAudioSettings(const QAudioEncoderSettings &settings) -{ - m_actualAudioSettings = settings; -} - -void CameraBinAudioEncoder::resetActualSettings() -{ - m_actualAudioSettings = m_audioSettings; -} - -#if QT_CONFIG(gstreamer_encodingprofiles) - -GstEncodingProfile *CameraBinAudioEncoder::createProfile() -{ - QString codec = m_actualAudioSettings.codec(); - QString preset = m_actualAudioSettings.encodingOption(QStringLiteral("preset")).toString(); - GstCaps *caps; - - if (codec.isEmpty()) - return 0; - - caps = gst_caps_from_string(codec.toLatin1()); - - GstEncodingProfile *profile = (GstEncodingProfile *)gst_encoding_audio_profile_new( - caps, - !preset.isEmpty() ? preset.toLatin1().constData() : NULL, //preset - NULL, //restriction - 0); //presence - - gst_caps_unref(caps); - - return profile; -} - -#endif - -void CameraBinAudioEncoder::applySettings(GstElement *encoder) -{ - GObjectClass * const objectClass = G_OBJECT_GET_CLASS(encoder); - const char * const name = qt_gst_element_get_factory_name(encoder); - - const bool isVorbis = qstrcmp(name, "vorbisenc") == 0; - - const int bitRate = m_actualAudioSettings.bitRate(); - if (!isVorbis && bitRate == -1) { - // Bit rate is invalid, don't evaluate the remaining conditions unless the encoder is - // vorbisenc which is known to accept -1 as an unspecified bitrate. - } else if (g_object_class_find_property(objectClass, "bitrate")) { - g_object_set(G_OBJECT(encoder), "bitrate", bitRate, NULL); - } else if (g_object_class_find_property(objectClass, "target-bitrate")) { - g_object_set(G_OBJECT(encoder), "target-bitrate", bitRate, NULL); - } - - if (isVorbis) { - static const double qualities[] = { 0.1, 0.3, 0.5, 0.7, 1.0 }; - g_object_set(G_OBJECT(encoder), "quality", qualities[m_actualAudioSettings.quality()], NULL); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h deleted file mode 100644 index b8091c8ca..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CAMERABINAUDIOENCODE_H -#define CAMERABINAUDIOENCODE_H - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include <qaudioencodersettingscontrol.h> - -#include <QtCore/qstringlist.h> -#include <QtCore/qmap.h> -#include <QtCore/qset.h> - -#include <gst/gst.h> -#include <gst/pbutils/pbutils.h> - -#if QT_CONFIG(gstreamer_encodingprofiles) -#include <gst/pbutils/encoding-profile.h> -#include <private/qgstcodecsinfo_p.h> -#endif - -#include <qaudioformat.h> - -QT_BEGIN_NAMESPACE -class CameraBinSession; - -class CameraBinAudioEncoder : public QAudioEncoderSettingsControl -{ - Q_OBJECT -public: - CameraBinAudioEncoder(QObject *parent); - virtual ~CameraBinAudioEncoder(); - - QStringList supportedAudioCodecs() const override; - QString codecDescription(const QString &codecName) const override; - - QStringList supportedEncodingOptions(const QString &codec) const; - QVariant encodingOption(const QString &codec, const QString &name) const; - void setEncodingOption(const QString &codec, const QString &name, const QVariant &value); - - QList<int> supportedSampleRates(const QAudioEncoderSettings &settings = QAudioEncoderSettings(), - bool *isContinuous = 0) const override; - QList<int> supportedChannelCounts(const QAudioEncoderSettings &settings = QAudioEncoderSettings()) const; - QList<int> supportedSampleSizes(const QAudioEncoderSettings &settings = QAudioEncoderSettings()) const; - - QAudioEncoderSettings audioSettings() const override; - void setAudioSettings(const QAudioEncoderSettings &) override; - - QAudioEncoderSettings actualAudioSettings() const; - void setActualAudioSettings(const QAudioEncoderSettings&); - void resetActualSettings(); - -#if QT_CONFIG(gstreamer_encodingprofiles) - GstEncodingProfile *createProfile(); -#endif - - void applySettings(GstElement *element); - -Q_SIGNALS: - void settingsChanged(); - -private: -#if QT_CONFIG(gstreamer_encodingprofiles) - QGstCodecsInfo m_codecs; -#endif - - QAudioEncoderSettings m_actualAudioSettings; - QAudioEncoderSettings m_audioSettings; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/gstreamer/camerabin/camerabincontainer.cpp b/src/plugins/gstreamer/camerabin/camerabincontainer.cpp deleted file mode 100644 index b19a5524e..000000000 --- a/src/plugins/gstreamer/camerabin/camerabincontainer.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include "camerabincontainer.h" -#include <private/qgstutils_p.h> - -#include <QtCore/qdebug.h> - -QT_BEGIN_NAMESPACE - -CameraBinContainer::CameraBinContainer(QObject *parent) - :QMediaContainerControl(parent) -#if QT_CONFIG(gstreamer_encodingprofiles) - , m_supportedContainers(QGstCodecsInfo::Muxer) -#endif -{ -} - -QStringList CameraBinContainer::supportedContainers() const -{ -#if QT_CONFIG(gstreamer_encodingprofiles) - return m_supportedContainers.supportedCodecs(); -#else - return QStringList(); -#endif -} - -QString CameraBinContainer::containerDescription(const QString &formatMimeType) const -{ -#if QT_CONFIG(gstreamer_encodingprofiles) - return m_supportedContainers.codecDescription(formatMimeType); -#else - Q_UNUSED(formatMimeType); - return QString(); -#endif -} - -QString CameraBinContainer::containerFormat() const -{ - return m_format; -} - -void CameraBinContainer::setContainerFormat(const QString &format) -{ -#if QT_CONFIG(gstreamer_encodingprofiles) - if (m_format != format) { - m_format = format; - m_actualFormat = format; - emit settingsChanged(); - } -#endif -} - -QString CameraBinContainer::actualContainerFormat() const -{ - return m_actualFormat; -} - -void CameraBinContainer::setActualContainerFormat(const QString &containerFormat) -{ -#if QT_CONFIG(gstreamer_encodingprofiles) - m_actualFormat = containerFormat; -#endif -} - -void CameraBinContainer::resetActualContainerFormat() -{ - m_actualFormat = m_format; -} - -#if QT_CONFIG(gstreamer_encodingprofiles) - -GstEncodingContainerProfile *CameraBinContainer::createProfile() -{ - GstCaps *caps = nullptr; - - if (m_actualFormat.isEmpty()) - return 0; - - QString format = m_actualFormat; - const QStringList supportedFormats = m_supportedContainers.supportedCodecs(); - - //if format is not in the list of supported gstreamer mime types, - //try to find the mime type with matching extension - if (!supportedFormats.contains(format)) { - format.clear(); - QString extension = QGstUtils::fileExtensionForMimeType(m_actualFormat); - for (const QString &formatCandidate : supportedFormats) { - if (QGstUtils::fileExtensionForMimeType(formatCandidate) == extension) { - format = formatCandidate; - break; - } - } - } - - if (format.isEmpty()) - return nullptr; - - caps = gst_caps_from_string(format.toLatin1()); - - GstEncodingContainerProfile *profile = (GstEncodingContainerProfile *)gst_encoding_container_profile_new( - "camerabin2_profile", - (gchar *)"custom camera profile", - caps, - NULL); //preset - - gst_caps_unref(caps); - - return profile; -} - -#endif - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabincontainer.h b/src/plugins/gstreamer/camerabin/camerabincontainer.h deleted file mode 100644 index 738e55e2a..000000000 --- a/src/plugins/gstreamer/camerabin/camerabincontainer.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef CAMERABINMEDIACONTAINERCONTROL_H -#define CAMERABINMEDIACONTAINERCONTROL_H - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include <qmediacontainercontrol.h> -#include <QtCore/qstringlist.h> -#include <QtCore/qset.h> - -#include <gst/gst.h> -#include <gst/pbutils/pbutils.h> - -#if QT_CONFIG(gstreamer_encodingprofiles) -#include <gst/pbutils/encoding-profile.h> -#include <private/qgstcodecsinfo_p.h> -#endif - -QT_BEGIN_NAMESPACE - -class CameraBinContainer : public QMediaContainerControl -{ -Q_OBJECT -public: - CameraBinContainer(QObject *parent); - virtual ~CameraBinContainer() {} - - QStringList supportedContainers() const override; - QString containerDescription(const QString &formatMimeType) const override; - - QString containerFormat() const override; - void setContainerFormat(const QString &format) override; - - QString actualContainerFormat() const; - void setActualContainerFormat(const QString &containerFormat); - void resetActualContainerFormat(); - -#if QT_CONFIG(gstreamer_encodingprofiles) - GstEncodingContainerProfile *createProfile(); -#endif - -Q_SIGNALS: - void settingsChanged(); - -private: - QString m_format; - QString m_actualFormat; - -#if QT_CONFIG(gstreamer_encodingprofiles) - QGstCodecsInfo m_supportedContainers; -#endif -}; - -QT_END_NAMESPACE - -#endif // CAMERABINMEDIACONTAINERCONTROL_H diff --git a/src/plugins/gstreamer/camerabin/camerabincontrol.cpp b/src/plugins/gstreamer/camerabin/camerabincontrol.cpp deleted file mode 100644 index a02e9ab72..000000000 --- a/src/plugins/gstreamer/camerabin/camerabincontrol.cpp +++ /dev/null @@ -1,432 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include "camerabincontrol.h" -#include "camerabincontainer.h" -#include "camerabinaudioencoder.h" -#include "camerabinvideoencoder.h" -#include "camerabinimageencoder.h" -#include "camerabinfocus.h" -#include "camerabinimageprocessing.h" - -#include <QtCore/qdebug.h> -#include <QtCore/qfile.h> -#include <QtCore/qmetaobject.h> -#include <QtCore/qcoreevent.h> - -QT_BEGIN_NAMESPACE - -//#define CAMEABIN_DEBUG 1 -#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v))) - -CameraBinControl::CameraBinControl(CameraBinSession *session) - :QCameraControl(session), - m_session(session), - m_state(QCamera::UnloadedState), - m_reloadPending(false), - m_focus(m_session->cameraFocusControl()) -{ - connect(m_session, SIGNAL(statusChanged(QCamera::Status)), - this, SIGNAL(statusChanged(QCamera::Status))); - - connect(m_session, SIGNAL(viewfinderChanged()), - SLOT(reloadLater())); - connect(m_session, SIGNAL(readyChanged(bool)), - SLOT(reloadLater())); - connect(m_session, SIGNAL(error(int,QString)), - SLOT(handleCameraError(int,QString))); - - connect(m_session, SIGNAL(busyChanged(bool)), - SLOT(handleBusyChanged(bool))); - - connect(m_focus, SIGNAL(_q_focusStatusChanged(QCamera::LockStatus,QCamera::LockChangeReason)), - this, SLOT(updateFocusStatus(QCamera::LockStatus,QCamera::LockChangeReason))); -} - -CameraBinControl::~CameraBinControl() -{ -} - -QCamera::CaptureModes CameraBinControl::captureMode() const -{ - return m_session->captureMode(); -} - -void CameraBinControl::setCaptureMode(QCamera::CaptureModes mode) -{ - if (m_session->captureMode() != mode) { - m_session->setCaptureMode(mode); - - emit captureModeChanged(mode); - } -} - -bool CameraBinControl::isCaptureModeSupported(QCamera::CaptureModes mode) const -{ - return mode == QCamera::CaptureStillImage || mode == QCamera::CaptureVideo; -} - -void CameraBinControl::setState(QCamera::State state) -{ -#ifdef CAMEABIN_DEBUG - qDebug() << Q_FUNC_INFO << ENUM_NAME(QCamera, "State", state); -#endif - if (m_state != state) { - m_state = state; - - //special case for stopping the camera while it's busy, - //it should be delayed until the camera is idle - if ((state == QCamera::LoadedState || state == QCamera::UnloadedState) && - m_session->status() == QCamera::ActiveStatus && - m_session->isBusy()) { -#ifdef CAMEABIN_DEBUG - qDebug() << Q_FUNC_INFO << "Camera is busy," - << state == QCamera::LoadedState ? "QCamera::stop()" : "QCamera::unload()" - << "is delayed"; -#endif - emit stateChanged(m_state); - return; - } - - //postpone changing to Active if the session is nor ready yet - if (state == QCamera::ActiveState) { - if (m_session->isReady()) { - m_session->setState(state); - } else { -#ifdef CAMEABIN_DEBUG - qDebug() << "Camera session is not ready yet, postpone activating"; -#endif - } - } else - m_session->setState(state); - - emit stateChanged(m_state); - } -} - -QCamera::State CameraBinControl::state() const -{ - return m_state; -} - -QCamera::Status CameraBinControl::status() const -{ - return m_session->status(); -} - -void CameraBinControl::reloadLater() -{ -#ifdef CAMEABIN_DEBUG - qDebug() << "CameraBinControl: reload pipeline requested" << ENUM_NAME(QCamera, "State", m_state); -#endif - if (!m_reloadPending && m_state == QCamera::ActiveState) { - m_reloadPending = true; - - if (!m_session->isBusy()) { - m_session->setState(QCamera::LoadedState); - QMetaObject::invokeMethod(this, "delayedReload", Qt::QueuedConnection); - } - } -} - -void CameraBinControl::handleBusyChanged(bool busy) -{ - if (!busy && m_session->status() == QCamera::ActiveStatus) { - if (m_state != QCamera::ActiveState) { - m_session->setState(m_state); - } else if (m_reloadPending) { - //handle delayed reload because of busy camera - m_session->setState(QCamera::LoadedState); - QMetaObject::invokeMethod(this, "delayedReload", Qt::QueuedConnection); - } - } -} - -void CameraBinControl::handleCameraError(int errorCode, const QString &errorString) -{ - emit error(errorCode, errorString); - setState(QCamera::UnloadedState); -} - -void CameraBinControl::delayedReload() -{ -#ifdef CAMEABIN_DEBUG - qDebug() << "CameraBinControl: reload pipeline"; -#endif - if (m_reloadPending) { - m_reloadPending = false; - if (m_state == QCamera::ActiveState && m_session->isReady()) - m_session->setState(QCamera::ActiveState); - } -} - -bool CameraBinControl::canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const -{ - Q_UNUSED(status); - - switch (changeType) { - case QCameraControl::Viewfinder: - return true; - case QCameraControl::CaptureMode: - case QCameraControl::ImageEncodingSettings: - case QCameraControl::VideoEncodingSettings: - case QCameraControl::ViewfinderSettings: - default: - return status != QCamera::ActiveStatus; - } -} - -#define VIEWFINDER_COLORSPACE_CONVERSION 0x00000004 - -bool CameraBinControl::viewfinderColorSpaceConversion() const -{ - gint flags = 0; - g_object_get(G_OBJECT(m_session->cameraBin()), "flags", &flags, NULL); - - return flags & VIEWFINDER_COLORSPACE_CONVERSION; -} - -void CameraBinControl::setViewfinderColorSpaceConversion(bool enabled) -{ - gint flags = 0; - g_object_get(G_OBJECT(m_session->cameraBin()), "flags", &flags, NULL); - - if (enabled) - flags |= VIEWFINDER_COLORSPACE_CONVERSION; - else - flags &= ~VIEWFINDER_COLORSPACE_CONVERSION; - - g_object_set(G_OBJECT(m_session->cameraBin()), "flags", flags, NULL); -} - -QCamera::LockTypes CameraBinControl::supportedLocks() const -{ - QCamera::LockTypes locks = QCamera::LockFocus; - - if (GstPhotography *photography = m_session->photography()) { - if (gst_photography_get_capabilities(photography) & GST_PHOTOGRAPHY_CAPS_WB_MODE) - locks |= QCamera::LockWhiteBalance; - - if (GstElement *source = m_session->cameraSource()) { - if (g_object_class_find_property( - G_OBJECT_GET_CLASS(source), "exposure-mode")) { - locks |= QCamera::LockExposure; - } - } - } - - return locks; -} - -QCamera::LockStatus CameraBinControl::lockStatus(QCamera::LockType lock) const -{ - switch (lock) { - case QCamera::LockFocus: - return m_focus->focusStatus(); - case QCamera::LockExposure: - if (m_pendingLocks & QCamera::LockExposure) - return QCamera::Searching; - return isExposureLocked() ? QCamera::Locked : QCamera::Unlocked; - case QCamera::LockWhiteBalance: - if (m_pendingLocks & QCamera::LockWhiteBalance) - return QCamera::Searching; - return isWhiteBalanceLocked() ? QCamera::Locked : QCamera::Unlocked; - default: - return QCamera::Unlocked; - } -} - -void CameraBinControl::searchAndLock(QCamera::LockTypes locks) -{ - m_pendingLocks &= ~locks; - - if (locks & QCamera::LockFocus) { - m_pendingLocks |= QCamera::LockFocus; - m_focus->_q_startFocusing(); - } - if (!m_pendingLocks) - m_lockTimer.stop(); - - if (locks & QCamera::LockExposure) { - if (isExposureLocked()) { - unlockExposure(QCamera::Searching, QCamera::UserRequest); - m_pendingLocks |= QCamera::LockExposure; - m_lockTimer.start(1000, this); - } else { - lockExposure(QCamera::UserRequest); - } - } - if (locks & QCamera::LockWhiteBalance) { - if (isWhiteBalanceLocked()) { - unlockWhiteBalance(QCamera::Searching, QCamera::UserRequest); - m_pendingLocks |= QCamera::LockWhiteBalance; - m_lockTimer.start(1000, this); - } else { - lockWhiteBalance(QCamera::UserRequest); - } - } -} - -void CameraBinControl::unlock(QCamera::LockTypes locks) -{ - m_pendingLocks &= ~locks; - - if (locks & QCamera::LockFocus) - m_focus->_q_stopFocusing(); - - if (!m_pendingLocks) - m_lockTimer.stop(); - - if (locks & QCamera::LockExposure) - unlockExposure(QCamera::Unlocked, QCamera::UserRequest); - if (locks & QCamera::LockWhiteBalance) - unlockWhiteBalance(QCamera::Unlocked, QCamera::UserRequest); -} - -void CameraBinControl::updateFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason) -{ - if (status != QCamera::Searching) - m_pendingLocks &= ~QCamera::LockFocus; - - if (status == QCamera::Locked && !m_lockTimer.isActive()) { - if (m_pendingLocks & QCamera::LockExposure) - lockExposure(QCamera::LockAcquired); - if (m_pendingLocks & QCamera::LockWhiteBalance) - lockWhiteBalance(QCamera::LockAcquired); - } - emit lockStatusChanged(QCamera::LockFocus, status, reason); -} - -void CameraBinControl::timerEvent(QTimerEvent *event) -{ - if (event->timerId() != m_lockTimer.timerId()) - return QCameraControl::timerEvent(event); - - m_lockTimer.stop(); - - if (!(m_pendingLocks & QCamera::LockFocus)) { - if (m_pendingLocks & QCamera::LockExposure) - lockExposure(QCamera::LockAcquired); - if (m_pendingLocks & QCamera::LockWhiteBalance) - lockWhiteBalance(QCamera::LockAcquired); - } -} - -bool CameraBinControl::isExposureLocked() const -{ - if (GstElement *source = m_session->cameraSource()) { - GstPhotographyExposureMode exposureMode = GST_PHOTOGRAPHY_EXPOSURE_MODE_AUTO; - g_object_get (G_OBJECT(source), "exposure-mode", &exposureMode, NULL); - return exposureMode == GST_PHOTOGRAPHY_EXPOSURE_MODE_MANUAL; - } - - return false; -} - -void CameraBinControl::lockExposure(QCamera::LockChangeReason reason) -{ - GstElement *source = m_session->cameraSource(); - if (!source) - return; - - m_pendingLocks &= ~QCamera::LockExposure; - g_object_set( - G_OBJECT(source), - "exposure-mode", - GST_PHOTOGRAPHY_EXPOSURE_MODE_MANUAL, - NULL); - emit lockStatusChanged(QCamera::LockExposure, QCamera::Locked, reason); -} - -void CameraBinControl::unlockExposure(QCamera::LockStatus status, QCamera::LockChangeReason reason) -{ - GstElement *source = m_session->cameraSource(); - if (!source) - return; - - g_object_set( - G_OBJECT(source), - "exposure-mode", - GST_PHOTOGRAPHY_EXPOSURE_MODE_AUTO, - NULL); - emit lockStatusChanged(QCamera::LockExposure, status, reason); -} - -bool CameraBinControl::isWhiteBalanceLocked() const -{ - if (GstPhotography *photography = m_session->photography()) { - GstPhotographyWhiteBalanceMode whiteBalanceMode; - return gst_photography_get_white_balance_mode(photography, &whiteBalanceMode) - && whiteBalanceMode == GST_PHOTOGRAPHY_WB_MODE_MANUAL; - } - - return false; -} - -void CameraBinControl::lockWhiteBalance(QCamera::LockChangeReason reason) -{ - m_pendingLocks &= ~QCamera::LockWhiteBalance; - m_session->imageProcessingControl()->lockWhiteBalance(); - emit lockStatusChanged(QCamera::LockWhiteBalance, QCamera::Locked, reason); -} - -void CameraBinControl::unlockWhiteBalance( - QCamera::LockStatus status, QCamera::LockChangeReason reason) -{ - m_session->imageProcessingControl()->lockWhiteBalance(); - emit lockStatusChanged(QCamera::LockWhiteBalance, status, reason); -} - -QList<QCameraViewfinderSettings> CameraBinControl::supportedViewfinderSettings() const -{ - return m_session->supportedViewfinderSettings(); -} - -QCameraViewfinderSettings CameraBinControl::viewfinderSettings() const -{ - return m_session->viewfinderSettings(); -} - -void CameraBinControl::setViewfinderSettings(const QCameraViewfinderSettings &settings) -{ - m_session->setViewfinderSettings(settings); -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabincontrol.h b/src/plugins/gstreamer/camerabin/camerabincontrol.h deleted file mode 100644 index 20039bb72..000000000 --- a/src/plugins/gstreamer/camerabin/camerabincontrol.h +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef CAMERABINCONTROL_H -#define CAMERABINCONTROL_H - -#include <QHash> -#include <qbasictimer.h> -#include <qcameracontrol.h> -#include "camerabinsession.h" - -QT_BEGIN_NAMESPACE - -class CameraBinControl : public QCameraControl -{ - Q_OBJECT - Q_PROPERTY(bool viewfinderColorSpaceConversion READ viewfinderColorSpaceConversion WRITE setViewfinderColorSpaceConversion) -public: - CameraBinControl( CameraBinSession *session ); - virtual ~CameraBinControl(); - - bool isValid() const { return true; } - - QCamera::State state() const override; - void setState(QCamera::State state) override; - - QCamera::Status status() const override; - - QCamera::CaptureModes captureMode() const override; - void setCaptureMode(QCamera::CaptureModes mode) override; - - bool isCaptureModeSupported(QCamera::CaptureModes mode) const override; - bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const override; - bool viewfinderColorSpaceConversion() const; - - QCamera::LockTypes supportedLocks() const override; - - QCamera::LockStatus lockStatus(QCamera::LockType lock) const override; - - void searchAndLock(QCamera::LockTypes locks) override; - void unlock(QCamera::LockTypes locks) override; - - QList<QCameraViewfinderSettings> supportedViewfinderSettings() const override; - - QCameraViewfinderSettings viewfinderSettings() const override; - void setViewfinderSettings(const QCameraViewfinderSettings &settings) override; - -public slots: - void reloadLater(); - void setViewfinderColorSpaceConversion(bool enabled); - -private slots: - void delayedReload(); - - void handleBusyChanged(bool); - void handleCameraError(int error, const QString &errorString); - -private: - void updateSupportedResolutions(const QString &device); - -protected: - void timerEvent(QTimerEvent *event) override; - -private slots: - void updateFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason); - -private: - bool isExposureLocked() const; - void lockExposure(QCamera::LockChangeReason reason); - void unlockExposure(QCamera::LockStatus status, QCamera::LockChangeReason reason); - - bool isWhiteBalanceLocked() const; - void lockWhiteBalance(QCamera::LockChangeReason reason); - void unlockWhiteBalance(QCamera::LockStatus status, QCamera::LockChangeReason reason); - - CameraBinSession *m_session; - QCamera::State m_state; - - bool m_reloadPending; - - CameraBinFocus *m_focus; - QBasicTimer m_lockTimer; - QCamera::LockTypes m_pendingLocks; -}; - -QT_END_NAMESPACE - -#endif // CAMERABINCONTROL_H diff --git a/src/plugins/gstreamer/camerabin/camerabinexposure.cpp b/src/plugins/gstreamer/camerabin/camerabinexposure.cpp deleted file mode 100644 index 740532d22..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinexposure.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "camerabinexposure.h" -#include "camerabinsession.h" -#include <gst/interfaces/photography.h> - -#include <QDebug> - -QT_BEGIN_NAMESPACE - -CameraBinExposure::CameraBinExposure(CameraBinSession *session) - :QCameraExposureControl(session), - m_session(session) -{ -} - -CameraBinExposure::~CameraBinExposure() -{ -} - -bool CameraBinExposure::isParameterSupported(ExposureParameter parameter) const -{ - switch (parameter) { - case QCameraExposureControl::ExposureCompensation: - case QCameraExposureControl::ISO: - case QCameraExposureControl::Aperture: - case QCameraExposureControl::ShutterSpeed: - return true; - default: - return false; - } -} - -QVariantList CameraBinExposure::supportedParameterRange(ExposureParameter parameter, - bool *continuous) const -{ - if (continuous) - *continuous = false; - - QVariantList res; - switch (parameter) { - case QCameraExposureControl::ExposureCompensation: - if (continuous) - *continuous = true; - res << -2.0 << 2.0; - break; - case QCameraExposureControl::ISO: - res << 100 << 200 << 400; - break; - case QCameraExposureControl::Aperture: - res << 2.8; - break; - default: - break; - } - - return res; -} - -QVariant CameraBinExposure::requestedValue(ExposureParameter parameter) const -{ - return m_requestedValues.value(parameter); -} - -QVariant CameraBinExposure::actualValue(ExposureParameter parameter) const -{ - switch (parameter) { - case QCameraExposureControl::ExposureCompensation: - { - gfloat ev; - gst_photography_get_ev_compensation(m_session->photography(), &ev); - return QVariant(ev); - } - case QCameraExposureControl::ISO: - { - guint isoSpeed = 0; - gst_photography_get_iso_speed(m_session->photography(), &isoSpeed); - return QVariant(isoSpeed); - } - case QCameraExposureControl::Aperture: - return QVariant(2.8); - case QCameraExposureControl::ShutterSpeed: - { - guint32 shutterSpeed = 0; - gst_photography_get_exposure(m_session->photography(), &shutterSpeed); - - return QVariant(shutterSpeed/1000000.0); - } - case QCameraExposureControl::ExposureMode: - { - GstPhotographySceneMode sceneMode; - gst_photography_get_scene_mode(m_session->photography(), &sceneMode); - - switch (sceneMode) { - case GST_PHOTOGRAPHY_SCENE_MODE_PORTRAIT: - return QVariant::fromValue(QCameraExposure::ExposurePortrait); - case GST_PHOTOGRAPHY_SCENE_MODE_SPORT: - return QVariant::fromValue(QCameraExposure::ExposureSports); - case GST_PHOTOGRAPHY_SCENE_MODE_NIGHT: - return QVariant::fromValue(QCameraExposure::ExposureNight); - case GST_PHOTOGRAPHY_SCENE_MODE_MANUAL: - return QVariant::fromValue(QCameraExposure::ExposureManual); - case GST_PHOTOGRAPHY_SCENE_MODE_LANDSCAPE: - return QVariant::fromValue(QCameraExposure::ExposureLandscape); - case GST_PHOTOGRAPHY_SCENE_MODE_SNOW: - return QVariant::fromValue(QCameraExposure::ExposureSnow); - case GST_PHOTOGRAPHY_SCENE_MODE_BEACH: - return QVariant::fromValue(QCameraExposure::ExposureBeach); - case GST_PHOTOGRAPHY_SCENE_MODE_ACTION: - return QVariant::fromValue(QCameraExposure::ExposureAction); - case GST_PHOTOGRAPHY_SCENE_MODE_NIGHT_PORTRAIT: - return QVariant::fromValue(QCameraExposure::ExposureNightPortrait); - case GST_PHOTOGRAPHY_SCENE_MODE_THEATRE: - return QVariant::fromValue(QCameraExposure::ExposureTheatre); - case GST_PHOTOGRAPHY_SCENE_MODE_SUNSET: - return QVariant::fromValue(QCameraExposure::ExposureSunset); - case GST_PHOTOGRAPHY_SCENE_MODE_STEADY_PHOTO: - return QVariant::fromValue(QCameraExposure::ExposureSteadyPhoto); - case GST_PHOTOGRAPHY_SCENE_MODE_FIREWORKS: - return QVariant::fromValue(QCameraExposure::ExposureFireworks); - case GST_PHOTOGRAPHY_SCENE_MODE_PARTY: - return QVariant::fromValue(QCameraExposure::ExposureParty); - case GST_PHOTOGRAPHY_SCENE_MODE_CANDLELIGHT: - return QVariant::fromValue(QCameraExposure::ExposureCandlelight); - case GST_PHOTOGRAPHY_SCENE_MODE_BARCODE: - return QVariant::fromValue(QCameraExposure::ExposureBarcode); - //no direct mapping available so mapping to auto mode - case GST_PHOTOGRAPHY_SCENE_MODE_CLOSEUP: - case GST_PHOTOGRAPHY_SCENE_MODE_AUTO: - default: - return QVariant::fromValue(QCameraExposure::ExposureAuto); - } - } - default: - return QVariant(); - } -} - -bool CameraBinExposure::setValue(ExposureParameter parameter, const QVariant& value) -{ - QVariant oldValue = actualValue(parameter); - - switch (parameter) { - case QCameraExposureControl::ExposureCompensation: - gst_photography_set_ev_compensation(m_session->photography(), value.toReal()); - break; - case QCameraExposureControl::ISO: - gst_photography_set_iso_speed(m_session->photography(), value.toInt()); - break; - case QCameraExposureControl::Aperture: - gst_photography_set_aperture(m_session->photography(), guint(value.toReal()*1000000)); - break; - case QCameraExposureControl::ShutterSpeed: - gst_photography_set_exposure(m_session->photography(), guint(value.toReal()*1000000)); - break; - case QCameraExposureControl::ExposureMode: - { - QCameraExposure::ExposureMode mode = value.value<QCameraExposure::ExposureMode>(); - GstPhotographySceneMode sceneMode; - - gst_photography_get_scene_mode(m_session->photography(), &sceneMode); - - switch (mode) { - case QCameraExposure::ExposureManual: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_MANUAL; - break; - case QCameraExposure::ExposurePortrait: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_PORTRAIT; - break; - case QCameraExposure::ExposureSports: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_SPORT; - break; - case QCameraExposure::ExposureNight: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_NIGHT; - break; - case QCameraExposure::ExposureAuto: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_AUTO; - break; - case QCameraExposure::ExposureLandscape: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_LANDSCAPE; - break; - case QCameraExposure::ExposureSnow: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_SNOW; - break; - case QCameraExposure::ExposureBeach: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_BEACH; - break; - case QCameraExposure::ExposureAction: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_ACTION; - break; - case QCameraExposure::ExposureNightPortrait: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_NIGHT_PORTRAIT; - break; - case QCameraExposure::ExposureTheatre: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_THEATRE; - break; - case QCameraExposure::ExposureSunset: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_SUNSET; - break; - case QCameraExposure::ExposureSteadyPhoto: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_STEADY_PHOTO; - break; - case QCameraExposure::ExposureFireworks: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_FIREWORKS; - break; - case QCameraExposure::ExposureParty: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_PARTY; - break; - case QCameraExposure::ExposureCandlelight: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_CANDLELIGHT; - break; - case QCameraExposure::ExposureBarcode: - sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_BARCODE; - break; - default: - break; - } - - gst_photography_set_scene_mode(m_session->photography(), sceneMode); - break; - } - default: - return false; - } - - if (!qFuzzyCompare(m_requestedValues.value(parameter).toReal(), value.toReal())) { - m_requestedValues[parameter] = value; - emit requestedValueChanged(parameter); - } - - QVariant newValue = actualValue(parameter); - if (!qFuzzyCompare(oldValue.toReal(), newValue.toReal())) - emit actualValueChanged(parameter); - - return true; -} - -QCameraExposure::FlashModes CameraBinExposure::flashMode() const -{ - GstPhotographyFlashMode flashMode; - gst_photography_get_flash_mode(m_session->photography(), &flashMode); - - QCameraExposure::FlashModes modes; - switch (flashMode) { - case GST_PHOTOGRAPHY_FLASH_MODE_AUTO: modes |= QCameraExposure::FlashAuto; break; - case GST_PHOTOGRAPHY_FLASH_MODE_OFF: modes |= QCameraExposure::FlashOff; break; - case GST_PHOTOGRAPHY_FLASH_MODE_ON: modes |= QCameraExposure::FlashOn; break; - case GST_PHOTOGRAPHY_FLASH_MODE_FILL_IN: modes |= QCameraExposure::FlashFill; break; - case GST_PHOTOGRAPHY_FLASH_MODE_RED_EYE: modes |= QCameraExposure::FlashRedEyeReduction; break; - default: - modes |= QCameraExposure::FlashAuto; - break; - } - return modes; -} - -void CameraBinExposure::setFlashMode(QCameraExposure::FlashModes mode) -{ - GstPhotographyFlashMode flashMode; - gst_photography_get_flash_mode(m_session->photography(), &flashMode); - - if (mode.testFlag(QCameraExposure::FlashAuto)) flashMode = GST_PHOTOGRAPHY_FLASH_MODE_AUTO; - else if (mode.testFlag(QCameraExposure::FlashOff)) flashMode = GST_PHOTOGRAPHY_FLASH_MODE_OFF; - else if (mode.testFlag(QCameraExposure::FlashOn)) flashMode = GST_PHOTOGRAPHY_FLASH_MODE_ON; - else if (mode.testFlag(QCameraExposure::FlashFill)) flashMode = GST_PHOTOGRAPHY_FLASH_MODE_FILL_IN; - else if (mode.testFlag(QCameraExposure::FlashRedEyeReduction)) flashMode = GST_PHOTOGRAPHY_FLASH_MODE_RED_EYE; - - gst_photography_set_flash_mode(m_session->photography(), flashMode); -} - -bool CameraBinExposure::isFlashModeSupported(QCameraExposure::FlashModes mode) const -{ - return mode == QCameraExposure::FlashOff || - mode == QCameraExposure::FlashOn || - mode == QCameraExposure::FlashAuto || - mode == QCameraExposure::FlashRedEyeReduction || - mode == QCameraExposure::FlashFill; -} - -bool CameraBinExposure::isFlashReady() const -{ - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinexposure.h b/src/plugins/gstreamer/camerabin/camerabinexposure.h deleted file mode 100644 index 24722a632..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinexposure.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CAMERABINEXPOSURECONTROL_H -#define CAMERABINEXPOSURECONTROL_H - -#include <qcamera.h> -#include <qcameraexposurecontrol.h> - -#include <gst/gst.h> -#include <glib.h> - -QT_BEGIN_NAMESPACE - -class CameraBinSession; - -class CameraBinExposure : public QCameraExposureControl -{ - Q_OBJECT - -public: - CameraBinExposure(CameraBinSession *session); - virtual ~CameraBinExposure(); - - bool isParameterSupported(ExposureParameter parameter) const override; - QVariantList supportedParameterRange(ExposureParameter parameter, bool *continuous) const override; - - QVariant requestedValue(ExposureParameter parameter) const override; - QVariant actualValue(ExposureParameter parameter) const override; - bool setValue(ExposureParameter parameter, const QVariant &value) override; - - QCameraExposure::FlashModes flashMode() const override; - void setFlashMode(QCameraExposure::FlashModes mode) override; - bool isFlashModeSupported(QCameraExposure::FlashModes mode) const override; - - bool isFlashReady() const override; - -private: - CameraBinSession *m_session; - QHash<ExposureParameter, QVariant> m_requestedValues; -}; - -QT_END_NAMESPACE - -#endif // CAMERABINEXPOSURECONTROL_H diff --git a/src/plugins/gstreamer/camerabin/camerabinfocus.cpp b/src/plugins/gstreamer/camerabin/camerabinfocus.cpp deleted file mode 100644 index f795b0f2f..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinfocus.cpp +++ /dev/null @@ -1,607 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "camerabinfocus.h" -#include "camerabinsession.h" - -#include <gst/interfaces/photography.h> - -#include <QDebug> -#include <QtCore/qcoreevent.h> -#include <QtCore/qmetaobject.h> - -#include <private/qgstutils_p.h> - -#define ZOOM_PROPERTY "zoom" -#define MAX_ZOOM_PROPERTY "max-zoom" - -//#define CAMERABIN_DEBUG 1 - -QT_BEGIN_NAMESPACE - -CameraBinFocus::CameraBinFocus(CameraBinSession *session) - :QCameraFocusControl(session), - QGstreamerBufferProbe(ProbeBuffers), - m_session(session), - m_cameraStatus(QCamera::UnloadedStatus), - m_focusMode(QCameraFocus::AutoFocus), - m_focusPointMode(QCameraFocus::FocusPointAuto), - m_focusStatus(QCamera::Unlocked), - m_focusZoneStatus(QCameraFocusZone::Selected), - m_focusPoint(0.5, 0.5), - m_focusRect(0, 0, 0.3, 0.3) -{ - m_focusRect.moveCenter(m_focusPoint); - - gst_photography_set_focus_mode(m_session->photography(), GST_PHOTOGRAPHY_FOCUS_MODE_AUTO); - - connect(m_session, SIGNAL(statusChanged(QCamera::Status)), - this, SLOT(_q_handleCameraStatusChange(QCamera::Status))); - - 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); -} - -CameraBinFocus::~CameraBinFocus() -{ -} - -QCameraFocus::FocusModes CameraBinFocus::focusMode() const -{ - return m_focusMode; -} - -void CameraBinFocus::setFocusMode(QCameraFocus::FocusModes mode) -{ - GstPhotographyFocusMode photographyMode; - - switch (mode) { - case QCameraFocus::AutoFocus: - photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_AUTO; - break; - case QCameraFocus::HyperfocalFocus: - photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_HYPERFOCAL; - break; - case QCameraFocus::InfinityFocus: - photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_INFINITY; - break; - case QCameraFocus::ContinuousFocus: - photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_CONTINUOUS_NORMAL; - break; - case QCameraFocus::MacroFocus: - photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_MACRO; - break; - default: - if (mode & QCameraFocus::AutoFocus) { - photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_AUTO; - break; - } else { - return; - } - } - - if (gst_photography_set_focus_mode(m_session->photography(), photographyMode)) - m_focusMode = mode; -} - -bool CameraBinFocus::isFocusModeSupported(QCameraFocus::FocusModes mode) const -{ - switch (mode) { - case QCameraFocus::AutoFocus: - case QCameraFocus::HyperfocalFocus: - case QCameraFocus::InfinityFocus: - case QCameraFocus::ContinuousFocus: - case QCameraFocus::MacroFocus: - return true; - default: - return mode & QCameraFocus::AutoFocus; - } -} - -QCameraFocus::FocusPointMode CameraBinFocus::focusPointMode() const -{ - return m_focusPointMode; -} - -void CameraBinFocus::setFocusPointMode(QCameraFocus::FocusPointMode mode) -{ - GstElement *source = m_session->cameraSource(); - - if (m_focusPointMode == mode || !source) - return; - - if (m_focusPointMode == QCameraFocus::FocusPointFaceDetection) { - g_object_set (G_OBJECT(source), "detect-faces", FALSE, NULL); - - if (GstPad *pad = gst_element_get_static_pad(source, "vfsrc")) { - removeProbeFromPad(pad); - gst_object_unref(GST_OBJECT(pad)); - } - - m_faceResetTimer.stop(); - m_faceFocusRects.clear(); - - QMutexLocker locker(&m_mutex); - m_faces.clear(); - } - - if (m_focusPointMode != QCameraFocus::FocusPointAuto) - resetFocusPoint(); - - switch (mode) { - case QCameraFocus::FocusPointAuto: - case QCameraFocus::FocusPointCustom: - break; - case QCameraFocus::FocusPointFaceDetection: - if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "detect-faces")) { - if (GstPad *pad = gst_element_get_static_pad(source, "vfsrc")) { - addProbeToPad(pad); - g_object_set (G_OBJECT(source), "detect-faces", TRUE, NULL); - break; - } - } - return; - default: - return; - } - - m_focusPointMode = mode; - emit focusPointModeChanged(m_focusPointMode); - emit focusZonesChanged(); -} - -bool CameraBinFocus::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const -{ - switch (mode) { - case QCameraFocus::FocusPointAuto: - case QCameraFocus::FocusPointCustom: - return true; - case QCameraFocus::FocusPointFaceDetection: - if (GstElement *source = m_session->cameraSource()) - return g_object_class_find_property(G_OBJECT_GET_CLASS(source), "detect-faces"); - return false; - default: - return false; - } -} - -QPointF CameraBinFocus::customFocusPoint() const -{ - return m_focusPoint; -} - -void CameraBinFocus::setCustomFocusPoint(const QPointF &point) -{ - if (m_focusPoint != point) { - m_focusPoint = point; - - // Bound the focus point so the focus rect remains entirely within the unit square. - m_focusPoint.setX(qBound(m_focusRect.width() / 2, m_focusPoint.x(), 1 - m_focusRect.width() / 2)); - m_focusPoint.setY(qBound(m_focusRect.height() / 2, m_focusPoint.y(), 1 - m_focusRect.height() / 2)); - - if (m_focusPointMode == QCameraFocus::FocusPointCustom) { - const QRectF focusRect = m_focusRect; - m_focusRect.moveCenter(m_focusPoint); - - updateRegionOfInterest(m_focusRect); - - if (focusRect != m_focusRect) { - emit focusZonesChanged(); - } - } - - emit customFocusPointChanged(m_focusPoint); - } -} - -QCameraFocusZoneList CameraBinFocus::focusZones() const -{ - QCameraFocusZoneList zones; - - if (m_focusPointMode != QCameraFocus::FocusPointFaceDetection) { - zones.append(QCameraFocusZone(m_focusRect, m_focusZoneStatus)); - } else for (const QRect &face : qAsConst(m_faceFocusRects)) { - const QRectF normalizedRect( - face.x() / qreal(m_viewfinderResolution.width()), - face.y() / qreal(m_viewfinderResolution.height()), - face.width() / qreal(m_viewfinderResolution.width()), - face.height() / qreal(m_viewfinderResolution.height())); - zones.append(QCameraFocusZone(normalizedRect, m_focusZoneStatus)); - } - return zones; -} - -void CameraBinFocus::handleFocusMessage(GstMessage *gm) -{ - //it's a sync message, so it's called from non main thread - const GstStructure *structure = gst_message_get_structure(gm); - if (gst_structure_has_name(structure, GST_PHOTOGRAPHY_AUTOFOCUS_DONE)) { - gint status = GST_PHOTOGRAPHY_FOCUS_STATUS_NONE; - gst_structure_get_int (structure, "status", &status); - QCamera::LockStatus focusStatus = m_focusStatus; - QCamera::LockChangeReason reason = QCamera::UserRequest; - - switch (status) { - case GST_PHOTOGRAPHY_FOCUS_STATUS_FAIL: - focusStatus = QCamera::Unlocked; - reason = QCamera::LockFailed; - break; - case GST_PHOTOGRAPHY_FOCUS_STATUS_SUCCESS: - focusStatus = QCamera::Locked; - break; - case GST_PHOTOGRAPHY_FOCUS_STATUS_NONE: - break; - case GST_PHOTOGRAPHY_FOCUS_STATUS_RUNNING: - focusStatus = QCamera::Searching; - break; - default: - break; - } - - static int signalIndex = metaObject()->indexOfSlot( - "_q_setFocusStatus(QCamera::LockStatus,QCamera::LockChangeReason)"); - metaObject()->method(signalIndex).invoke(this, - Qt::QueuedConnection, - Q_ARG(QCamera::LockStatus,focusStatus), - Q_ARG(QCamera::LockChangeReason,reason)); - } -} - -void CameraBinFocus::_q_setFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason) -{ -#ifdef CAMERABIN_DEBUG - qDebug() << Q_FUNC_INFO << "Current:" - << m_focusStatus - << "New:" - << status << reason; -#endif - - if (m_focusStatus != status) { - m_focusStatus = status; - - QCameraFocusZone::FocusZoneStatus zonesStatus = - m_focusStatus == QCamera::Locked ? - QCameraFocusZone::Focused : QCameraFocusZone::Selected; - - if (m_focusZoneStatus != zonesStatus) { - m_focusZoneStatus = zonesStatus; - emit focusZonesChanged(); - } - - if (m_focusPointMode == QCameraFocus::FocusPointFaceDetection - && m_focusStatus == QCamera::Unlocked) { - _q_updateFaces(); - } - - emit _q_focusStatusChanged(m_focusStatus, reason); - } -} - -void CameraBinFocus::_q_handleCameraStatusChange(QCamera::Status status) -{ - m_cameraStatus = status; - if (status == QCamera::ActiveStatus) { - if (GstPad *pad = gst_element_get_static_pad(m_session->cameraSource(), "vfsrc")) { - if (GstCaps *caps = qt_gst_pad_get_current_caps(pad)) { - if (GstStructure *structure = gst_caps_get_structure(caps, 0)) { - int width = 0; - int height = 0; - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); - setViewfinderResolution(QSize(width, height)); - } - gst_caps_unref(caps); - } - gst_object_unref(GST_OBJECT(pad)); - } - if (m_focusPointMode == QCameraFocus::FocusPointCustom) { - updateRegionOfInterest(m_focusRect); - } - } else { - _q_setFocusStatus(QCamera::Unlocked, QCamera::LockLost); - - resetFocusPoint(); - } -} - -void CameraBinFocus::_q_startFocusing() -{ - _q_setFocusStatus(QCamera::Searching, QCamera::UserRequest); - gst_photography_set_autofocus(m_session->photography(), TRUE); -} - -void CameraBinFocus::_q_stopFocusing() -{ - gst_photography_set_autofocus(m_session->photography(), FALSE); - _q_setFocusStatus(QCamera::Unlocked, QCamera::UserRequest); -} - -void CameraBinFocus::setViewfinderResolution(const QSize &resolution) -{ - if (resolution != m_viewfinderResolution) { - m_viewfinderResolution = resolution; - if (!resolution.isEmpty()) { - const QPointF center = m_focusRect.center(); - m_focusRect.setWidth(m_focusRect.height() * resolution.height() / resolution.width()); - m_focusRect.moveCenter(center); - } - } -} - -void CameraBinFocus::resetFocusPoint() -{ - const QRectF focusRect = m_focusRect; - m_focusPoint = QPointF(0.5, 0.5); - m_focusRect.moveCenter(m_focusPoint); - - updateRegionOfInterest(QList<QRect>()); - - if (focusRect != m_focusRect) { - emit customFocusPointChanged(m_focusPoint); - emit focusZonesChanged(); - } -} - -static void appendRegion(GValue *regions, int priority, const QRect &rectangle) -{ - GstStructure *region = gst_structure_new( - "region", - "region-x" , G_TYPE_UINT , rectangle.x(), - "region-y" , G_TYPE_UINT, rectangle.y(), - "region-w" , G_TYPE_UINT , rectangle.width(), - "region-h" , G_TYPE_UINT, rectangle.height(), - "region-priority" , G_TYPE_UINT, priority, - NULL); - - GValue regionValue = G_VALUE_INIT; - g_value_init(®ionValue, GST_TYPE_STRUCTURE); - gst_value_set_structure(®ionValue, region); - gst_structure_free(region); - - gst_value_list_append_value(regions, ®ionValue); - g_value_unset(®ionValue); -} - -void CameraBinFocus::updateRegionOfInterest(const QRectF &rectangle) -{ - updateRegionOfInterest(QList<QRect>() << QRect( - rectangle.x() * m_viewfinderResolution.width(), - rectangle.y() * m_viewfinderResolution.height(), - rectangle.width() * m_viewfinderResolution.width(), - rectangle.height() * m_viewfinderResolution.height())); -} - -void CameraBinFocus::updateRegionOfInterest(const QList<QRect> &rectangles) -{ - if (m_cameraStatus != QCamera::ActiveStatus) - return; - - GstElement * const cameraSource = m_session->cameraSource(); - if (!cameraSource) - return; - - GValue regions = G_VALUE_INIT; - g_value_init(®ions, GST_TYPE_LIST); - - if (rectangles.isEmpty()) { - appendRegion(®ions, 0, QRect(0, 0, 0, 0)); - } else { - // Add padding around small face rectangles so the auto focus has a reasonable amount - // of image to work with. - const int minimumDimension = qMin( - m_viewfinderResolution.width(), m_viewfinderResolution.height()) * 0.3; - const QRect viewfinderRectangle(QPoint(0, 0), m_viewfinderResolution); - - for (const QRect &rectangle : rectangles) { - QRect paddedRectangle( - 0, - 0, - qMax(rectangle.width(), minimumDimension), - qMax(rectangle.height(), minimumDimension)); - paddedRectangle.moveCenter(rectangle.center()); - - appendRegion(®ions, 1, viewfinderRectangle.intersected(paddedRectangle)); - } - } - - GstStructure *regionsOfInterest = gst_structure_new( - "regions-of-interest", - "frame-width" , G_TYPE_UINT , m_viewfinderResolution.width(), - "frame-height" , G_TYPE_UINT, m_viewfinderResolution.height(), - NULL); - gst_structure_set_value(regionsOfInterest, "regions", ®ions); - g_value_unset(®ions); - - GstEvent *event = gst_event_new_custom(GST_EVENT_CUSTOM_UPSTREAM, regionsOfInterest); - gst_element_send_event(cameraSource, event); -} - -void CameraBinFocus::_q_updateFaces() -{ - if (m_focusPointMode != QCameraFocus::FocusPointFaceDetection - || m_focusStatus != QCamera::Unlocked) { - return; - } - - QList<QRect> faces; - - { - QMutexLocker locker(&m_mutex); - faces = m_faces; - } - - if (!faces.isEmpty()) { - m_faceResetTimer.stop(); - m_faceFocusRects = faces; - updateRegionOfInterest(m_faceFocusRects); - emit focusZonesChanged(); - } else { - m_faceResetTimer.start(500, this); - } -} - -void CameraBinFocus::timerEvent(QTimerEvent *event) -{ - if (event->timerId() == m_faceResetTimer.timerId()) { - m_faceResetTimer.stop(); - - if (m_focusStatus == QCamera::Unlocked) { - m_faceFocusRects.clear(); - updateRegionOfInterest(m_faceFocusRects); - emit focusZonesChanged(); - } - } else { - QCameraFocusControl::timerEvent(event); - } -} - -bool CameraBinFocus::probeBuffer(GstBuffer *buffer) -{ - QList<QRect> faces; - - gpointer state = NULL; - const GstMetaInfo *info = GST_VIDEO_REGION_OF_INTEREST_META_INFO; - - while (GstMeta *meta = gst_buffer_iterate_meta(buffer, &state)) { - if (meta->info->api != info->api) - continue; - - GstVideoRegionOfInterestMeta *region = reinterpret_cast<GstVideoRegionOfInterestMeta *>(meta); - - faces.append(QRect(region->x, region->y, region->w, region->h)); - } - - QMutexLocker locker(&m_mutex); - - if (m_faces != faces) { - m_faces = faces; - - static const int signalIndex = metaObject()->indexOfSlot("_q_updateFaces()"); - metaObject()->method(signalIndex).invoke(this, Qt::QueuedConnection); - } - - return true; -} - -qreal CameraBinFocus::maximumOpticalZoom() const -{ - return 1.0; -} - -qreal CameraBinFocus::maximumDigitalZoom() const -{ - gfloat zoomFactor = 1.0; - g_object_get(GST_BIN(m_session->cameraBin()), MAX_ZOOM_PROPERTY, &zoomFactor, NULL); - return zoomFactor; -} - -qreal CameraBinFocus::requestedDigitalZoom() const -{ - return m_requestedDigitalZoom; -} - -qreal CameraBinFocus::requestedOpticalZoom() const -{ - return m_requestedOpticalZoom; -} - -qreal CameraBinFocus::currentOpticalZoom() const -{ - return 1.0; -} - -qreal CameraBinFocus::currentDigitalZoom() const -{ - gfloat zoomFactor = 1.0; - g_object_get(GST_BIN(m_session->cameraBin()), ZOOM_PROPERTY, &zoomFactor, NULL); - return zoomFactor; -} - -void CameraBinFocus::zoomTo(qreal optical, qreal digital) -{ - qreal oldDigitalZoom = currentDigitalZoom(); - - if (m_requestedDigitalZoom != digital) { - m_requestedDigitalZoom = digital; - emit requestedDigitalZoomChanged(digital); - } - - if (m_requestedOpticalZoom != optical) { - m_requestedOpticalZoom = optical; - emit requestedOpticalZoomChanged(optical); - } - - digital = qBound(qreal(1.0), digital, maximumDigitalZoom()); - g_object_set(GST_BIN(m_session->cameraBin()), ZOOM_PROPERTY, digital, NULL); - - qreal newDigitalZoom = currentDigitalZoom(); - if (!qFuzzyCompare(oldDigitalZoom, newDigitalZoom)) - emit currentDigitalZoomChanged(digital); -} - -void CameraBinFocus::updateZoom(GObject *o, GParamSpec *p, gpointer d) -{ - Q_UNUSED(p); - - gfloat zoomFactor = 1.0; - g_object_get(o, ZOOM_PROPERTY, &zoomFactor, NULL); - - CameraBinFocus *zoom = reinterpret_cast<CameraBinFocus *>(d); - - QMetaObject::invokeMethod(zoom, "currentDigitalZoomChanged", - Qt::QueuedConnection, - Q_ARG(qreal, zoomFactor)); -} - -void CameraBinFocus::updateMaxZoom(GObject *o, GParamSpec *p, gpointer d) -{ - Q_UNUSED(p); - - gfloat zoomFactor = 1.0; - g_object_get(o, MAX_ZOOM_PROPERTY, &zoomFactor, NULL); - - CameraBinFocus *zoom = reinterpret_cast<CameraBinFocus *>(d); - - QMetaObject::invokeMethod(zoom, "maximumDigitalZoomChanged", - Qt::QueuedConnection, - Q_ARG(qreal, zoomFactor)); -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinfocus.h b/src/plugins/gstreamer/camerabin/camerabinfocus.h deleted file mode 100644 index 549b913df..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinfocus.h +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CAMERABINFOCUSCONTROL_H -#define CAMERABINFOCUSCONTROL_H - -#include <qcamera.h> -#include <qcamerafocuscontrol.h> - -#include <private/qgstreamerbufferprobe_p.h> - -#include <qbasictimer.h> -#include <qlist.h> -#include <qmutex.h> - -#include <gst/gst.h> -#include <glib.h> - -QT_BEGIN_NAMESPACE - -class CameraBinSession; - -class CameraBinFocus - : public QCameraFocusControl - , QGstreamerBufferProbe -{ - Q_OBJECT - -public: - CameraBinFocus(CameraBinSession *session); - virtual ~CameraBinFocus(); - - QCameraFocus::FocusModes focusMode() const override; - void setFocusMode(QCameraFocus::FocusModes mode) override; - bool isFocusModeSupported(QCameraFocus::FocusModes mode) const override; - - QCameraFocus::FocusPointMode focusPointMode() const override; - void setFocusPointMode(QCameraFocus::FocusPointMode mode) override; - bool isFocusPointModeSupported(QCameraFocus::FocusPointMode) const override; - QPointF customFocusPoint() const override; - void setCustomFocusPoint(const QPointF &point) override; - - QCameraFocusZoneList focusZones() const override; - - - qreal maximumOpticalZoom() const override; - qreal maximumDigitalZoom() const override; - - qreal requestedOpticalZoom() const override; - qreal requestedDigitalZoom() const override; - qreal currentOpticalZoom() const override; - qreal currentDigitalZoom() const override; - - void zoomTo(qreal optical, qreal digital) override; - - void handleFocusMessage(GstMessage*); - QCamera::LockStatus focusStatus() const { return m_focusStatus; } - -Q_SIGNALS: - void _q_focusStatusChanged(QCamera::LockStatus status, QCamera::LockChangeReason reason); - -public Q_SLOTS: - void _q_startFocusing(); - void _q_stopFocusing(); - - void setViewfinderResolution(const QSize &resolution); - -protected: - void timerEvent(QTimerEvent *event) override; - -private Q_SLOTS: - void _q_setFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason); - void _q_handleCameraStatusChange(QCamera::Status status); - void _q_updateFaces(); - -private: - void resetFocusPoint(); - void updateRegionOfInterest(const QRectF &rectangle); - void updateRegionOfInterest(const QList<QRect> &rectangles); - bool probeBuffer(GstBuffer *buffer) override; - - CameraBinSession *m_session; - QCamera::Status m_cameraStatus; - QCameraFocus::FocusModes m_focusMode; - QCameraFocus::FocusPointMode m_focusPointMode; - QCamera::LockStatus m_focusStatus; - QCameraFocusZone::FocusZoneStatus m_focusZoneStatus; - QPointF m_focusPoint; - QRectF m_focusRect; - QSize m_viewfinderResolution; - QList<QRect> m_faces; - QList<QRect> m_faceFocusRects; - QBasicTimer m_faceResetTimer; - mutable QMutex m_mutex; - - static void updateZoom(GObject *o, GParamSpec *p, gpointer d); - static void updateMaxZoom(GObject *o, GParamSpec *p, gpointer d); - - qreal m_requestedOpticalZoom = 1.; - qreal m_requestedDigitalZoom = 1.; - -}; - -QT_END_NAMESPACE - -#endif // CAMERABINFOCUSCONTROL_H diff --git a/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp b/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp deleted file mode 100644 index 36fb4c205..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "camerabinimagecapture.h" -#include "camerabincontrol.h" -#include "camerabinsession.h" -#include <private/qgstvideobuffer_p.h> -#include <private/qgstutils_p.h> -#include <QtMultimedia/qmediametadata.h> -#include <QtCore/qdebug.h> -#include <QtCore/qbuffer.h> -#include <QtGui/qimagereader.h> - -//#define DEBUG_CAPTURE - -#define IMAGE_DONE_SIGNAL "image-done" - -QT_BEGIN_NAMESPACE - -CameraBinImageCapture::CameraBinImageCapture(CameraBinSession *session) - :QCameraImageCaptureControl(session) - , m_encoderProbe(this) - , m_muxerProbe(this) - , m_session(session) - , m_jpegEncoderElement(0) - , m_metadataMuxerElement(0) - , m_requestId(0) - , m_ready(false) -{ - connect(m_session, SIGNAL(statusChanged(QCamera::Status)), SLOT(updateState())); - connect(m_session, SIGNAL(imageExposed(int)), this, SIGNAL(imageExposed(int))); - connect(m_session, SIGNAL(imageCaptured(int,QImage)), this, SIGNAL(imageCaptured(int,QImage))); - - m_session->bus()->installMessageFilter(this); -} - -CameraBinImageCapture::~CameraBinImageCapture() -{ -} - -bool CameraBinImageCapture::isReadyForCapture() const -{ - return m_ready; -} - -int CameraBinImageCapture::capture(const QString &fileName) -{ - m_requestId++; - - if (!m_ready) { - emit error(m_requestId, QCameraImageCapture::NotReadyError, tr("Camera not ready")); - return m_requestId; - } - -#ifdef DEBUG_CAPTURE - qDebug() << Q_FUNC_INFO << m_requestId << fileName; -#endif - m_session->captureImage(m_requestId, fileName); - return m_requestId; -} - -void CameraBinImageCapture::cancelCapture() -{ -} - -QCameraImageCapture::CaptureDestinations CameraBinImageCapture::captureDestination() const -{ - return m_destination; -} - -void CameraBinImageCapture::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) -{ - m_destination = destination; -} - - -void CameraBinImageCapture::updateState() -{ - bool ready = m_session->status() == QCamera::ActiveStatus; - if (m_ready != ready) { -#ifdef DEBUG_CAPTURE - qDebug() << "readyForCaptureChanged" << ready; -#endif - emit readyForCaptureChanged(m_ready = ready); - } -} - -GstPadProbeReturn CameraBinImageCapture::encoderEventProbe( - GstPad *, GstPadProbeInfo *info, gpointer user_data) -{ - GstEvent * const event = gst_pad_probe_info_get_event(info); - CameraBinImageCapture * const self = static_cast<CameraBinImageCapture *>(user_data); - if (event && GST_EVENT_TYPE(event) == GST_EVENT_TAG) { - GstTagList *gstTags; - gst_event_parse_tag(event, &gstTags); - QMap<QByteArray, QVariant> extendedTags = QGstUtils::gstTagListToMap(gstTags); - -#ifdef DEBUG_CAPTURE - qDebug() << QString(gst_structure_to_string(gst_event_get_structure(event))).right(768); - qDebug() << "Capture event probe" << extendedTags; -#endif - - QVariantMap tags; - tags[QMediaMetaData::ISOSpeedRatings] = extendedTags.value("capturing-iso-speed"); - tags[QMediaMetaData::DigitalZoomRatio] = extendedTags.value("capturing-digital-zoom-ratio"); - tags[QMediaMetaData::ExposureTime] = extendedTags.value("capturing-shutter-speed"); - tags[QMediaMetaData::WhiteBalance] = extendedTags.value("capturing-white-balance"); - tags[QMediaMetaData::Flash] = extendedTags.value("capturing-flash-fired"); - tags[QMediaMetaData::FocalLengthIn35mmFilm] = extendedTags.value("capturing-focal-length"); - tags[QMediaMetaData::ExposureMode] = extendedTags.value("capturing-exposure-mode"); - tags[QMediaMetaData::FNumber] = extendedTags.value("capturing-focal-ratio"); - tags[QMediaMetaData::ExposureMode] = extendedTags.value("capturing-exposure-mode"); - - for (auto i = tags.cbegin(), end = tags.cend(); i != end; ++i) { - if (i.value().isValid()) { - QMetaObject::invokeMethod(self, "imageMetadataAvailable", - Qt::QueuedConnection, - Q_ARG(int, self->m_requestId), - Q_ARG(QString, i.key()), - Q_ARG(QVariant, i.value())); - } - } - } - return GST_PAD_PROBE_OK; -} - -void CameraBinImageCapture::EncoderProbe::probeCaps(GstCaps *caps) -{ - capture->m_bufferFormat = QGstUtils::formatForCaps(caps, &capture->m_videoInfo); -} - -bool CameraBinImageCapture::EncoderProbe::probeBuffer(GstBuffer *) -{ -#ifdef DEBUG_CAPTURE - qDebug() << "Uncompressed buffer probe"; -#endif - // keep the buffer so we can capture to file or encode the image - return true; -} - -void CameraBinImageCapture::MuxerProbe::probeCaps(GstCaps *caps) -{ - capture->m_jpegResolution = QGstUtils::capsCorrectedResolution(caps); -} - -bool CameraBinImageCapture::MuxerProbe::probeBuffer(GstBuffer *buffer) -{ - QCameraImageCapture::CaptureDestinations destination = capture->m_destination; - - if (destination & QCameraImageCapture::CaptureToBuffer) { - QSize resolution = capture->m_jpegResolution; - //if resolution is not presented in caps, try to find it from encoded jpeg data: - GstMapInfo mapInfo; - if (resolution.isEmpty() && gst_buffer_map(buffer, &mapInfo, GST_MAP_READ)) { - QBuffer data; - data.setData(reinterpret_cast<const char*>(mapInfo.data), mapInfo.size); - - QImageReader reader(&data, "JPEG"); - resolution = reader.size(); - - gst_buffer_unmap(buffer, &mapInfo); - } - - GstVideoInfo info; - gst_video_info_set_format( - &info, GST_VIDEO_FORMAT_ENCODED, resolution.width(), resolution.height()); - QGstVideoBuffer *videoBuffer = new QGstVideoBuffer(buffer, info); - - QVideoFrame frame(videoBuffer, - resolution, - QVideoFrame::Format_Jpeg); - QMetaObject::invokeMethod(capture, "imageAvailable", - Qt::QueuedConnection, - Q_ARG(int, capture->m_requestId), - Q_ARG(QVideoFrame, frame)); - } - - - // Theoretically we could drop the buffer here when don't want to capture to file but that - // prevents camerabin from recognizing that capture has been completed and returning - // to its idle state. - return true; -} - - -bool CameraBinImageCapture::processBusMessage(const QGstreamerMessage &message) -{ - //Install metadata event and buffer probes - - //The image capture pipiline is built dynamically, - //it's necessary to wait until jpeg encoder is added to pipeline - - GstMessage *gm = message.rawMessage(); - if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED) { - GstState oldState; - GstState newState; - GstState pending; - gst_message_parse_state_changed(gm, &oldState, &newState, &pending); - - if (newState == GST_STATE_READY) { - GstElement *element = GST_ELEMENT(GST_MESSAGE_SRC(gm)); - if (!element) - return false; - - gchar *name = gst_element_get_name(element); - QString elementName = QString::fromLatin1(name); - g_free(name); - if (elementName.contains("jpegenc") && element != m_jpegEncoderElement) { - m_jpegEncoderElement = element; - GstPad *sinkpad = gst_element_get_static_pad(element, "sink"); - - //metadata event probe is installed before jpeg encoder - //to emit metadata available signal as soon as possible. -#ifdef DEBUG_CAPTURE - qDebug() << "install metadata probe"; -#endif - gst_pad_add_probe( - sinkpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, encoderEventProbe, this, NULL); -#ifdef DEBUG_CAPTURE - qDebug() << "install uncompressed buffer probe"; -#endif - m_encoderProbe.addProbeToPad(sinkpad, true); - - gst_object_unref(sinkpad); - } else if ((elementName.contains("jifmux") || elementName.startsWith("metadatamux")) - && element != m_metadataMuxerElement) { - //Jpeg encoded buffer probe is added after jifmux/metadatamux - //element to ensure the resulting jpeg buffer contains capture metadata - m_metadataMuxerElement = element; - - GstPad *srcpad = gst_element_get_static_pad(element, "src"); -#ifdef DEBUG_CAPTURE - qDebug() << "install jpeg buffer probe"; -#endif - m_muxerProbe.addProbeToPad(srcpad); - - gst_object_unref(srcpad); - } - } - } else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) { - if (GST_MESSAGE_SRC(gm) == (GstObject *)m_session->cameraBin()) { - const GstStructure *structure = gst_message_get_structure(gm); - - if (gst_structure_has_name (structure, "image-done")) { - const gchar *fileName = gst_structure_get_string (structure, "filename"); -#ifdef DEBUG_CAPTURE - qDebug() << "Image saved" << fileName; -#endif - - if (m_destination & QCameraImageCapture::CaptureToFile) { - emit imageSaved(m_requestId, QString::fromUtf8(fileName)); - } else { -#ifdef DEBUG_CAPTURE - qDebug() << Q_FUNC_INFO << "Dropped saving file" << fileName; -#endif - QFileInfo info(QString::fromUtf8(fileName)); - if (info.exists() && info.isFile()) - QFile(info.absoluteFilePath()).remove(); - } - } - } - } - - return false; -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinimagecapture.h b/src/plugins/gstreamer/camerabin/camerabinimagecapture.h deleted file mode 100644 index b18495a14..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinimagecapture.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef CAMERABINIMAGECAPTURECONTROL_H -#define CAMERABINIMAGECAPTURECONTROL_H - -#include <qcameraimagecapturecontrol.h> -#include "camerabinsession.h" - -#include <qvideosurfaceformat.h> - -#include <private/qgstreamerbufferprobe_p.h> - -#include <gst/video/video.h> - -QT_BEGIN_NAMESPACE - -class CameraBinImageCapture : public QCameraImageCaptureControl, public QGstreamerBusMessageFilter -{ - Q_OBJECT - Q_INTERFACES(QGstreamerBusMessageFilter) -public: - CameraBinImageCapture(CameraBinSession *session); - virtual ~CameraBinImageCapture(); - - QCameraImageCapture::DriveMode driveMode() const override { return QCameraImageCapture::SingleImageCapture; } - void setDriveMode(QCameraImageCapture::DriveMode) override {} - - bool isReadyForCapture() const override; - int capture(const QString &fileName) override; - void cancelCapture() override; - - QCameraImageCapture::CaptureDestinations captureDestination() const override; - void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) override; - - bool processBusMessage(const QGstreamerMessage &message) override; - -private slots: - void updateState(); - -private: - static GstPadProbeReturn encoderEventProbe(GstPad *, GstPadProbeInfo *info, gpointer user_data); - - class EncoderProbe : public QGstreamerBufferProbe - { - public: - EncoderProbe(CameraBinImageCapture *capture) : capture(capture) {} - void probeCaps(GstCaps *caps) override; - bool probeBuffer(GstBuffer *buffer) override; - - private: - CameraBinImageCapture * const capture; - } m_encoderProbe; - - class MuxerProbe : public QGstreamerBufferProbe - { - public: - MuxerProbe(CameraBinImageCapture *capture) : capture(capture) {} - void probeCaps(GstCaps *caps) override; - bool probeBuffer(GstBuffer *buffer) override; - - private: - CameraBinImageCapture * const capture; - - } m_muxerProbe; - - QVideoSurfaceFormat m_bufferFormat; - QSize m_jpegResolution; - CameraBinSession *m_session; - GstElement *m_jpegEncoderElement; - GstElement *m_metadataMuxerElement; - GstVideoInfo m_videoInfo; - int m_requestId; - bool m_ready; - QCameraImageCapture::CaptureDestinations m_destination; -}; - -QT_END_NAMESPACE - -#endif // CAMERABINCAPTURECORNTROL_H diff --git a/src/plugins/gstreamer/camerabin/camerabinimageencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinimageencoder.cpp deleted file mode 100644 index 8c4eaec70..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinimageencoder.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "camerabinimageencoder.h" -#include "camerabinsession.h" - -#include <QtCore/qdebug.h> - -QT_BEGIN_NAMESPACE - -CameraBinImageEncoder::CameraBinImageEncoder(CameraBinSession *session) - :QImageEncoderControl(session), m_session(session) -{ -} - -CameraBinImageEncoder::~CameraBinImageEncoder() -{ -} - -QList<QSize> CameraBinImageEncoder::supportedResolutions(const QImageEncoderSettings &, bool *continuous) const -{ - if (continuous) - *continuous = false; - - return m_session->supportedResolutions(qMakePair<int,int>(0,0), continuous, QCamera::CaptureStillImage); -} - -QStringList CameraBinImageEncoder::supportedImageCodecs() const -{ - return QStringList() << "jpeg"; -} - -QString CameraBinImageEncoder::imageCodecDescription(const QString &codecName) const -{ - if (codecName == "jpeg") - return tr("JPEG image"); - - return QString(); -} - -QImageEncoderSettings CameraBinImageEncoder::imageSettings() const -{ - return m_settings; -} - -void CameraBinImageEncoder::setImageSettings(const QImageEncoderSettings &settings) -{ - m_settings = settings; - emit settingsChanged(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinimageencoder.h b/src/plugins/gstreamer/camerabin/camerabinimageencoder.h deleted file mode 100644 index 96f7ae7aa..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinimageencoder.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CAMERABINIMAGEENCODE_H -#define CAMERABINIMAGEENCODE_H - -#include <qimageencodercontrol.h> - -#include <QtCore/qstringlist.h> -#include <QtCore/qmap.h> - -#include <gst/gst.h> -QT_BEGIN_NAMESPACE - -class CameraBinSession; - -class CameraBinImageEncoder : public QImageEncoderControl -{ - Q_OBJECT -public: - CameraBinImageEncoder(CameraBinSession *session); - virtual ~CameraBinImageEncoder(); - - QList<QSize> supportedResolutions(const QImageEncoderSettings &settings = QImageEncoderSettings(), - bool *continuous = 0) const override; - - QStringList supportedImageCodecs() const override; - QString imageCodecDescription(const QString &formatName) const override; - - QImageEncoderSettings imageSettings() const override; - void setImageSettings(const QImageEncoderSettings &settings) override; - -Q_SIGNALS: - void settingsChanged(); - -private: - QImageEncoderSettings m_settings; - - CameraBinSession *m_session; - - // Added - QStringList m_codecs; - QMap<QString,QByteArray> m_elementNames; - QMap<QString,QString> m_codecDescriptions; - QMap<QString,QStringList> m_codecOptions; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp b/src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp deleted file mode 100644 index 3629a1336..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp +++ /dev/null @@ -1,409 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include "camerabinimageprocessing.h" -#include "camerabinsession.h" - -#if QT_CONFIG(linux_v4l) -#include "camerabinv4limageprocessing.h" -#endif - -# include <gst/video/colorbalance.h> - -QT_BEGIN_NAMESPACE - -CameraBinImageProcessing::CameraBinImageProcessing(CameraBinSession *session) - : QCameraImageProcessingControl(session) - , m_session(session) - , m_whiteBalanceMode(QCameraImageProcessing::WhiteBalanceAuto) -#if QT_CONFIG(linux_v4l) - , m_v4lImageControl(nullptr) -#endif -{ -#if QT_CONFIG(gstreamer_photography) - if (m_session->photography()) { - m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_AUTO] = QCameraImageProcessing::WhiteBalanceAuto; - m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_DAYLIGHT] = QCameraImageProcessing::WhiteBalanceSunlight; - m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_CLOUDY] = QCameraImageProcessing::WhiteBalanceCloudy; - m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_SUNSET] = QCameraImageProcessing::WhiteBalanceSunset; - m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_TUNGSTEN] = QCameraImageProcessing::WhiteBalanceTungsten; - m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_FLUORESCENT] = QCameraImageProcessing::WhiteBalanceFluorescent; - unlockWhiteBalance(); - } - - m_filterMap.insert(QCameraImageProcessing::ColorFilterNone, GST_PHOTOGRAPHY_COLOR_TONE_MODE_NORMAL); - if (m_session->photography()) { - m_filterMap.insert(QCameraImageProcessing::ColorFilterSepia, GST_PHOTOGRAPHY_COLOR_TONE_MODE_SEPIA); - m_filterMap.insert(QCameraImageProcessing::ColorFilterGrayscale, GST_PHOTOGRAPHY_COLOR_TONE_MODE_GRAYSCALE); - m_filterMap.insert(QCameraImageProcessing::ColorFilterNegative, GST_PHOTOGRAPHY_COLOR_TONE_MODE_NEGATIVE); - m_filterMap.insert(QCameraImageProcessing::ColorFilterSolarize, GST_PHOTOGRAPHY_COLOR_TONE_MODE_SOLARIZE); - m_filterMap.insert(QCameraImageProcessing::ColorFilterPosterize, GST_PHOTOGRAPHY_COLOR_TONE_MODE_POSTERIZE); - m_filterMap.insert(QCameraImageProcessing::ColorFilterWhiteboard, GST_PHOTOGRAPHY_COLOR_TONE_MODE_WHITEBOARD); - m_filterMap.insert(QCameraImageProcessing::ColorFilterBlackboard, GST_PHOTOGRAPHY_COLOR_TONE_MODE_BLACKBOARD); - m_filterMap.insert(QCameraImageProcessing::ColorFilterAqua, GST_PHOTOGRAPHY_COLOR_TONE_MODE_AQUA); - } -#endif - -#if QT_CONFIG(linux_v4l) - m_v4lImageControl = new CameraBinV4LImageProcessing(m_session); - connect(m_session, &CameraBinSession::statusChanged, - m_v4lImageControl, &CameraBinV4LImageProcessing::updateParametersInfo); -#endif - - updateColorBalanceValues(); -} - -CameraBinImageProcessing::~CameraBinImageProcessing() -{ -} - -void CameraBinImageProcessing::updateColorBalanceValues() -{ - if (!GST_IS_COLOR_BALANCE(m_session->cameraBin())) { - // Camerabin doesn't implement gstcolorbalance interface - return; - } - - GstColorBalance *balance = GST_COLOR_BALANCE(m_session->cameraBin()); - const GList *controls = gst_color_balance_list_channels(balance); - - const GList *item; - GstColorBalanceChannel *channel; - gint cur_value; - qreal scaledValue = 0; - - for (item = controls; item; item = g_list_next (item)) { - channel = (GstColorBalanceChannel *)item->data; - cur_value = gst_color_balance_get_value (balance, channel); - - //map the [min_value..max_value] range to [-1.0 .. 1.0] - if (channel->min_value != channel->max_value) { - scaledValue = qreal(cur_value - channel->min_value) / - (channel->max_value - channel->min_value) * 2 - 1; - } - - if (!g_ascii_strcasecmp (channel->label, "brightness")) { - m_values[QCameraImageProcessingControl::BrightnessAdjustment] = scaledValue; - } else if (!g_ascii_strcasecmp (channel->label, "contrast")) { - m_values[QCameraImageProcessingControl::ContrastAdjustment] = scaledValue; - } else if (!g_ascii_strcasecmp (channel->label, "saturation")) { - m_values[QCameraImageProcessingControl::SaturationAdjustment] = scaledValue; - } - } -} - -bool CameraBinImageProcessing::setColorBalanceValue(const QString& channel, qreal value) -{ - - if (!GST_IS_COLOR_BALANCE(m_session->cameraBin())) { - // Camerabin doesn't implement gstcolorbalance interface - return false; - } - - GstColorBalance *balance = GST_COLOR_BALANCE(m_session->cameraBin()); - const GList *controls = gst_color_balance_list_channels(balance); - - const GList *item; - GstColorBalanceChannel *colorBalanceChannel; - - for (item = controls; item; item = g_list_next (item)) { - colorBalanceChannel = (GstColorBalanceChannel *)item->data; - - if (!g_ascii_strcasecmp (colorBalanceChannel->label, channel.toLatin1())) { - //map the [-1.0 .. 1.0] range to [min_value..max_value] - gint scaledValue = colorBalanceChannel->min_value + qRound( - (value+1.0)/2.0 * (colorBalanceChannel->max_value - colorBalanceChannel->min_value)); - - gst_color_balance_set_value (balance, colorBalanceChannel, scaledValue); - return true; - } - } - - return false; -} - -QCameraImageProcessing::WhiteBalanceMode CameraBinImageProcessing::whiteBalanceMode() const -{ - return m_whiteBalanceMode; -} - -bool CameraBinImageProcessing::setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode) -{ -#if QT_CONFIG(gstreamer_photography) - if (isWhiteBalanceModeSupported(mode)) { - m_whiteBalanceMode = mode; - GstPhotographyWhiteBalanceMode currentMode; - if (gst_photography_get_white_balance_mode(m_session->photography(), ¤tMode) - && currentMode != GST_PHOTOGRAPHY_WB_MODE_MANUAL) - { - unlockWhiteBalance(); - return true; - } - } -#else - Q_UNUSED(mode); -#endif - return false; -} - -bool CameraBinImageProcessing::isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const -{ -#if QT_CONFIG(gstreamer_photography) - return m_mappedWbValues.values().contains(mode); -#else - Q_UNUSED(mode); - return false; -#endif -} - -bool CameraBinImageProcessing::isParameterSupported(QCameraImageProcessingControl::ProcessingParameter parameter) const -{ -#if QT_CONFIG(gstreamer_photography) - if (parameter == QCameraImageProcessingControl::WhiteBalancePreset - || parameter == QCameraImageProcessingControl::ColorFilter) { - if (m_session->photography()) - return true; - } -#endif - - if (parameter == QCameraImageProcessingControl::Contrast - || parameter == QCameraImageProcessingControl::Brightness - || parameter == QCameraImageProcessingControl::Saturation) { - if (GST_IS_COLOR_BALANCE(m_session->cameraBin())) - return true; - } - -#if QT_CONFIG(linux_v4l) - if (m_v4lImageControl->isParameterSupported(parameter)) - return true; -#endif - - return false; -} - -bool CameraBinImageProcessing::isParameterValueSupported(QCameraImageProcessingControl::ProcessingParameter parameter, const QVariant &value) const -{ - switch (parameter) { - case ContrastAdjustment: - case BrightnessAdjustment: - case SaturationAdjustment: { - const bool isGstColorBalanceValueSupported = GST_IS_COLOR_BALANCE(m_session->cameraBin()) - && qAbs(value.toReal()) <= 1.0; -#if QT_CONFIG(linux_v4l) - if (!isGstColorBalanceValueSupported) - return m_v4lImageControl->isParameterValueSupported(parameter, value); -#endif - return isGstColorBalanceValueSupported; - } - case SharpeningAdjustment: { -#if QT_CONFIG(linux_v4l) - return m_v4lImageControl->isParameterValueSupported(parameter, value); -#else - return false; -#endif - } - case WhiteBalancePreset: { - const QCameraImageProcessing::WhiteBalanceMode mode = - value.value<QCameraImageProcessing::WhiteBalanceMode>(); - const bool isPhotographyWhiteBalanceSupported = isWhiteBalanceModeSupported(mode); -#if QT_CONFIG(linux_v4l) - if (!isPhotographyWhiteBalanceSupported) - return m_v4lImageControl->isParameterValueSupported(parameter, value); -#endif - return isPhotographyWhiteBalanceSupported; - } - case ColorTemperature: { -#if QT_CONFIG(linux_v4l) - return m_v4lImageControl->isParameterValueSupported(parameter, value); -#else - return false; -#endif - } - case ColorFilter: { - const QCameraImageProcessing::ColorFilter filter = value.value<QCameraImageProcessing::ColorFilter>(); -#if QT_CONFIG(gstreamer_photography) - return m_filterMap.contains(filter); -#else - return filter == QCameraImageProcessing::ColorFilterNone; -#endif - } - default: - break; - } - - return false; -} - -QVariant CameraBinImageProcessing::parameter( - QCameraImageProcessingControl::ProcessingParameter parameter) const -{ - switch (parameter) { - case QCameraImageProcessingControl::WhiteBalancePreset: { - const QCameraImageProcessing::WhiteBalanceMode mode = whiteBalanceMode(); -#if QT_CONFIG(linux_v4l) - if (mode == QCameraImageProcessing::WhiteBalanceAuto - || mode == QCameraImageProcessing::WhiteBalanceManual) { - return m_v4lImageControl->parameter(parameter); - } -#endif - return QVariant::fromValue<QCameraImageProcessing::WhiteBalanceMode>(mode); - } - case QCameraImageProcessingControl::ColorTemperature: { -#if QT_CONFIG(linux_v4l) - return m_v4lImageControl->parameter(parameter); -#else - return QVariant(); -#endif - } - case QCameraImageProcessingControl::ColorFilter: -#if QT_CONFIG(gstreamer_photography) - if (GstPhotography *photography = m_session->photography()) { - GstPhotographyColorToneMode mode = GST_PHOTOGRAPHY_COLOR_TONE_MODE_NORMAL; - gst_photography_get_color_tone_mode(photography, &mode); - return QVariant::fromValue(m_filterMap.key(mode, QCameraImageProcessing::ColorFilterNone)); - } -#endif - return QVariant::fromValue(QCameraImageProcessing::ColorFilterNone); - default: { - const bool isGstParameterSupported = m_values.contains(parameter); -#if QT_CONFIG(linux_v4l) - if (!isGstParameterSupported) { - if (parameter == QCameraImageProcessingControl::BrightnessAdjustment - || parameter == QCameraImageProcessingControl::ContrastAdjustment - || parameter == QCameraImageProcessingControl::SaturationAdjustment - || parameter == QCameraImageProcessingControl::SharpeningAdjustment) { - return m_v4lImageControl->parameter(parameter); - } - } -#endif - return isGstParameterSupported - ? QVariant(m_values.value(parameter)) - : QVariant(); - } - } -} - -void CameraBinImageProcessing::setParameter(QCameraImageProcessingControl::ProcessingParameter parameter, - const QVariant &value) -{ - switch (parameter) { - case ContrastAdjustment: { - if (!setColorBalanceValue("contrast", value.toReal())) { -#if QT_CONFIG(linux_v4l) - m_v4lImageControl->setParameter(parameter, value); -#endif - } - } - break; - case BrightnessAdjustment: { - if (!setColorBalanceValue("brightness", value.toReal())) { -#if QT_CONFIG(linux_v4l) - m_v4lImageControl->setParameter(parameter, value); -#endif - } - } - break; - case SaturationAdjustment: { - if (!setColorBalanceValue("saturation", value.toReal())) { -#if QT_CONFIG(linux_v4l) - m_v4lImageControl->setParameter(parameter, value); -#endif - } - } - break; - case SharpeningAdjustment: { -#if QT_CONFIG(linux_v4l) - m_v4lImageControl->setParameter(parameter, value); -#endif - } - break; - case WhiteBalancePreset: { - if (!setWhiteBalanceMode(value.value<QCameraImageProcessing::WhiteBalanceMode>())) { -#if QT_CONFIG(linux_v4l) - const QCameraImageProcessing::WhiteBalanceMode mode = - value.value<QCameraImageProcessing::WhiteBalanceMode>(); - if (mode == QCameraImageProcessing::WhiteBalanceAuto - || mode == QCameraImageProcessing::WhiteBalanceManual) { - m_v4lImageControl->setParameter(parameter, value); - return; - } -#endif - } - } - break; - case QCameraImageProcessingControl::ColorTemperature: { -#if QT_CONFIG(linux_v4l) - m_v4lImageControl->setParameter(parameter, value); -#endif - break; - } - case QCameraImageProcessingControl::ColorFilter: -#if QT_CONFIG(gstreamer_photography) - if (GstPhotography *photography = m_session->photography()) { - gst_photography_set_color_tone_mode(photography, m_filterMap.value( - value.value<QCameraImageProcessing::ColorFilter>(), - GST_PHOTOGRAPHY_COLOR_TONE_MODE_NORMAL)); - } -#endif - break; - default: - break; - } - - updateColorBalanceValues(); -} - -#if QT_CONFIG(gstreamer_photography) -void CameraBinImageProcessing::lockWhiteBalance() -{ - if (GstPhotography *photography = m_session->photography()) - gst_photography_set_white_balance_mode(photography, GST_PHOTOGRAPHY_WB_MODE_MANUAL); -} - -void CameraBinImageProcessing::unlockWhiteBalance() -{ - if (GstPhotography *photography = m_session->photography()) { - gst_photography_set_white_balance_mode( - photography, m_mappedWbValues.key(m_whiteBalanceMode)); - } -} -#endif - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinimageprocessing.h b/src/plugins/gstreamer/camerabin/camerabinimageprocessing.h deleted file mode 100644 index 51e6f7c82..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinimageprocessing.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CAMERABINIMAGEPROCESSINGCONTROL_H -#define CAMERABINIMAGEPROCESSINGCONTROL_H - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include <qcamera.h> -#include <qcameraimageprocessingcontrol.h> - -#include <gst/gst.h> -#include <glib.h> - -#if QT_CONFIG(gstreamer_photography) -# include <gst/interfaces/photography.h> -#endif - -QT_BEGIN_NAMESPACE - -#if QT_CONFIG(linux_v4l) -class CameraBinV4LImageProcessing; -#endif - -class CameraBinSession; - -class CameraBinImageProcessing : public QCameraImageProcessingControl -{ - Q_OBJECT - -public: - CameraBinImageProcessing(CameraBinSession *session); - virtual ~CameraBinImageProcessing(); - - QCameraImageProcessing::WhiteBalanceMode whiteBalanceMode() const; - bool setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode); - bool isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const; - - bool isParameterSupported(ProcessingParameter) const override; - bool isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const override; - QVariant parameter(ProcessingParameter parameter) const override; - void setParameter(ProcessingParameter parameter, const QVariant &value) override; - -#if QT_CONFIG(gstreamer_photography) - void lockWhiteBalance(); - void unlockWhiteBalance(); -#endif - -private: - bool setColorBalanceValue(const QString& channel, qreal value); - void updateColorBalanceValues(); - -private: - CameraBinSession *m_session; - QMap<QCameraImageProcessingControl::ProcessingParameter, int> m_values; -#if QT_CONFIG(gstreamer_photography) - QMap<GstPhotographyWhiteBalanceMode, QCameraImageProcessing::WhiteBalanceMode> m_mappedWbValues; - QMap<QCameraImageProcessing::ColorFilter, GstPhotographyColorToneMode> m_filterMap; -#endif - QCameraImageProcessing::WhiteBalanceMode m_whiteBalanceMode; - -#if QT_CONFIG(linux_v4l) - CameraBinV4LImageProcessing *m_v4lImageControl; -#endif -}; - -QT_END_NAMESPACE - -#endif // CAMERABINIMAGEPROCESSINGCONTROL_H diff --git a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp b/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp deleted file mode 100644 index e2b12aab1..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "camerabinmetadata.h" - -#include <QtMultimedia/qmediametadata.h> - -#include <gst/gst.h> -#include <gst/gstversion.h> -#include <private/qgstutils_p.h> - -#include <QDebug> - -QT_BEGIN_NAMESPACE - -namespace { - struct QGStreamerMetaDataKey - { - QString qtName; - const char *gstName; - QMetaType::Type type; - - QGStreamerMetaDataKey(const QString &qtn, const char *gstn, QMetaType::Type t) - : qtName(qtn) - , gstName(gstn) - , type(t) - { } - }; -} - -typedef QList<QGStreamerMetaDataKey> QGStreamerMetaDataKeys; -Q_GLOBAL_STATIC(QGStreamerMetaDataKeys, metadataKeys) - -static const QGStreamerMetaDataKeys *qt_gstreamerMetaDataKeys() -{ - if (metadataKeys->isEmpty()) { - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Title, GST_TAG_TITLE, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::SubTitle, 0, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Author, 0, QMetaType::QString)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Comment, GST_TAG_COMMENT, QMetaType::QString)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Date, GST_TAG_DATE_TIME, QMetaType::QDateTime)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Description, GST_TAG_DESCRIPTION, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Category, 0, QMetaType::QString)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Genre, GST_TAG_GENRE, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Year, 0, QMetaType::Int)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::UserRating, , QMetaType::Int)); - - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE, QMetaType::QString)); - - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Publisher, GST_TAG_ORGANIZATION, QMetaType::QString)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Copyright, GST_TAG_COPYRIGHT, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::ParentalRating, 0, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::RatingOrganisation, 0, QMetaType::QString)); - - // Media - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Size, 0, QMetaType::Int)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::MediaType, 0, QMetaType::QString)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Duration, GST_TAG_DURATION, QMetaType::Int)); - - // Audio - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::AudioBitRate, GST_TAG_BITRATE, QMetaType::Int)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::ChannelCount, 0, QMetaType::Int)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::SampleRate, 0, QMetaType::Int)); - - // Music - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::AlbumTitle, GST_TAG_ALBUM, QMetaType::QString)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::AlbumArtist, GST_TAG_ARTIST, QMetaType::QString)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER, QMetaType::QString)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Composer, GST_TAG_COMPOSER, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Conductor, 0, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Lyrics, 0, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Mood, 0, QMetaType::QString)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER, QMetaType::Int)); - - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::CoverArtUrlSmall, 0, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::CoverArtUrlLarge, 0, QMetaType::QString)); - - // Image/Video - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Resolution, 0, QMetaType::QSize)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::PixelAspectRatio, 0, QMetaType::QSize)); - - // Video - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::VideoFrameRate, 0, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::VideoBitRate, 0, QMetaType::Double)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC, QMetaType::QString)); - - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::PosterUrl, 0, QMetaType::QString)); - - // Movie - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::ChapterNumber, 0, QMetaType::Int)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Director, 0, QMetaType::QString)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Writer, 0, QMetaType::QString)); - - // Photos - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::CameraManufacturer, GST_TAG_DEVICE_MANUFACTURER, QMetaType::QString)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::CameraModel, GST_TAG_DEVICE_MODEL, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Event, 0, QMetaType::QString)); - //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Subject, 0, QMetaType::QString)); - - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Orientation, GST_TAG_IMAGE_ORIENTATION, QMetaType::QString)); - - // GPS - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::GPSLatitude, GST_TAG_GEO_LOCATION_LATITUDE, QMetaType::Double)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::GPSLongitude, GST_TAG_GEO_LOCATION_LONGITUDE, QMetaType::Double)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::GPSAltitude, GST_TAG_GEO_LOCATION_ELEVATION, QMetaType::Double)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::GPSTrack, GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, QMetaType::Double)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::GPSSpeed, GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, QMetaType::Double)); - metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::GPSImgDirection, GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, QMetaType::Double)); - } - - return metadataKeys; -} - -CameraBinMetaData::CameraBinMetaData(QObject *parent) - :QMetaDataWriterControl(parent) -{ -} - -QVariant CameraBinMetaData::metaData(const QString &key) const -{ - if (key == QMediaMetaData::Orientation) - return QGstUtils::fromGStreamerOrientation(m_values.value(QByteArray(GST_TAG_IMAGE_ORIENTATION))); - - if (key == QMediaMetaData::GPSSpeed) { - const double metersPerSec = m_values.value(QByteArray(GST_TAG_GEO_LOCATION_MOVEMENT_SPEED)).toDouble(); - return (metersPerSec * 3600) / 1000; - } - - const auto keys = *qt_gstreamerMetaDataKeys(); - for (const QGStreamerMetaDataKey &metadataKey : keys) { - if (metadataKey.qtName == key) - return m_values.value(QByteArray::fromRawData(metadataKey.gstName, qstrlen(metadataKey.gstName))); - } - return QVariant(); -} - -void CameraBinMetaData::setMetaData(const QString &key, const QVariant &value) -{ - QVariant correctedValue = value; - if (value.isValid()) { - if (key == QMediaMetaData::Orientation) { - correctedValue = QGstUtils::toGStreamerOrientation(value); - } else if (key == QMediaMetaData::GPSSpeed) { - // kilometers per hour to meters per second. - correctedValue = (value.toDouble() * 1000) / 3600; - } - } - - const auto keys = *qt_gstreamerMetaDataKeys(); - for (const QGStreamerMetaDataKey &metadataKey : keys) { - if (metadataKey.qtName == key) { - const char *name = metadataKey.gstName; - - if (correctedValue.isValid()) { - correctedValue.convert(QMetaType(metadataKey.type)); - m_values.insert(QByteArray::fromRawData(name, qstrlen(name)), correctedValue); - } else { - m_values.remove(QByteArray::fromRawData(name, qstrlen(name))); - } - - emit QMetaDataWriterControl::metaDataChanged(); - emit metaDataChanged(m_values); - - return; - } - } -} - -QStringList CameraBinMetaData::availableMetaData() const -{ - static QMap<QByteArray, QString> keysMap; - if (keysMap.isEmpty()) { - const auto keys = *qt_gstreamerMetaDataKeys(); - for (const QGStreamerMetaDataKey &metadataKey : keys) - keysMap[QByteArray(metadataKey.gstName)] = metadataKey.qtName; - } - - QStringList res; - for (auto it = m_values.keyBegin(), end = m_values.keyEnd(); it != end; ++it) { - QString tag = keysMap.value(*it); - if (!tag.isEmpty()) - res.append(tag); - } - - return res; -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinmetadata.h b/src/plugins/gstreamer/camerabin/camerabinmetadata.h deleted file mode 100644 index acc184af3..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinmetadata.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CAMERABINCAPTUREMETADATACONTROL_H -#define CAMERABINCAPTUREMETADATACONTROL_H - -#include <qmetadatawritercontrol.h> -#include <qmap.h> -#include <qvariant.h> - -QT_BEGIN_NAMESPACE - -class CameraBinMetaData : public QMetaDataWriterControl -{ - Q_OBJECT -public: - CameraBinMetaData(QObject *parent); - virtual ~CameraBinMetaData() {} - - - bool isMetaDataAvailable() const override { return true; } - bool isWritable() const override { return true; } - - QVariant metaData(const QString &key) const override; - void setMetaData(const QString &key, const QVariant &value) override; - QStringList availableMetaData() const override; - -Q_SIGNALS: - void metaDataChanged(const QMap<QByteArray, QVariant>&); - -private: - QMap<QByteArray, QVariant> m_values; -}; - -QT_END_NAMESPACE - -#endif // CAMERABINCAPTUREMETADATACONTROL_H diff --git a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp b/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp deleted file mode 100644 index a83971226..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "camerabinrecorder.h" -#include "camerabincontrol.h" -#include "camerabinaudioencoder.h" -#include "camerabinvideoencoder.h" -#include "camerabincontainer.h" -#include <QtCore/QDebug> - - -QT_BEGIN_NAMESPACE - -CameraBinRecorder::CameraBinRecorder(CameraBinSession *session) - :QMediaRecorderControl(session), - m_session(session), - m_state(QMediaRecorder::StoppedState), - m_status(QMediaRecorder::UnloadedStatus) -{ - connect(m_session, SIGNAL(statusChanged(QCamera::Status)), SLOT(updateStatus())); - connect(m_session, SIGNAL(pendingStateChanged(QCamera::State)), SLOT(updateStatus())); - connect(m_session, SIGNAL(busyChanged(bool)), SLOT(updateStatus())); - - connect(m_session, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64))); - connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool))); -} - -CameraBinRecorder::~CameraBinRecorder() -{ -} - -QUrl CameraBinRecorder::outputLocation() const -{ - return m_session->outputLocation(); -} - -bool CameraBinRecorder::setOutputLocation(const QUrl &sink) -{ - m_session->setOutputLocation(sink); - return true; -} - -QMediaRecorder::State CameraBinRecorder::state() const -{ - return m_state; -} - -QMediaRecorder::Status CameraBinRecorder::status() const -{ - return m_status; -} - -void CameraBinRecorder::updateStatus() -{ - QCamera::Status sessionStatus = m_session->status(); - - QMediaRecorder::State oldState = m_state; - QMediaRecorder::Status oldStatus = m_status; - - if (sessionStatus == QCamera::ActiveStatus && - m_session->captureMode().testFlag(QCamera::CaptureVideo)) { - - if (m_state == QMediaRecorder::RecordingState) { - m_status = QMediaRecorder::RecordingStatus; - } else { - m_status = m_session->isBusy() ? - QMediaRecorder::FinalizingStatus : - QMediaRecorder::LoadedStatus; - } - } else { - if (m_state == QMediaRecorder::RecordingState) { - m_state = QMediaRecorder::StoppedState; - m_session->stopVideoRecording(); - } - m_status = m_session->pendingState() == QCamera::ActiveState - && m_session->captureMode().testFlag(QCamera::CaptureVideo) - ? QMediaRecorder::LoadingStatus - : QMediaRecorder::UnloadedStatus; - } - - if (m_state != oldState) - emit stateChanged(m_state); - - if (m_status != oldStatus) - emit statusChanged(m_status); -} - -qint64 CameraBinRecorder::duration() const -{ - return m_session->duration(); -} - - -void CameraBinRecorder::applySettings() -{ -#if QT_CONFIG(gstreamer_encodingprofiles) - CameraBinContainer *containerControl = m_session->mediaContainerControl(); - CameraBinAudioEncoder *audioEncoderControl = m_session->audioEncodeControl(); - CameraBinVideoEncoder *videoEncoderControl = m_session->videoEncodeControl(); - - containerControl->resetActualContainerFormat(); - audioEncoderControl->resetActualSettings(); - videoEncoderControl->resetActualSettings(); - - //encodebin doesn't like the encoding profile with ANY caps, - //if container and codecs are not specified, - //try to find a commonly used supported combination - if (containerControl->containerFormat().isEmpty() && - audioEncoderControl->audioSettings().codec().isEmpty() && - videoEncoderControl->videoSettings().codec().isEmpty()) { - - QList<QStringList> candidates; - - // By order of preference - - // .mp4 (h264, AAC) - candidates.append(QStringList() << "video/quicktime, variant=(string)iso" << "video/x-h264" << "audio/mpeg, mpegversion=(int)4"); - - // .mp4 (h264, AC3) - candidates.append(QStringList() << "video/quicktime, variant=(string)iso" << "video/x-h264" << "audio/x-ac3"); - - // .mp4 (h264, MP3) - candidates.append(QStringList() << "video/quicktime, variant=(string)iso" << "video/x-h264" << "audio/mpeg, mpegversion=(int)1, layer=(int)3"); - - // .mkv (h264, AAC) - candidates.append(QStringList() << "video/x-matroska" << "video/x-h264" << "audio/mpeg, mpegversion=(int)4"); - - // .mkv (h264, AC3) - candidates.append(QStringList() << "video/x-matroska" << "video/x-h264" << "audio/x-ac3"); - - // .mkv (h264, MP3) - candidates.append(QStringList() << "video/x-matroska" << "video/x-h264" << "audio/mpeg, mpegversion=(int)1, layer=(int)3"); - - // .mov (h264, AAC) - candidates.append(QStringList() << "video/quicktime" << "video/x-h264" << "audio/mpeg, mpegversion=(int)4"); - - // .mov (h264, MP3) - candidates.append(QStringList() << "video/quicktime" << "video/x-h264" << "audio/mpeg, mpegversion=(int)1, layer=(int)3"); - - // .webm (VP8, Vorbis) - candidates.append(QStringList() << "video/webm" << "video/x-vp8" << "audio/x-vorbis"); - - // .ogg (Theora, Vorbis) - candidates.append(QStringList() << "application/ogg" << "video/x-theora" << "audio/x-vorbis"); - - // .avi (DivX, MP3) - candidates.append(QStringList() << "video/x-msvideo" << "video/x-divx" << "audio/mpeg, mpegversion=(int)1, layer=(int)3"); - - for (const QStringList &candidate : qAsConst(candidates)) { - if (containerControl->supportedContainers().contains(candidate[0]) && - videoEncoderControl->supportedVideoCodecs().contains(candidate[1]) && - audioEncoderControl->supportedAudioCodecs().contains(candidate[2])) { - containerControl->setActualContainerFormat(candidate[0]); - - QVideoEncoderSettings videoSettings = videoEncoderControl->videoSettings(); - videoSettings.setCodec(candidate[1]); - videoEncoderControl->setActualVideoSettings(videoSettings); - - QAudioEncoderSettings audioSettings = audioEncoderControl->audioSettings(); - audioSettings.setCodec(candidate[2]); - audioEncoderControl->setActualAudioSettings(audioSettings); - - break; - } - } - } -#endif -} - -#if QT_CONFIG(gstreamer_encodingprofiles) - -GstEncodingContainerProfile *CameraBinRecorder::videoProfile() -{ - GstEncodingContainerProfile *containerProfile = m_session->mediaContainerControl()->createProfile(); - - if (containerProfile) { - GstEncodingProfile *audioProfile = m_session->audioEncodeControl()->createProfile(); - GstEncodingProfile *videoProfile = m_session->videoEncodeControl()->createProfile(); - - if (audioProfile) { - if (!gst_encoding_container_profile_add_profile(containerProfile, audioProfile)) - gst_encoding_profile_unref(audioProfile); - } - if (videoProfile) { - if (!gst_encoding_container_profile_add_profile(containerProfile, videoProfile)) - gst_encoding_profile_unref(videoProfile); - } - } - - return containerProfile; -} - -#endif - -void CameraBinRecorder::setState(QMediaRecorder::State state) -{ - if (m_state == state) - return; - - QMediaRecorder::State oldState = m_state; - QMediaRecorder::Status oldStatus = m_status; - - switch (state) { - case QMediaRecorder::StoppedState: - m_state = state; - m_status = QMediaRecorder::FinalizingStatus; - m_session->stopVideoRecording(); - break; - case QMediaRecorder::PausedState: - emit error(QMediaRecorder::ResourceError, tr("QMediaRecorder::pause() is not supported by camerabin2.")); - break; - case QMediaRecorder::RecordingState: - - if (m_session->status() != QCamera::ActiveStatus) { - emit error(QMediaRecorder::ResourceError, tr("Service has not been started")); - } else { - m_session->recordVideo(); - m_state = state; - m_status = QMediaRecorder::RecordingStatus; - emit actualLocationChanged(m_session->outputLocation()); - } - } - - if (m_state != oldState) - emit stateChanged(m_state); - - if (m_status != oldStatus) - emit statusChanged(m_status); -} - -bool CameraBinRecorder::isMuted() const -{ - return m_session->isMuted(); -} - -qreal CameraBinRecorder::volume() const -{ - return 1.0; -} - -void CameraBinRecorder::setMuted(bool muted) -{ - m_session->setMuted(muted); -} - -void CameraBinRecorder::setVolume(qreal volume) -{ - if (!qFuzzyCompare(volume, qreal(1.0))) - qWarning() << "Media service doesn't support recorder audio gain."; -} - -QT_END_NAMESPACE - diff --git a/src/plugins/gstreamer/camerabin/camerabinrecorder.h b/src/plugins/gstreamer/camerabin/camerabinrecorder.h deleted file mode 100644 index 8bd922fb8..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinrecorder.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef CAMERABINRECORDERCONTROL_H -#define CAMERABINRECORDERCONTROL_H - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include <qmediarecordercontrol.h> -#include "camerabinsession.h" - -#if QT_CONFIG(gstreamer_encodingprofiles) -#include <gst/pbutils/encoding-profile.h> -#endif - -QT_BEGIN_NAMESPACE - -class CameraBinRecorder : public QMediaRecorderControl -{ - Q_OBJECT - -public: - CameraBinRecorder(CameraBinSession *session); - virtual ~CameraBinRecorder(); - - QUrl outputLocation() const override; - bool setOutputLocation(const QUrl &sink) override; - - QMediaRecorder::State state() const override; - QMediaRecorder::Status status() const override; - - qint64 duration() const override; - - bool isMuted() const override; - qreal volume() const override; - - void applySettings() override; - -#if QT_CONFIG(gstreamer_encodingprofiles) - GstEncodingContainerProfile *videoProfile(); -#endif - -public slots: - void setState(QMediaRecorder::State state) override; - void setMuted(bool) override; - void setVolume(qreal volume) override; - - void updateStatus(); - -private: - CameraBinSession *m_session; - QMediaRecorder::State m_state; - QMediaRecorder::Status m_status; -}; - -QT_END_NAMESPACE - -#endif // CAMERABINCAPTURECORNTROL_H diff --git a/src/plugins/gstreamer/camerabin/camerabinservice.cpp b/src/plugins/gstreamer/camerabin/camerabinservice.cpp deleted file mode 100644 index 671649bab..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinservice.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include "camerabinservice.h" -#include "camerabinsession.h" -#include "camerabinrecorder.h" -#include "camerabincontainer.h" -#include "camerabinaudioencoder.h" -#include "camerabinvideoencoder.h" -#include "camerabinimageencoder.h" -#include "camerabincontrol.h" -#include "camerabinmetadata.h" - -#if QT_CONFIG(gstreamer_photography) -#include "camerabinexposure.h" -#include "camerabinfocus.h" -#endif - -#include "camerabinimagecapture.h" -#include "camerabinimageprocessing.h" -#include <private/qgstreamerbushelper_p.h> -#include <private/qgstutils_p.h> - -#include <private/qgstreameraudioinputselector_p.h> -#include <private/qgstreamervideoinputdevicecontrol_p.h> - -#if defined(HAVE_WIDGETS) -#include <private/qgstreamervideowidget_p.h> -#endif -#include <private/qgstreamervideowindow_p.h> -#include <private/qgstreamervideorenderer_p.h> -#include <private/qmediaserviceprovider_p.h> - -#include <QtCore/qdebug.h> - -QT_BEGIN_NAMESPACE - -CameraBinService::CameraBinService(GstElementFactory *sourceFactory, QObject *parent) - : QMediaService(parent) -{ - m_captureSession = 0; - m_metaDataControl = 0; - - m_audioInputSelector = 0; - m_videoInputDevice = 0; - - m_videoOutput = 0; - m_videoRenderer = 0; - m_videoWindow = 0; -#if defined(HAVE_WIDGETS) - m_videoWidgetControl = 0; -#endif - m_imageCaptureControl = 0; - - m_captureSession = new CameraBinSession(sourceFactory, this); - m_videoInputDevice = new QGstreamerVideoInputDeviceControl(sourceFactory, m_captureSession); - m_imageCaptureControl = new CameraBinImageCapture(m_captureSession); - - connect(m_videoInputDevice, SIGNAL(selectedDeviceChanged(QString)), - m_captureSession, SLOT(setDevice(QString))); - - if (m_videoInputDevice->deviceCount()) - m_captureSession->setDevice(m_videoInputDevice->deviceName(m_videoInputDevice->selectedDevice())); - - m_videoRenderer = new QGstreamerVideoRenderer(this); - - m_videoWindow = new QGstreamerVideoWindow(this); - // If the GStreamer video sink is not available, don't provide the video window control since - // it won't work anyway. - if (!m_videoWindow->videoSink()) { - delete m_videoWindow; - m_videoWindow = 0; - } -#if defined(HAVE_WIDGETS) - m_videoWidgetControl = new QGstreamerVideoWidgetControl(this); - - // If the GStreamer video sink is not available, don't provide the video widget control since - // it won't work anyway. QVideoWidget will fall back to QVideoRendererControl in that case. - if (!m_videoWidgetControl->videoSink()) { - delete m_videoWidgetControl; - m_videoWidgetControl = 0; - } -#endif - - m_audioInputSelector = new QGstreamerAudioInputSelector(this); - connect(m_audioInputSelector, SIGNAL(activeInputChanged(QString)), m_captureSession, SLOT(setCaptureDevice(QString))); - - if (m_captureSession && m_audioInputSelector->availableInputs().size() > 0) - m_captureSession->setCaptureDevice(m_audioInputSelector->defaultInput()); - - m_metaDataControl = new CameraBinMetaData(this); - connect(m_metaDataControl, SIGNAL(metaDataChanged(QMap<QByteArray,QVariant>)), - m_captureSession, SLOT(setMetaData(QMap<QByteArray,QVariant>))); -} - -CameraBinService::~CameraBinService() -{ -} - -QObject *CameraBinService::requestControl(const char *name) -{ - if (!m_captureSession) - return 0; - - if (!m_videoOutput) { - if (qstrcmp(name, QVideoRendererControl_iid) == 0) { - m_videoOutput = m_videoRenderer; - } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) { - m_videoOutput = m_videoWindow; - } -#if defined(HAVE_WIDGETS) - else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) { - m_videoOutput = m_videoWidgetControl; - } -#endif - - if (m_videoOutput) { - m_captureSession->setViewfinder(m_videoOutput); - return m_videoOutput; - } - } - - if (qstrcmp(name, QMediaVideoProbeControl_iid) == 0) - return m_captureSession->videoProbe(); - - if (qstrcmp(name,QAudioInputSelectorControl_iid) == 0) - return m_audioInputSelector; - - if (qstrcmp(name,QVideoDeviceSelectorControl_iid) == 0) - return m_videoInputDevice; - - if (qstrcmp(name,QMediaRecorderControl_iid) == 0) - return m_captureSession->recorderControl(); - - if (qstrcmp(name,QAudioEncoderSettingsControl_iid) == 0) - return m_captureSession->audioEncodeControl(); - - if (qstrcmp(name,QVideoEncoderSettingsControl_iid) == 0) - return m_captureSession->videoEncodeControl(); - - if (qstrcmp(name,QImageEncoderControl_iid) == 0) - return m_captureSession->imageEncodeControl(); - - - if (qstrcmp(name,QMediaContainerControl_iid) == 0) - return m_captureSession->mediaContainerControl(); - - if (qstrcmp(name,QCameraControl_iid) == 0) - return m_captureSession->cameraControl(); - - if (qstrcmp(name,QMetaDataWriterControl_iid) == 0) - return m_metaDataControl; - - if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) - return m_imageCaptureControl; - -#if QT_CONFIG(gstreamer_photography) - if (qstrcmp(name, QCameraExposureControl_iid) == 0) - return m_captureSession->cameraExposureControl(); - - if (qstrcmp(name, QCameraFocusControl_iid) == 0) - return m_captureSession->cameraFocusControl(); -#endif - - if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0) - return m_captureSession->imageProcessingControl(); - - return nullptr; -} - -void CameraBinService::releaseControl(QObject *control) -{ - if (control && control == m_videoOutput) { - m_videoOutput = 0; - m_captureSession->setViewfinder(0); - } -} - -bool CameraBinService::isCameraBinAvailable() -{ - GstElementFactory *factory = gst_element_factory_find("camerabin"); - if (factory) { - gst_object_unref(GST_OBJECT(factory)); - return true; - } - - return false; -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinservice.h b/src/plugins/gstreamer/camerabin/camerabinservice.h deleted file mode 100644 index 0fae02121..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinservice.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CAMERABINCAPTURESERVICE_H -#define CAMERABINCAPTURESERVICE_H - -#include <qmediaservice.h> - -#include <gst/gst.h> - -QT_BEGIN_NAMESPACE -class QAudioInputSelectorControl; -class QVideoDeviceSelectorControl; - - -class CameraBinSession; -class CameraBinControl; -class QGstreamerMessage; -class QGstreamerBusHelper; -class QGstreamerVideoRenderer; -class QGstreamerVideoWindow; -class QGstreamerVideoWidgetControl; -class QGstreamerElementFactory; -class CameraBinMetaData; -class CameraBinImageCapture; -class CameraBinMetaData; - -class CameraBinService : public QMediaService -{ - Q_OBJECT - -public: - CameraBinService(GstElementFactory *sourceFactory, QObject *parent = 0); - virtual ~CameraBinService(); - - QObject *requestControl(const char *name) override; - void releaseControl(QObject *) override; - - static bool isCameraBinAvailable(); - -private: - void setAudioPreview(GstElement*); - - CameraBinSession *m_captureSession; - CameraBinMetaData *m_metaDataControl; - - QAudioInputSelectorControl *m_audioInputSelector; - QVideoDeviceSelectorControl *m_videoInputDevice; - - QObject *m_videoOutput; - - QObject *m_videoRenderer; - QGstreamerVideoWindow *m_videoWindow; -#if defined(HAVE_WIDGETS) - QGstreamerVideoWidgetControl *m_videoWidgetControl; -#endif - CameraBinImageCapture *m_imageCaptureControl; -}; - -QT_END_NAMESPACE - -#endif // CAMERABINCAPTURESERVICE_H diff --git a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp deleted file mode 100644 index f8d9b5a37..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qstring.h> -#include <QtCore/qdebug.h> -#include <QtCore/QDir> -#include <QtCore/QDebug> - -#include "camerabinserviceplugin.h" - -#include "camerabinservice.h" -#include <private/qgstutils_p.h> - -QT_BEGIN_NAMESPACE - -template <typename T, int N> static int lengthOf(const T(&)[N]) { return N; } - -CameraBinServicePlugin::CameraBinServicePlugin() - : m_sourceFactory(0) -{ -} - -CameraBinServicePlugin::~CameraBinServicePlugin() -{ - if (m_sourceFactory) - gst_object_unref(GST_OBJECT(m_sourceFactory)); -} - -QMediaService* CameraBinServicePlugin::create(const QString &key) -{ - QGstUtils::initializeGst(); - - if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)) { - if (!CameraBinService::isCameraBinAvailable()) { - guint major, minor, micro, nano; - gst_version(&major, &minor, µ, &nano); - qWarning("Error: cannot create camera service, the 'camerabin' plugin is missing for " - "GStreamer %u.%u." - "\nPlease install the 'bad' GStreamer plugin package.", - major, minor); - return nullptr; - } - - return new CameraBinService(sourceFactory()); - } - - qWarning() << "Gstreamer camerabin service plugin: unsupported key:" << key; - return 0; -} - -void CameraBinServicePlugin::release(QMediaService *service) -{ - delete service; -} - -QByteArray CameraBinServicePlugin::defaultDevice(const QByteArray &service) const -{ - return service == Q_MEDIASERVICE_CAMERA - ? QGstUtils::enumerateCameras().value(0).name.toUtf8() - : QByteArray(); -} - -QList<QByteArray> CameraBinServicePlugin::devices(const QByteArray &service) const -{ - - return service == Q_MEDIASERVICE_CAMERA - ? QGstUtils::cameraDevices() - : QList<QByteArray>(); -} - -QString CameraBinServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &deviceName) -{ - return service == Q_MEDIASERVICE_CAMERA - ? QGstUtils::cameraDescription(deviceName) - : QString(); -} - -QVariant CameraBinServicePlugin::deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property) -{ - Q_UNUSED(service); - Q_UNUSED(device); - Q_UNUSED(property); - return QVariant(); -} - -GstElementFactory *CameraBinServicePlugin::sourceFactory() const -{ - if (!m_sourceFactory) { - GstElementFactory *factory = 0; - const QByteArray envCandidate = qgetenv("QT_GSTREAMER_CAMERABIN_SRC"); - if (!envCandidate.isEmpty()) - factory = gst_element_factory_find(envCandidate.constData()); - - static const char *candidates[] = { "subdevsrc", "wrappercamerabinsrc" }; - for (int i = 0; !factory && i < lengthOf(candidates); ++i) - factory = gst_element_factory_find(candidates[i]); - - if (factory) { - m_sourceFactory = GST_ELEMENT_FACTORY(gst_plugin_feature_load( - GST_PLUGIN_FEATURE(factory))); - gst_object_unref((GST_OBJECT(factory))); - } - } - - return m_sourceFactory; -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.h b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.h deleted file mode 100644 index 2c1b1a207..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef CAMERABINSERVICEPLUGIN_H -#define CAMERABINSERVICEPLUGIN_H - -#include <qmediaserviceproviderplugin.h> -#include <private/qgstreamervideoinputdevicecontrol_p.h> - -#include <gst/gst.h> - -QT_BEGIN_NAMESPACE - -class CameraBinServicePlugin - : public QMediaServiceProviderPlugin - , public QMediaServiceSupportedDevicesInterface -{ - Q_OBJECT - Q_INTERFACES(QMediaServiceSupportedDevicesInterface) - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "camerabin.json") -public: - CameraBinServicePlugin(); - ~CameraBinServicePlugin(); - - QMediaService* create(const QString &key) override; - void release(QMediaService *service) override; - - QByteArray defaultDevice(const QByteArray &service) const override; - QList<QByteArray> devices(const QByteArray &service) const override; - QString deviceDescription(const QByteArray &service, const QByteArray &device) override; - QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property); - -private: - GstElementFactory *sourceFactory() const; - - mutable GstElementFactory *m_sourceFactory; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERCAPTURESERVICEPLUGIN_H diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp deleted file mode 100644 index 3c05156cc..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp +++ /dev/null @@ -1,1510 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include "camerabinsession.h" -#include "camerabincontrol.h" -#include "camerabinrecorder.h" -#include "camerabincontainer.h" -#include "camerabinaudioencoder.h" -#include "camerabinvideoencoder.h" -#include "camerabinimageencoder.h" - -#if QT_CONFIG(gstreamer_photography) -#include "camerabinexposure.h" -#include "camerabinfocus.h" -#endif - -#include "camerabinimageprocessing.h" - -#include <private/qgstreamerbushelper_p.h> -#include <private/qgstreamervideorendererinterface_p.h> -#include <private/qgstutils_p.h> -#include <qmediarecorder.h> -#include <qvideosurfaceformat.h> - -#if QT_CONFIG(gstreamer_photography) -#include <gst/interfaces/photography.h> -#endif - -#include <gst/gsttagsetter.h> -#include <gst/gstversion.h> - -#include <QtCore/qdebug.h> -#include <QCoreApplication> -#include <QtCore/qmetaobject.h> -#include <QtGui/qdesktopservices.h> - -#include <QtGui/qimage.h> -#include <QtCore/qdatetime.h> - -#include <algorithm> - -//#define CAMERABIN_DEBUG 1 -//#define CAMERABIN_DEBUG_DUMP_BIN 1 -#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v))) - -#define FILENAME_PROPERTY "location" -#define MODE_PROPERTY "mode" -#define MUTE_PROPERTY "mute" -#define IMAGE_PP_PROPERTY "image-post-processing" -#define IMAGE_ENCODER_PROPERTY "image-encoder" -#define VIDEO_PP_PROPERTY "video-post-processing" -#define VIEWFINDER_SINK_PROPERTY "viewfinder-sink" -#define CAMERA_SOURCE_PROPERTY "camera-source" -#define AUDIO_SOURCE_PROPERTY "audio-source" -#define SUPPORTED_IMAGE_CAPTURE_CAPS_PROPERTY "image-capture-supported-caps" -#define SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY "video-capture-supported-caps" -#define SUPPORTED_VIEWFINDER_CAPS_PROPERTY "viewfinder-supported-caps" -#define AUDIO_CAPTURE_CAPS_PROPERTY "audio-capture-caps" -#define IMAGE_CAPTURE_CAPS_PROPERTY "image-capture-caps" -#define VIDEO_CAPTURE_CAPS_PROPERTY "video-capture-caps" -#define VIEWFINDER_CAPS_PROPERTY "viewfinder-caps" -#define PREVIEW_CAPS_PROPERTY "preview-caps" -#define POST_PREVIEWS_PROPERTY "post-previews" - - -#define CAPTURE_START "start-capture" -#define CAPTURE_STOP "stop-capture" - -#define FILESINK_BIN_NAME "videobin-filesink" - -#define CAMERABIN_IMAGE_MODE 1 -#define CAMERABIN_VIDEO_MODE 2 - -#define PREVIEW_CAPS_4_3 \ - "video/x-raw-rgb, width = (int) 640, height = (int) 480" - -QT_BEGIN_NAMESPACE - -CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *parent) - :QObject(parent), - m_recordingActive(false), - m_status(QCamera::UnloadedStatus), - m_pendingState(QCamera::UnloadedState), - m_muted(false), - m_busy(false), - m_captureMode(QCamera::CaptureStillImage), - m_audioInputFactory(0), - m_videoInputFactory(0), - m_viewfinder(0), - m_viewfinderInterface(0), -#if QT_CONFIG(gstreamer_photography) - m_cameraExposureControl(0), - m_cameraFocusControl(0), -#endif - m_cameraSrc(0), - m_videoSrc(0), - m_viewfinderElement(0), - m_sourceFactory(sourceFactory), - m_viewfinderHasChanged(true), - m_inputDeviceHasChanged(true), - m_usingWrapperCameraBinSrc(false), - m_viewfinderProbe(this), - m_audioSrc(0), - m_audioConvert(0), - m_capsFilter(0), - m_fileSink(0), - m_audioEncoder(0), - m_videoEncoder(0), - m_muxer(0) -{ - if (m_sourceFactory) - gst_object_ref(GST_OBJECT(m_sourceFactory)); - m_camerabin = gst_element_factory_make("camerabin", "camerabin"); - - g_signal_connect(G_OBJECT(m_camerabin), "notify::idle", G_CALLBACK(updateBusyStatus), this); - g_signal_connect(G_OBJECT(m_camerabin), "element-added", G_CALLBACK(elementAdded), this); - g_signal_connect(G_OBJECT(m_camerabin), "element-removed", G_CALLBACK(elementRemoved), this); - qt_gst_object_ref_sink(m_camerabin); - - m_bus = gst_element_get_bus(m_camerabin); - - m_busHelper = new QGstreamerBusHelper(m_bus, this); - m_busHelper->installMessageFilter(this); - - m_cameraControl = new CameraBinControl(this); - m_audioEncodeControl = new CameraBinAudioEncoder(this); - m_videoEncodeControl = new CameraBinVideoEncoder(this); - m_imageEncodeControl = new CameraBinImageEncoder(this); - m_recorderControl = new CameraBinRecorder(this); - m_mediaContainerControl = new CameraBinContainer(this); - m_imageProcessingControl = new CameraBinImageProcessing(this); - - QByteArray envFlags = qgetenv("QT_GSTREAMER_CAMERABIN_FLAGS"); - if (!envFlags.isEmpty()) - g_object_set(G_OBJECT(m_camerabin), "flags", envFlags.toInt(), NULL); - - //post image preview in RGB format - g_object_set(G_OBJECT(m_camerabin), POST_PREVIEWS_PROPERTY, TRUE, NULL); - - GstCaps *previewCaps = gst_caps_new_simple( - "video/x-raw", - "format", G_TYPE_STRING, "RGBx", - NULL); - - g_object_set(G_OBJECT(m_camerabin), PREVIEW_CAPS_PROPERTY, previewCaps, NULL); - gst_caps_unref(previewCaps); -} - -CameraBinSession::~CameraBinSession() -{ - if (m_camerabin) { - if (m_viewfinderInterface) - m_viewfinderInterface->stopRenderer(); - - gst_element_set_state(m_camerabin, GST_STATE_NULL); - gst_element_get_state(m_camerabin, NULL, NULL, GST_CLOCK_TIME_NONE); - gst_object_unref(GST_OBJECT(m_bus)); - gst_object_unref(GST_OBJECT(m_camerabin)); - } - if (m_viewfinderElement) - gst_object_unref(GST_OBJECT(m_viewfinderElement)); - - if (m_sourceFactory) - gst_object_unref(GST_OBJECT(m_sourceFactory)); - - if (m_cameraSrc) - gst_object_unref(GST_OBJECT(m_cameraSrc)); - - if (m_videoSrc) - gst_object_unref(GST_OBJECT(m_videoSrc)); -} - -#if QT_CONFIG(gstreamer_photography) -GstPhotography *CameraBinSession::photography() -{ - if (GST_IS_PHOTOGRAPHY(m_camerabin)) { - return GST_PHOTOGRAPHY(m_camerabin); - } - - GstElement * const source = buildCameraSource(); - - if (source && GST_IS_PHOTOGRAPHY(source)) - return GST_PHOTOGRAPHY(source); - - return 0; -} - -CameraBinExposure *CameraBinSession::cameraExposureControl() -{ - if (!m_cameraExposureControl && photography()) - m_cameraExposureControl = new CameraBinExposure(this); - return m_cameraExposureControl; -} - -CameraBinFocus *CameraBinSession::cameraFocusControl() -{ - if (!m_cameraFocusControl && photography()) - m_cameraFocusControl = new CameraBinFocus(this); - return m_cameraFocusControl; -} -#endif - -bool CameraBinSession::setupCameraBin() -{ - if (!buildCameraSource()) - return false; - - if (m_viewfinderHasChanged) { - if (m_viewfinderElement) { - GstPad *pad = gst_element_get_static_pad(m_viewfinderElement, "sink"); - m_viewfinderProbe.removeProbeFromPad(pad); - gst_object_unref(GST_OBJECT(pad)); - gst_object_unref(GST_OBJECT(m_viewfinderElement)); - } - - m_viewfinderElement = m_viewfinderInterface ? m_viewfinderInterface->videoSink() : 0; -#if CAMERABIN_DEBUG - qDebug() << Q_FUNC_INFO << "Viewfinder changed, reconfigure."; -#endif - m_viewfinderHasChanged = false; - if (!m_viewfinderElement) { - if (m_pendingState == QCamera::ActiveState) - qWarning() << "Starting camera without viewfinder available"; - m_viewfinderElement = gst_element_factory_make("fakesink", NULL); - } - - GstPad *pad = gst_element_get_static_pad(m_viewfinderElement, "sink"); - m_viewfinderProbe.addProbeToPad(pad); - gst_object_unref(GST_OBJECT(pad)); - - g_object_set(G_OBJECT(m_viewfinderElement), "sync", FALSE, NULL); - qt_gst_object_ref_sink(GST_OBJECT(m_viewfinderElement)); - gst_element_set_state(m_camerabin, GST_STATE_NULL); - g_object_set(G_OBJECT(m_camerabin), VIEWFINDER_SINK_PROPERTY, m_viewfinderElement, NULL); - } - - return true; -} - -static GstCaps *resolutionToCaps(const QSize &resolution, - qreal frameRate = 0.0, - QVideoFrame::PixelFormat pixelFormat = QVideoFrame::Format_Invalid) -{ - GstCaps *caps = 0; - if (pixelFormat == QVideoFrame::Format_Invalid) - caps = QGstUtils::videoFilterCaps(); - else - caps = QGstUtils::capsForFormats(QList<QVideoFrame::PixelFormat>() << pixelFormat); - - if (!resolution.isEmpty()) { - gst_caps_set_simple( - caps, - "width", G_TYPE_INT, resolution.width(), - "height", G_TYPE_INT, resolution.height(), - NULL); - } - - if (frameRate > 0.0) { - gint numerator; - gint denominator; - qt_gst_util_double_to_fraction(frameRate, &numerator, &denominator); - - gst_caps_set_simple( - caps, - "framerate", GST_TYPE_FRACTION, numerator, denominator, - NULL); - } - - return caps; -} - -void CameraBinSession::setupCaptureResolution() -{ - QSize viewfinderResolution = m_viewfinderSettings.resolution(); - qreal viewfinderFrameRate = m_viewfinderSettings.maximumFrameRate(); - QVideoFrame::PixelFormat viewfinderPixelFormat = m_viewfinderSettings.pixelFormat(); - const QSize imageResolution = m_imageEncodeControl->imageSettings().resolution(); - const QSize videoResolution = m_videoEncodeControl->actualVideoSettings().resolution(); - - // WrapperCameraBinSrc cannot have different caps on its imgsrc, vidsrc and vfsrc pads. - // If capture resolution is specified, use it also for the viewfinder to avoid caps negotiation - // to fail. - if (m_usingWrapperCameraBinSrc) { - if (viewfinderResolution.isEmpty()) { - if (m_captureMode == QCamera::CaptureStillImage && !imageResolution.isEmpty()) - viewfinderResolution = imageResolution; - else if (m_captureMode == QCamera::CaptureVideo && !videoResolution.isEmpty()) - viewfinderResolution = videoResolution; - } - - // Make sure we don't use incompatible frame rate and pixel format with the new resolution - if (viewfinderResolution != m_viewfinderSettings.resolution() && - (!qFuzzyIsNull(viewfinderFrameRate) || viewfinderPixelFormat != QVideoFrame::Format_Invalid)) { - - enum { - Nothing = 0x0, - OnlyFrameRate = 0x1, - OnlyPixelFormat = 0x2, - Both = 0x4 - }; - quint8 found = Nothing; - auto viewfinderSettings = supportedViewfinderSettings(); - for (int i = 0; i < viewfinderSettings.count() && !(found & Both); ++i) { - const QCameraViewfinderSettings &s = viewfinderSettings.at(i); - if (s.resolution() == viewfinderResolution) { - if ((qFuzzyIsNull(viewfinderFrameRate) || s.maximumFrameRate() == viewfinderFrameRate) - && (viewfinderPixelFormat == QVideoFrame::Format_Invalid || s.pixelFormat() == viewfinderPixelFormat)) - found |= Both; - else if (s.maximumFrameRate() == viewfinderFrameRate) - found |= OnlyFrameRate; - else if (s.pixelFormat() == viewfinderPixelFormat) - found |= OnlyPixelFormat; - } - } - - if (found & Both) { - // no-op - } else if (found & OnlyPixelFormat) { - viewfinderFrameRate = qreal(0); - } else if (found & OnlyFrameRate) { - viewfinderPixelFormat = QVideoFrame::Format_Invalid; - } else { - viewfinderPixelFormat = QVideoFrame::Format_Invalid; - viewfinderFrameRate = qreal(0); - } - } - } - - GstCaps *caps = resolutionToCaps(imageResolution); - g_object_set(m_camerabin, IMAGE_CAPTURE_CAPS_PROPERTY, caps, NULL); - gst_caps_unref(caps); - - qreal framerate = m_videoEncodeControl->videoSettings().frameRate(); - caps = resolutionToCaps(videoResolution, framerate); - g_object_set(m_camerabin, VIDEO_CAPTURE_CAPS_PROPERTY, caps, NULL); - gst_caps_unref(caps); - - caps = resolutionToCaps(viewfinderResolution, viewfinderFrameRate, viewfinderPixelFormat); - g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, caps, NULL); - gst_caps_unref(caps); - - // Special case when using mfw_v4lsrc - if (m_videoSrc && qstrcmp(qt_gst_element_get_factory_name(m_videoSrc), "mfw_v4lsrc") == 0) { - int capMode = 0; - if (viewfinderResolution == QSize(320, 240)) - capMode = 1; - else if (viewfinderResolution == QSize(720, 480)) - capMode = 2; - else if (viewfinderResolution == QSize(720, 576)) - capMode = 3; - else if (viewfinderResolution == QSize(1280, 720)) - capMode = 4; - else if (viewfinderResolution == QSize(1920, 1080)) - capMode = 5; - g_object_set(G_OBJECT(m_videoSrc), "capture-mode", capMode, NULL); - - if (!qFuzzyIsNull(viewfinderFrameRate)) { - int n, d; - qt_gst_util_double_to_fraction(viewfinderFrameRate, &n, &d); - g_object_set(G_OBJECT(m_videoSrc), "fps-n", n, NULL); - g_object_set(G_OBJECT(m_videoSrc), "fps-d", d, NULL); - } - } - - if (m_videoEncoder) - m_videoEncodeControl->applySettings(m_videoEncoder); -} - -void CameraBinSession::setAudioCaptureCaps() -{ - QAudioEncoderSettings settings = m_audioEncodeControl->audioSettings(); - const int sampleRate = settings.sampleRate(); - const int channelCount = settings.channelCount(); - - if (sampleRate <= 0 && channelCount <=0) - return; - - GstStructure *structure = gst_structure_new_empty("audio/x-raw"); - if (sampleRate > 0) - gst_structure_set(structure, "rate", G_TYPE_INT, sampleRate, NULL); - if (channelCount > 0) - gst_structure_set(structure, "channels", G_TYPE_INT, channelCount, NULL); - - GstCaps *caps = gst_caps_new_full(structure, NULL); - g_object_set(G_OBJECT(m_camerabin), AUDIO_CAPTURE_CAPS_PROPERTY, caps, NULL); - gst_caps_unref(caps); - - if (m_audioEncoder) - m_audioEncodeControl->applySettings(m_audioEncoder); -} - -GstElement *CameraBinSession::buildCameraSource() -{ -#if CAMERABIN_DEBUG - qDebug() << Q_FUNC_INFO; -#endif - if (m_inputDevice.isEmpty()) - return nullptr; - - if (!m_inputDeviceHasChanged) - return m_cameraSrc; - - m_inputDeviceHasChanged = false; - m_usingWrapperCameraBinSrc = false; - - GstElement *camSrc = 0; - g_object_get(G_OBJECT(m_camerabin), CAMERA_SOURCE_PROPERTY, &camSrc, NULL); - - if (!m_cameraSrc && m_sourceFactory) - m_cameraSrc = gst_element_factory_create(m_sourceFactory, "camera_source"); - - // If gstreamer has set a default source use it. - if (!m_cameraSrc) - m_cameraSrc = camSrc; - - if (m_cameraSrc) { -#if CAMERABIN_DEBUG - qDebug() << "set camera device" << m_inputDevice; -#endif - m_usingWrapperCameraBinSrc = qstrcmp(qt_gst_element_get_factory_name(m_cameraSrc), "wrappercamerabinsrc") == 0; - - if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_cameraSrc), "video-source")) { - if (!m_videoSrc) { - /* QT_GSTREAMER_CAMERABIN_VIDEOSRC can be used to set the video source element. - - --- Usage - - QT_GSTREAMER_CAMERABIN_VIDEOSRC=[drivername=elementname[,drivername2=elementname2 ...],][elementname] - - --- Examples - - Always use 'somevideosrc': - QT_GSTREAMER_CAMERABIN_VIDEOSRC="somevideosrc" - - Use 'somevideosrc' when the device driver is 'somedriver', otherwise use default: - QT_GSTREAMER_CAMERABIN_VIDEOSRC="somedriver=somevideosrc" - - Use 'somevideosrc' when the device driver is 'somedriver', otherwise use 'somevideosrc2' - QT_GSTREAMER_CAMERABIN_VIDEOSRC="somedriver=somevideosrc,somevideosrc2" - */ - const QByteArray envVideoSource = qgetenv("QT_GSTREAMER_CAMERABIN_VIDEOSRC"); - - if (!envVideoSource.isEmpty()) { - const QList<QByteArray> sources = envVideoSource.split(','); - for (const QByteArray &source : sources) { - QList<QByteArray> keyValue = source.split('='); - QByteArray name = keyValue.at(0); - if (keyValue.count() > 1 && keyValue.at(0) == QGstUtils::cameraDriver(m_inputDevice)) - name = keyValue.at(1); - - GError *error = NULL; - GstElement *element = gst_parse_launch(name, &error); - - if (error) { - g_printerr("ERROR: %s: %s\n", name.constData(), GST_STR_NULL(error->message)); - g_clear_error(&error); - } - if (element) { - m_videoSrc = element; - break; - } - } - } else if (m_videoInputFactory) { - m_videoSrc = m_videoInputFactory->buildElement(); - } - - if (!m_videoSrc) - m_videoSrc = gst_element_factory_make("v4l2src", "camera_source"); - - if (!m_videoSrc) - m_videoSrc = gst_element_factory_make("ksvideosrc", "camera_source"); - - if (!m_videoSrc) - m_videoSrc = gst_element_factory_make("avfvideosrc", "camera_source"); - - if (m_videoSrc) - g_object_set(G_OBJECT(m_cameraSrc), "video-source", m_videoSrc, NULL); - } - - if (m_videoSrc) { - if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSrc), "device")) - g_object_set(G_OBJECT(m_videoSrc), "device", m_inputDevice.toUtf8().constData(), NULL); - - if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSrc), "device-path")) - g_object_set(G_OBJECT(m_videoSrc), "device-path", m_inputDevice.toUtf8().constData(), NULL); - - if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSrc), "device-index")) - g_object_set(G_OBJECT(m_videoSrc), "device-index", m_inputDevice.toInt(), NULL); - } - } else if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_cameraSrc), "camera-device")) { - if (m_inputDevice == QLatin1String("secondary")) { - g_object_set(G_OBJECT(m_cameraSrc), "camera-device", 1, NULL); - } else { - g_object_set(G_OBJECT(m_cameraSrc), "camera-device", 0, NULL); - } - } - } - - if (m_cameraSrc != camSrc) { - g_object_set(G_OBJECT(m_camerabin), CAMERA_SOURCE_PROPERTY, m_cameraSrc, NULL); - // Unref only if camSrc is not m_cameraSrc to prevent double unrefing. - if (camSrc) - gst_object_unref(GST_OBJECT(camSrc)); - } - - return m_cameraSrc; -} - -void CameraBinSession::captureImage(int requestId, const QString &fileName) -{ - const QString actualFileName = m_mediaStorageLocation.generateFileName(fileName, - QMediaStorageLocation::Pictures, - QLatin1String("IMG_"), - QLatin1String("jpg")); - - m_requestId = requestId; - -#if CAMERABIN_DEBUG - qDebug() << Q_FUNC_INFO << m_requestId << fileName << "actual file name:" << actualFileName; -#endif - - g_object_set(G_OBJECT(m_camerabin), FILENAME_PROPERTY, actualFileName.toLocal8Bit().constData(), NULL); - - g_signal_emit_by_name(G_OBJECT(m_camerabin), CAPTURE_START, NULL); - - m_imageFileName = actualFileName; -} - -void CameraBinSession::setCaptureMode(QCamera::CaptureModes mode) -{ - m_captureMode = mode; - - switch (m_captureMode) { - case QCamera::CaptureStillImage: - g_object_set(m_camerabin, MODE_PROPERTY, CAMERABIN_IMAGE_MODE, NULL); - break; - case QCamera::CaptureVideo: - g_object_set(m_camerabin, MODE_PROPERTY, CAMERABIN_VIDEO_MODE, NULL); - break; - } - - m_recorderControl->updateStatus(); -} - -QUrl CameraBinSession::outputLocation() const -{ - //return the location service wrote data to, not one set by user, it can be empty. - return m_actualSink; -} - -bool CameraBinSession::setOutputLocation(const QUrl& sink) -{ - if (!sink.isRelative() && !sink.isLocalFile()) { - qWarning("Output location must be a local file"); - return false; - } - - m_sink = m_actualSink = sink; - return true; -} - -void CameraBinSession::setDevice(const QString &device) -{ - if (m_inputDevice != device) { - m_inputDevice = device; - m_inputDeviceHasChanged = true; - } -} - -void CameraBinSession::setAudioInput(QGstreamerElementFactory *audioInput) -{ - m_audioInputFactory = audioInput; -} - -void CameraBinSession::setVideoInput(QGstreamerElementFactory *videoInput) -{ - m_videoInputFactory = videoInput; - m_inputDeviceHasChanged = true; -} - -bool CameraBinSession::isReady() const -{ - //it's possible to use QCamera without any viewfinder attached - return !m_viewfinderInterface || m_viewfinderInterface->isReady(); -} - -void CameraBinSession::setViewfinder(QObject *viewfinder) -{ - if (m_viewfinderInterface) - m_viewfinderInterface->stopRenderer(); - - m_viewfinderInterface = qobject_cast<QGstreamerVideoRendererInterface*>(viewfinder); - if (!m_viewfinderInterface) - viewfinder = 0; - - if (m_viewfinder != viewfinder) { - bool oldReady = isReady(); - - if (m_viewfinder) { - disconnect(m_viewfinder, SIGNAL(sinkChanged()), - this, SLOT(handleViewfinderChange())); - disconnect(m_viewfinder, SIGNAL(readyChanged(bool)), - this, SIGNAL(readyChanged(bool))); - - m_busHelper->removeMessageFilter(m_viewfinder); - } - - m_viewfinder = viewfinder; - m_viewfinderHasChanged = true; - - if (m_viewfinder) { - connect(m_viewfinder, SIGNAL(sinkChanged()), - this, SLOT(handleViewfinderChange())); - connect(m_viewfinder, SIGNAL(readyChanged(bool)), - this, SIGNAL(readyChanged(bool))); - - m_busHelper->installMessageFilter(m_viewfinder); - } - - emit viewfinderChanged(); - if (oldReady != isReady()) - emit readyChanged(isReady()); - } -} - -static QList<QCameraViewfinderSettings> capsToViewfinderSettings(GstCaps *supportedCaps) -{ - QList<QCameraViewfinderSettings> settings; - - if (!supportedCaps) - return settings; - - supportedCaps = qt_gst_caps_normalize(supportedCaps); - - // Convert caps to QCameraViewfinderSettings - for (uint i = 0; i < gst_caps_get_size(supportedCaps); ++i) { - const GstStructure *structure = gst_caps_get_structure(supportedCaps, i); - - QCameraViewfinderSettings s; - s.setResolution(QGstUtils::structureResolution(structure)); - s.setPixelFormat(QGstUtils::structurePixelFormat(structure)); - s.setPixelAspectRatio(QGstUtils::structurePixelAspectRatio(structure)); - - QPair<qreal, qreal> frameRateRange = QGstUtils::structureFrameRateRange(structure); - s.setMinimumFrameRate(frameRateRange.first); - s.setMaximumFrameRate(frameRateRange.second); - - if (!s.resolution().isEmpty() - && s.pixelFormat() != QVideoFrame::Format_Invalid - && !settings.contains(s)) { - settings.append(s); - } - } - - gst_caps_unref(supportedCaps); - return settings; -} - -QList<QCameraViewfinderSettings> CameraBinSession::supportedViewfinderSettings() const -{ - if (m_status >= QCamera::LoadedStatus && m_supportedViewfinderSettings.isEmpty()) { - m_supportedViewfinderSettings = - capsToViewfinderSettings(supportedCaps(QCamera::CaptureViewfinder)); - } - - return m_supportedViewfinderSettings; -} - -QCameraViewfinderSettings CameraBinSession::viewfinderSettings() const -{ - return m_status == QCamera::ActiveStatus ? m_actualViewfinderSettings : m_viewfinderSettings; -} - -void CameraBinSession::ViewfinderProbe::probeCaps(GstCaps *caps) -{ - QGstreamerVideoProbeControl::probeCaps(caps); - - // Update actual viewfinder settings on viewfinder caps change - const GstStructure *s = gst_caps_get_structure(caps, 0); - const QPair<qreal, qreal> frameRate = QGstUtils::structureFrameRateRange(s); - session->m_actualViewfinderSettings.setResolution(QGstUtils::structureResolution(s)); - session->m_actualViewfinderSettings.setMinimumFrameRate(frameRate.first); - session->m_actualViewfinderSettings.setMaximumFrameRate(frameRate.second); - session->m_actualViewfinderSettings.setPixelFormat(QGstUtils::structurePixelFormat(s)); - session->m_actualViewfinderSettings.setPixelAspectRatio(QGstUtils::structurePixelAspectRatio(s)); -} - -void CameraBinSession::handleViewfinderChange() -{ - //the viewfinder will be reloaded - //shortly when the pipeline is started - m_viewfinderHasChanged = true; - emit viewfinderChanged(); -} - -void CameraBinSession::setStatus(QCamera::Status status) -{ - if (m_status == status) - return; - - m_status = status; - emit statusChanged(m_status); - - setStateHelper(m_pendingState); -} - -QCamera::Status CameraBinSession::status() const -{ - return m_status; -} - -QCamera::State CameraBinSession::pendingState() const -{ - return m_pendingState; -} - -void CameraBinSession::setState(QCamera::State newState) -{ - if (newState == m_pendingState) - return; - - m_pendingState = newState; - emit pendingStateChanged(m_pendingState); - -#if CAMERABIN_DEBUG - qDebug() << Q_FUNC_INFO << newState; -#endif - - setStateHelper(newState); -} - -void CameraBinSession::setStateHelper(QCamera::State state) -{ - switch (state) { - case QCamera::UnloadedState: - unload(); - break; - case QCamera::LoadedState: - if (m_status == QCamera::ActiveStatus) - stop(); - else if (m_status == QCamera::UnloadedStatus) - load(); - break; - case QCamera::ActiveState: - // If the viewfinder changed while in the loaded state, we need to reload the pipeline - if (m_status == QCamera::LoadedStatus && !m_viewfinderHasChanged) - start(); - else if (m_status == QCamera::UnloadedStatus || m_viewfinderHasChanged) - load(); - } -} - -void CameraBinSession::setError(int err, const QString &errorString) -{ - // Emit only first error - if (m_pendingState == QCamera::UnloadedState) - return; - - setState(QCamera::UnloadedState); - emit error(err, errorString); - setStatus(QCamera::UnloadedStatus); -} - -void CameraBinSession::load() -{ - if (m_status != QCamera::UnloadedStatus && !m_viewfinderHasChanged) - return; - - setStatus(QCamera::LoadingStatus); - - gst_element_set_state(m_camerabin, GST_STATE_NULL); - - if (!setupCameraBin()) { - setError(QCamera::CameraError, QStringLiteral("No camera source available")); - return; - } - - m_recorderControl->applySettings(); - -#if QT_CONFIG(gstreamer_encodingprofiles) - GstEncodingContainerProfile *profile = m_recorderControl->videoProfile(); - if (profile) { - g_object_set (G_OBJECT(m_camerabin), - "video-profile", - profile, - NULL); - gst_encoding_profile_unref(profile); - } -#endif - - gst_element_set_state(m_camerabin, GST_STATE_READY); -} - -void CameraBinSession::unload() -{ - if (m_status == QCamera::UnloadedStatus || m_status == QCamera::UnloadingStatus) - return; - - setStatus(QCamera::UnloadingStatus); - - if (m_recordingActive) - stopVideoRecording(); - - if (m_viewfinderInterface) - m_viewfinderInterface->stopRenderer(); - - gst_element_set_state(m_camerabin, GST_STATE_NULL); - - if (m_busy) - emit busyChanged(m_busy = false); - - m_supportedViewfinderSettings.clear(); - - setStatus(QCamera::UnloadedStatus); -} - -void CameraBinSession::start() -{ - if (m_status != QCamera::LoadedStatus) - return; - - setStatus(QCamera::StartingStatus); - - setAudioCaptureCaps(); - - setupCaptureResolution(); - - gst_element_set_state(m_camerabin, GST_STATE_PLAYING); -} - -void CameraBinSession::stop() -{ - if (m_status != QCamera::ActiveStatus) - return; - - setStatus(QCamera::StoppingStatus); - - if (m_recordingActive) - stopVideoRecording(); - - if (m_viewfinderInterface) - m_viewfinderInterface->stopRenderer(); - - gst_element_set_state(m_camerabin, GST_STATE_READY); -} - -bool CameraBinSession::isBusy() const -{ - return m_busy; -} - -void CameraBinSession::updateBusyStatus(GObject *o, GParamSpec *p, gpointer d) -{ - Q_UNUSED(p); - CameraBinSession *session = reinterpret_cast<CameraBinSession *>(d); - - gboolean idle = false; - g_object_get(o, "idle", &idle, NULL); - bool busy = !idle; - - if (session->m_busy != busy) { - session->m_busy = busy; - QMetaObject::invokeMethod(session, "busyChanged", - Qt::QueuedConnection, - Q_ARG(bool, busy)); - } -} - -qint64 CameraBinSession::duration() const -{ - if (m_camerabin) { - GstElement *fileSink = gst_bin_get_by_name(GST_BIN(m_camerabin), FILESINK_BIN_NAME); - if (fileSink) { - GstFormat format = GST_FORMAT_TIME; - gint64 duration = 0; - bool ret = qt_gst_element_query_position(fileSink, format, &duration); - gst_object_unref(GST_OBJECT(fileSink)); - if (ret) - return duration / 1000000; - } - } - - return 0; -} - -bool CameraBinSession::isMuted() const -{ - return m_muted; -} - -void CameraBinSession::setMuted(bool muted) -{ - if (m_muted != muted) { - m_muted = muted; - - if (m_camerabin) - g_object_set(G_OBJECT(m_camerabin), MUTE_PROPERTY, m_muted, NULL); - emit mutedChanged(m_muted); - } -} - -void CameraBinSession::setCaptureDevice(const QString &deviceName) -{ - m_captureDevice = deviceName; -} - -void CameraBinSession::setMetaData(const QMap<QByteArray, QVariant> &data) -{ - m_metaData = data; - - if (m_camerabin) - QGstUtils::setMetaData(m_camerabin, data); -} - -bool CameraBinSession::processSyncMessage(const QGstreamerMessage &message) -{ - GstMessage* gm = message.rawMessage(); - - if (gm && GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) { - const GstStructure *st = gst_message_get_structure(gm); - const GValue *sampleValue = 0; - if (m_captureMode == QCamera::CaptureStillImage - && gst_structure_has_name(st, "preview-image") - && gst_structure_has_field_typed(st, "sample", GST_TYPE_SAMPLE) - && (sampleValue = gst_structure_get_value(st, "sample"))) { - GstSample * const sample = gst_value_get_sample(sampleValue); - GstCaps * const previewCaps = gst_sample_get_caps(sample); - GstBuffer * const buffer = gst_sample_get_buffer(sample); - - QImage image; - GstVideoInfo previewInfo; - if (gst_video_info_from_caps(&previewInfo, previewCaps)) - image = QGstUtils::bufferToImage(buffer, previewInfo); - if (!image.isNull()) { - static QMetaMethod exposedSignal = QMetaMethod::fromSignal(&CameraBinSession::imageExposed); - exposedSignal.invoke(this, - Qt::QueuedConnection, - Q_ARG(int,m_requestId)); - - static QMetaMethod capturedSignal = QMetaMethod::fromSignal(&CameraBinSession::imageCaptured); - capturedSignal.invoke(this, - Qt::QueuedConnection, - Q_ARG(int,m_requestId), - Q_ARG(QImage,image)); - } - return true; - } -#if QT_CONFIG(gstreamer_photography) - if (gst_structure_has_name(st, GST_PHOTOGRAPHY_AUTOFOCUS_DONE)) - m_cameraFocusControl->handleFocusMessage(gm); -#endif - } - - return false; -} - -bool CameraBinSession::processBusMessage(const QGstreamerMessage &message) -{ - GstMessage* gm = message.rawMessage(); - - if (gm) { - if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ERROR) { - GError *err; - gchar *debug; - gst_message_parse_error (gm, &err, &debug); - - QString message; - - if (err && err->message) { - message = QString::fromUtf8(err->message); - qWarning() << "CameraBin error:" << message; -#if CAMERABIN_DEBUG - qWarning() << QString::fromUtf8(debug); -#endif - } - - // Only report error messages from camerabin or video source - if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_camerabin) - || GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSrc)) { - if (message.isEmpty()) - message = tr("Camera error"); - - setError(int(QMediaRecorder::ResourceError), message); - } - -#ifdef CAMERABIN_DEBUG_DUMP_BIN - _gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_camerabin), - GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES*/), - "camerabin_error"); -#endif - - - if (err) - g_error_free (err); - - if (debug) - g_free (debug); - } - - if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_WARNING) { - GError *err; - gchar *debug; - gst_message_parse_warning (gm, &err, &debug); - - if (err && err->message) - qWarning() << "CameraBin warning:" << QString::fromUtf8(err->message); - - if (err) - g_error_free (err); - if (debug) - g_free (debug); - } - - if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_camerabin)) { - switch (GST_MESSAGE_TYPE(gm)) { - case GST_MESSAGE_DURATION: - break; - - case GST_MESSAGE_STATE_CHANGED: - { - - GstState oldState; - GstState newState; - GstState pending; - - gst_message_parse_state_changed(gm, &oldState, &newState, &pending); - - -#if CAMERABIN_DEBUG - QStringList states; - states << "GST_STATE_VOID_PENDING" << "GST_STATE_NULL" << "GST_STATE_READY" << "GST_STATE_PAUSED" << "GST_STATE_PLAYING"; - - - qDebug() << QString("state changed: old: %1 new: %2 pending: %3") \ - .arg(states[oldState]) \ - .arg(states[newState]) \ - .arg(states[pending]); -#endif - -#ifdef CAMERABIN_DEBUG_DUMP_BIN - _gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_camerabin), - GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /*GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES*/), - "camerabin"); -#endif - - switch (newState) { - case GST_STATE_VOID_PENDING: - case GST_STATE_NULL: - setStatus(QCamera::UnloadedStatus); - break; - case GST_STATE_READY: - if (oldState == GST_STATE_NULL) - m_supportedViewfinderSettings.clear(); - - setMetaData(m_metaData); - setStatus(QCamera::LoadedStatus); - break; - case GST_STATE_PLAYING: - setStatus(QCamera::ActiveStatus); - break; - case GST_STATE_PAUSED: - default: - break; - } - } - break; - default: - break; - } - } - } - - return false; -} - -QGstreamerVideoProbeControl *CameraBinSession::videoProbe() -{ - return &m_viewfinderProbe; -} - -QString CameraBinSession::currentContainerFormat() const -{ - if (!m_muxer) - return QString(); - - QString format; - - if (GstPad *srcPad = gst_element_get_static_pad(m_muxer, "src")) { - if (GstCaps *caps = qt_gst_pad_get_caps(srcPad)) { - gchar *capsString = gst_caps_to_string(caps); - format = QString::fromLatin1(capsString); - if (capsString) - g_free(capsString); - gst_caps_unref(caps); - } - gst_object_unref(GST_OBJECT(srcPad)); - } - - return format; -} - -void CameraBinSession::recordVideo() -{ - QString format = currentContainerFormat(); - if (format.isEmpty()) - format = m_mediaContainerControl->actualContainerFormat(); - - const QString fileName = m_sink.isLocalFile() ? m_sink.toLocalFile() : m_sink.toString(); - const QFileInfo fileInfo(fileName); - const QString extension = fileInfo.suffix().isEmpty() - ? QGstUtils::fileExtensionForMimeType(format) - : fileInfo.suffix(); - - const QString actualFileName = m_mediaStorageLocation.generateFileName(fileName, - QMediaStorageLocation::Movies, - QLatin1String("clip_"), - extension); - - m_recordingActive = true; - m_actualSink = QUrl::fromLocalFile(actualFileName); - - g_object_set(G_OBJECT(m_camerabin), FILENAME_PROPERTY, QFile::encodeName(actualFileName).constData(), NULL); - - g_signal_emit_by_name(G_OBJECT(m_camerabin), CAPTURE_START, NULL); -} - -void CameraBinSession::stopVideoRecording() -{ - m_recordingActive = false; - g_signal_emit_by_name(G_OBJECT(m_camerabin), CAPTURE_STOP, NULL); -} - -//internal, only used by CameraBinSession::supportedFrameRates. -//recursively fills the list of framerates res from value data. -static void readValue(const GValue *value, QList< QPair<int,int> > *res, bool *continuous) -{ - if (GST_VALUE_HOLDS_FRACTION(value)) { - int num = gst_value_get_fraction_numerator(value); - int denum = gst_value_get_fraction_denominator(value); - - *res << QPair<int,int>(num, denum); - } else if (GST_VALUE_HOLDS_FRACTION_RANGE(value)) { - const GValue *rateValueMin = gst_value_get_fraction_range_min(value); - const GValue *rateValueMax = gst_value_get_fraction_range_max(value); - - if (continuous) - *continuous = true; - - readValue(rateValueMin, res, continuous); - readValue(rateValueMax, res, continuous); - } else if (GST_VALUE_HOLDS_LIST(value)) { - for (uint i=0; i<gst_value_list_get_size(value); i++) { - readValue(gst_value_list_get_value(value, i), res, continuous); - } - } -} - -static bool rateLessThan(const QPair<int,int> &r1, const QPair<int,int> &r2) -{ - return r1.first*r2.second < r2.first*r1.second; -} - -GstCaps *CameraBinSession::supportedCaps(QCamera::CaptureModes mode) const -{ - GstCaps *supportedCaps = 0; - - // When using wrappercamerabinsrc, get the supported caps directly from the video source element. - // This makes sure we only get the caps actually supported by the video source element. - if (m_videoSrc) { - GstPad *pad = gst_element_get_static_pad(m_videoSrc, "src"); - if (pad) { - supportedCaps = qt_gst_pad_get_caps(pad); - gst_object_unref(GST_OBJECT(pad)); - } - } - - // Otherwise, let the camerabin handle this. - if (!supportedCaps) { - const gchar *prop; - switch (mode) { - case QCamera::CaptureStillImage: - prop = SUPPORTED_IMAGE_CAPTURE_CAPS_PROPERTY; - break; - case QCamera::CaptureVideo: - prop = SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY; - break; - case QCamera::CaptureViewfinder: - default: - prop = SUPPORTED_VIEWFINDER_CAPS_PROPERTY; - break; - } - - g_object_get(G_OBJECT(m_camerabin), prop, &supportedCaps, NULL); - } - - return supportedCaps; -} - -QList< QPair<int,int> > CameraBinSession::supportedFrameRates(const QSize &frameSize, bool *continuous) const -{ - QList< QPair<int,int> > res; - - GstCaps *supportedCaps = this->supportedCaps(QCamera::CaptureVideo); - - if (!supportedCaps) - return res; - - GstCaps *caps = 0; - - if (frameSize.isEmpty()) { - caps = gst_caps_copy(supportedCaps); - } else { - GstCaps *filter = QGstUtils::videoFilterCaps(); - gst_caps_set_simple( - filter, - "width", G_TYPE_INT, frameSize.width(), - "height", G_TYPE_INT, frameSize.height(), - NULL); - - caps = gst_caps_intersect(supportedCaps, filter); - gst_caps_unref(filter); - } - gst_caps_unref(supportedCaps); - - //simplify to the list of rates only: - caps = gst_caps_make_writable(caps); - for (uint i=0; i<gst_caps_get_size(caps); i++) { - GstStructure *structure = gst_caps_get_structure(caps, i); - gst_structure_set_name(structure, "video/x-raw"); - gst_caps_set_features(caps, i, NULL); - const GValue *oldRate = gst_structure_get_value(structure, "framerate"); - if (!oldRate) - continue; - - GValue rate; - memset(&rate, 0, sizeof(rate)); - g_value_init(&rate, G_VALUE_TYPE(oldRate)); - g_value_copy(oldRate, &rate); - gst_structure_remove_all_fields(structure); - gst_structure_set_value(structure, "framerate", &rate); - g_value_unset(&rate); - } - caps = gst_caps_simplify(caps); - - for (uint i=0; i<gst_caps_get_size(caps); i++) { - GstStructure *structure = gst_caps_get_structure(caps, i); - const GValue *rateValue = gst_structure_get_value(structure, "framerate"); - if (!rateValue) - continue; - - readValue(rateValue, &res, continuous); - } - - std::sort(res.begin(), res.end(), rateLessThan); - -#if CAMERABIN_DEBUG - qDebug() << "Supported rates:" << caps; - qDebug() << res; -#endif - - gst_caps_unref(caps); - - return res; -} - -//internal, only used by CameraBinSession::supportedResolutions -//recursively find the supported resolutions range. -static QPair<int,int> valueRange(const GValue *value, bool *continuous) -{ - int minValue = 0; - int maxValue = 0; - - if (g_value_type_compatible(G_VALUE_TYPE(value), G_TYPE_INT)) { - minValue = maxValue = g_value_get_int(value); - } else if (GST_VALUE_HOLDS_INT_RANGE(value)) { - minValue = gst_value_get_int_range_min(value); - maxValue = gst_value_get_int_range_max(value); - *continuous = true; - } else if (GST_VALUE_HOLDS_LIST(value)) { - for (uint i=0; i<gst_value_list_get_size(value); i++) { - QPair<int,int> res = valueRange(gst_value_list_get_value(value, i), continuous); - - if (res.first > 0 && minValue > 0) - minValue = qMin(minValue, res.first); - else //select non 0 valid value - minValue = qMax(minValue, res.first); - - maxValue = qMax(maxValue, res.second); - } - } - - return QPair<int,int>(minValue, maxValue); -} - -static bool resolutionLessThan(const QSize &r1, const QSize &r2) -{ - return qlonglong(r1.width()) * r1.height() < qlonglong(r2.width()) * r2.height(); -} - - -QList<QSize> CameraBinSession::supportedResolutions(QPair<int,int> rate, - bool *continuous, - QCamera::CaptureModes mode) const -{ - QList<QSize> res; - - if (continuous) - *continuous = false; - - GstCaps *supportedCaps = this->supportedCaps(mode); - -#if CAMERABIN_DEBUG - qDebug() << "Source caps:" << supportedCaps; -#endif - - if (!supportedCaps) - return res; - - GstCaps *caps = 0; - bool isContinuous = false; - - if (rate.first <= 0 || rate.second <= 0) { - caps = gst_caps_copy(supportedCaps); - } else { - GstCaps *filter = QGstUtils::videoFilterCaps(); - gst_caps_set_simple( - filter, - "framerate" , GST_TYPE_FRACTION , rate.first, rate.second, - NULL); - caps = gst_caps_intersect(supportedCaps, filter); - gst_caps_unref(filter); - } - gst_caps_unref(supportedCaps); - - //simplify to the list of resolutions only: - caps = gst_caps_make_writable(caps); - for (uint i=0; i<gst_caps_get_size(caps); i++) { - GstStructure *structure = gst_caps_get_structure(caps, i); - gst_structure_set_name(structure, "video/x-raw"); - gst_caps_set_features(caps, i, NULL); - const GValue *oldW = gst_structure_get_value(structure, "width"); - const GValue *oldH = gst_structure_get_value(structure, "height"); - if (!oldW || !oldH) - continue; - - GValue w; - memset(&w, 0, sizeof(GValue)); - GValue h; - memset(&h, 0, sizeof(GValue)); - g_value_init(&w, G_VALUE_TYPE(oldW)); - g_value_init(&h, G_VALUE_TYPE(oldH)); - g_value_copy(oldW, &w); - g_value_copy(oldH, &h); - gst_structure_remove_all_fields(structure); - gst_structure_set_value(structure, "width", &w); - gst_structure_set_value(structure, "height", &h); - g_value_unset(&w); - g_value_unset(&h); - } - - caps = gst_caps_simplify(caps); - - for (uint i=0; i<gst_caps_get_size(caps); i++) { - GstStructure *structure = gst_caps_get_structure(caps, i); - const GValue *wValue = gst_structure_get_value(structure, "width"); - const GValue *hValue = gst_structure_get_value(structure, "height"); - if (!wValue || !hValue) - continue; - - QPair<int,int> wRange = valueRange(wValue, &isContinuous); - QPair<int,int> hRange = valueRange(hValue, &isContinuous); - - QSize minSize(wRange.first, hRange.first); - QSize maxSize(wRange.second, hRange.second); - - if (!minSize.isEmpty()) - res << minSize; - - if (minSize != maxSize && !maxSize.isEmpty()) - res << maxSize; - } - - - std::sort(res.begin(), res.end(), resolutionLessThan); - - //if the range is continuos, populate is with the common rates - if (isContinuous && res.size() >= 2) { - //fill the ragne with common value - static const QList<QSize> commonSizes = - QList<QSize>() << QSize(128, 96) - << QSize(160,120) - << QSize(176, 144) - << QSize(320, 240) - << QSize(352, 288) - << QSize(640, 480) - << QSize(848, 480) - << QSize(854, 480) - << QSize(1024, 768) - << QSize(1280, 720) // HD 720 - << QSize(1280, 1024) - << QSize(1600, 1200) - << QSize(1920, 1080) // HD - << QSize(1920, 1200) - << QSize(2048, 1536) - << QSize(2560, 1600) - << QSize(2580, 1936); - QSize minSize = res.first(); - QSize maxSize = res.last(); - res.clear(); - - for (const QSize &candidate : commonSizes) { - int w = candidate.width(); - int h = candidate.height(); - - if (w > maxSize.width() && h > maxSize.height()) - break; - - if (w >= minSize.width() && h >= minSize.height() && - w <= maxSize.width() && h <= maxSize.height()) - res << candidate; - } - - if (res.isEmpty() || res.first() != minSize) - res.prepend(minSize); - - if (res.last() != maxSize) - res.append(maxSize); - } - -#if CAMERABIN_DEBUG - qDebug() << "Supported resolutions:" << gst_caps_to_string(caps); - qDebug() << res; -#endif - - gst_caps_unref(caps); - - if (continuous) - *continuous = isContinuous; - - return res; -} - -void CameraBinSession::elementAdded(GstBin *, GstElement *element, CameraBinSession *session) -{ - GstElementFactory *factory = gst_element_get_factory(element); - - if (GST_IS_BIN(element)) { - g_signal_connect(G_OBJECT(element), "element-added", G_CALLBACK(elementAdded), session); - g_signal_connect(G_OBJECT(element), "element-removed", G_CALLBACK(elementRemoved), session); - } else if (!factory) { - // no-op - } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER)) { - session->m_audioEncoder = element; - session->m_audioEncodeControl->applySettings(element); - } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER)) { - session->m_videoEncoder = element; - session->m_videoEncodeControl->applySettings(element); - } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_MUXER)) { - session->m_muxer = element; - } -} - -void CameraBinSession::elementRemoved(GstBin *, GstElement *element, CameraBinSession *session) -{ - if (element == session->m_audioEncoder) - session->m_audioEncoder = 0; - else if (element == session->m_videoEncoder) - session->m_videoEncoder = 0; - else if (element == session->m_muxer) - session->m_muxer = 0; -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.h b/src/plugins/gstreamer/camerabin/camerabinsession.h deleted file mode 100644 index ccf0cdd4e..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinsession.h +++ /dev/null @@ -1,280 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CAMERABINCAPTURESESSION_H -#define CAMERABINCAPTURESESSION_H - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include <qmediarecordercontrol.h> - -#include <QtCore/qurl.h> -#include <QtCore/qdir.h> - -#include <gst/gst.h> -#if QT_CONFIG(gstreamer_photography) -#include <gst/interfaces/photography.h> -#endif - -#include <private/qgstreamerbushelper_p.h> -#include <private/qgstreamervideoprobecontrol_p.h> -#include <private/qmediastoragelocation_p.h> -#include "qcamera.h" - -QT_BEGIN_NAMESPACE - -class QGstreamerMessage; -class QGstreamerBusHelper; -class CameraBinControl; -class CameraBinAudioEncoder; -class CameraBinVideoEncoder; -class CameraBinImageEncoder; -class CameraBinRecorder; -class CameraBinContainer; -class CameraBinExposure; -class CameraBinFlash; -class CameraBinFocus; -class CameraBinImageProcessing; -class CameraBinLocks; -class CameraBinZoom; -class CameraBinCaptureDestination; -class CameraBinCaptureBufferFormat; -class QGstreamerVideoRendererInterface; - -class QGstreamerElementFactory -{ -public: - virtual GstElement *buildElement() = 0; -}; - -class CameraBinSession : public QObject, - public QGstreamerBusMessageFilter, - public QGstreamerSyncMessageFilter -{ - Q_OBJECT - Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged) - Q_INTERFACES(QGstreamerBusMessageFilter QGstreamerSyncMessageFilter) -public: - CameraBinSession(GstElementFactory *sourceFactory, QObject *parent); - ~CameraBinSession(); - -#if QT_CONFIG(gstreamer_photography) - GstPhotography *photography(); -#endif - GstElement *cameraBin() { return m_camerabin; } - GstElement *cameraSource() { return m_cameraSrc; } - QGstreamerBusHelper *bus() { return m_busHelper; } - - QList< QPair<int,int> > supportedFrameRates(const QSize &frameSize, bool *continuous) const; - QList<QSize> supportedResolutions(QPair<int,int> rate, bool *continuous, QCamera::CaptureModes mode) const; - - QCamera::CaptureModes captureMode() { return m_captureMode; } - void setCaptureMode(QCamera::CaptureModes mode); - - QUrl outputLocation() const; - bool setOutputLocation(const QUrl& sink); - - GstElement *buildCameraSource(); - GstElementFactory *sourceFactory() const { return m_sourceFactory; } - - CameraBinControl *cameraControl() const { return m_cameraControl; } - CameraBinAudioEncoder *audioEncodeControl() const { return m_audioEncodeControl; } - CameraBinVideoEncoder *videoEncodeControl() const { return m_videoEncodeControl; } - CameraBinImageEncoder *imageEncodeControl() const { return m_imageEncodeControl; } - -#if QT_CONFIG(gstreamer_photography) - CameraBinExposure *cameraExposureControl(); - CameraBinFocus *cameraFocusControl(); -#endif - - CameraBinImageProcessing *imageProcessingControl() const { return m_imageProcessingControl; } - - CameraBinRecorder *recorderControl() const { return m_recorderControl; } - CameraBinContainer *mediaContainerControl() const { return m_mediaContainerControl; } - - QGstreamerElementFactory *audioInput() const { return m_audioInputFactory; } - void setAudioInput(QGstreamerElementFactory *audioInput); - - QGstreamerElementFactory *videoInput() const { return m_videoInputFactory; } - void setVideoInput(QGstreamerElementFactory *videoInput); - bool isReady() const; - - QObject *viewfinder() const { return m_viewfinder; } - void setViewfinder(QObject *viewfinder); - - QList<QCameraViewfinderSettings> supportedViewfinderSettings() const; - QCameraViewfinderSettings viewfinderSettings() const; - void setViewfinderSettings(const QCameraViewfinderSettings &settings) { m_viewfinderSettings = settings; } - - void captureImage(int requestId, const QString &fileName); - - QCamera::Status status() const; - QCamera::State pendingState() const; - bool isBusy() const; - - qint64 duration() const; - - void recordVideo(); - void stopVideoRecording(); - - bool isMuted() const; - - QString device() const { return m_inputDevice; } - - bool processSyncMessage(const QGstreamerMessage &message) override; - bool processBusMessage(const QGstreamerMessage &message) override; - - QGstreamerVideoProbeControl *videoProbe(); - -signals: - void statusChanged(QCamera::Status status); - void pendingStateChanged(QCamera::State state); - void durationChanged(qint64 duration); - void error(int error, const QString &errorString); - void imageExposed(int requestId); - void imageCaptured(int requestId, const QImage &img); - void mutedChanged(bool); - void viewfinderChanged(); - void readyChanged(bool); - void busyChanged(bool); - -public slots: - void setDevice(const QString &device); - void setState(QCamera::State); - void setCaptureDevice(const QString &deviceName); - void setMetaData(const QMap<QByteArray, QVariant>&); - void setMuted(bool); - -private slots: - void handleViewfinderChange(); - void setupCaptureResolution(); - -private: - void load(); - void unload(); - void start(); - void stop(); - - void setStatus(QCamera::Status status); - void setStateHelper(QCamera::State state); - void setError(int error, const QString &errorString); - - bool setupCameraBin(); - void setAudioCaptureCaps(); - GstCaps *supportedCaps(QCamera::CaptureModes mode) const; - static void updateBusyStatus(GObject *o, GParamSpec *p, gpointer d); - - QString currentContainerFormat() const; - - static void elementAdded(GstBin *bin, GstElement *element, CameraBinSession *session); - static void elementRemoved(GstBin *bin, GstElement *element, CameraBinSession *session); - - QUrl m_sink; - QUrl m_actualSink; - bool m_recordingActive; - QString m_captureDevice; - QCamera::Status m_status; - QCamera::State m_pendingState; - QString m_inputDevice; - bool m_muted; - bool m_busy; - QMediaStorageLocation m_mediaStorageLocation; - - QCamera::CaptureModes m_captureMode; - QMap<QByteArray, QVariant> m_metaData; - - QGstreamerElementFactory *m_audioInputFactory; - QGstreamerElementFactory *m_videoInputFactory; - QObject *m_viewfinder; - QGstreamerVideoRendererInterface *m_viewfinderInterface; - mutable QList<QCameraViewfinderSettings> m_supportedViewfinderSettings; - QCameraViewfinderSettings m_viewfinderSettings; - QCameraViewfinderSettings m_actualViewfinderSettings; - - CameraBinControl *m_cameraControl; - CameraBinAudioEncoder *m_audioEncodeControl; - CameraBinVideoEncoder *m_videoEncodeControl; - CameraBinImageEncoder *m_imageEncodeControl; - CameraBinRecorder *m_recorderControl; - CameraBinContainer *m_mediaContainerControl; -#if QT_CONFIG(gstreamer_photography) - CameraBinExposure *m_cameraExposureControl; - CameraBinFocus *m_cameraFocusControl; -#endif - CameraBinImageProcessing *m_imageProcessingControl; - - QGstreamerBusHelper *m_busHelper; - GstBus* m_bus; - GstElement *m_camerabin; - GstElement *m_cameraSrc; - GstElement *m_videoSrc; - GstElement *m_viewfinderElement; - GstElementFactory *m_sourceFactory; - bool m_viewfinderHasChanged; - bool m_inputDeviceHasChanged; - bool m_usingWrapperCameraBinSrc; - - class ViewfinderProbe : public QGstreamerVideoProbeControl { - public: - ViewfinderProbe(CameraBinSession *s) - : QGstreamerVideoProbeControl(s) - , session(s) - {} - - void probeCaps(GstCaps *caps) override; - - private: - CameraBinSession * const session; - } m_viewfinderProbe; - - GstElement *m_audioSrc; - GstElement *m_audioConvert; - GstElement *m_capsFilter; - GstElement *m_fileSink; - GstElement *m_audioEncoder; - GstElement *m_videoEncoder; - GstElement *m_muxer; - -public: - QString m_imageFileName; - int m_requestId; -}; - -QT_END_NAMESPACE - -#endif // CAMERABINCAPTURESESSION_H diff --git a/src/plugins/gstreamer/camerabin/camerabinv4limageprocessing.cpp b/src/plugins/gstreamer/camerabin/camerabinv4limageprocessing.cpp deleted file mode 100644 index 963eb8580..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinv4limageprocessing.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Denis Shienkov <denis.shienkov@gmail.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "camerabinv4limageprocessing.h" -#include "camerabinsession.h" - -#include <QDebug> - -#include <private/qcore_unix_p.h> -#include <linux/videodev2.h> - -QT_BEGIN_NAMESPACE - -CameraBinV4LImageProcessing::CameraBinV4LImageProcessing(CameraBinSession *session) - : QCameraImageProcessingControl(session) - , m_session(session) -{ -} - -CameraBinV4LImageProcessing::~CameraBinV4LImageProcessing() -{ -} - -bool CameraBinV4LImageProcessing::isParameterSupported( - ProcessingParameter parameter) const -{ - return m_parametersInfo.contains(parameter); -} - -bool CameraBinV4LImageProcessing::isParameterValueSupported( - ProcessingParameter parameter, const QVariant &value) const -{ - QMap<ProcessingParameter, SourceParameterValueInfo>::const_iterator sourceValueInfo = - m_parametersInfo.constFind(parameter); - if (sourceValueInfo == m_parametersInfo.constEnd()) - return false; - - switch (parameter) { - - case QCameraImageProcessingControl::WhiteBalancePreset: { - const QCameraImageProcessing::WhiteBalanceMode checkedValue = - value.value<QCameraImageProcessing::WhiteBalanceMode>(); - const QCameraImageProcessing::WhiteBalanceMode firstAllowedValue = - (*sourceValueInfo).minimumValue ? QCameraImageProcessing::WhiteBalanceAuto - : QCameraImageProcessing::WhiteBalanceManual; - const QCameraImageProcessing::WhiteBalanceMode secondAllowedValue = - (*sourceValueInfo).maximumValue ? QCameraImageProcessing::WhiteBalanceAuto - : QCameraImageProcessing::WhiteBalanceManual; - if (checkedValue != firstAllowedValue - && checkedValue != secondAllowedValue) { - return false; - } - } - break; - - case QCameraImageProcessingControl::ColorTemperature: { - const qint32 checkedValue = value.toInt(); - if (checkedValue < (*sourceValueInfo).minimumValue - || checkedValue > (*sourceValueInfo).maximumValue) { - return false; - } - } - break; - - case QCameraImageProcessingControl::ContrastAdjustment: // falling back - case QCameraImageProcessingControl::SaturationAdjustment: // falling back - case QCameraImageProcessingControl::BrightnessAdjustment: // falling back - case QCameraImageProcessingControl::SharpeningAdjustment: { - const qint32 sourceValue = sourceImageProcessingParameterValue( - value.toReal(), (*sourceValueInfo)); - if (sourceValue < (*sourceValueInfo).minimumValue - || sourceValue > (*sourceValueInfo).maximumValue) { - return false; - } - } - break; - - default: - return false; - } - - return true; -} - -QVariant CameraBinV4LImageProcessing::parameter( - ProcessingParameter parameter) const -{ - QMap<ProcessingParameter, SourceParameterValueInfo>::const_iterator sourceValueInfo = - m_parametersInfo.constFind(parameter); - if (sourceValueInfo == m_parametersInfo.constEnd()) { - if (!m_parametersInfo.empty()) - qWarning() << "Unable to get the unsupported parameter:" << parameter; - return QVariant(); - } - - const QString deviceName = m_session->device(); - const int fd = qt_safe_open(deviceName.toLocal8Bit().constData(), O_RDONLY); - if (fd == -1) { - qWarning() << "Unable to open the camera" << deviceName - << "for read to get the parameter value:" << qt_error_string(errno); - return QVariant(); - } - - struct v4l2_control control; - ::memset(&control, 0, sizeof(control)); - control.id = (*sourceValueInfo).cid; - - const bool ret = (::ioctl(fd, VIDIOC_G_CTRL, &control) == 0); - - qt_safe_close(fd); - - if (!ret) { - qWarning() << "Unable to get the parameter value:" << parameter << ":" << qt_error_string(errno); - return QVariant(); - } - - switch (parameter) { - - case QCameraImageProcessingControl::WhiteBalancePreset: - return QVariant::fromValue<QCameraImageProcessing::WhiteBalanceMode>( - control.value ? QCameraImageProcessing::WhiteBalanceAuto - : QCameraImageProcessing::WhiteBalanceManual); - - case QCameraImageProcessingControl::ColorTemperature: - return QVariant::fromValue<qint32>(control.value); - - case QCameraImageProcessingControl::ContrastAdjustment: // falling back - case QCameraImageProcessingControl::SaturationAdjustment: // falling back - case QCameraImageProcessingControl::BrightnessAdjustment: // falling back - case QCameraImageProcessingControl::SharpeningAdjustment: { - return scaledImageProcessingParameterValue( - control.value, (*sourceValueInfo)); - } - - default: - return QVariant(); - } -} - -void CameraBinV4LImageProcessing::setParameter( - ProcessingParameter parameter, const QVariant &value) -{ - QMap<ProcessingParameter, SourceParameterValueInfo>::const_iterator sourceValueInfo = - m_parametersInfo.constFind(parameter); - if (sourceValueInfo == m_parametersInfo.constEnd()) { - if (!m_parametersInfo.empty()) - qWarning() << "Unable to set the unsupported parameter:" << parameter; - return; - } - - const QString deviceName = m_session->device(); - const int fd = qt_safe_open(deviceName.toLocal8Bit().constData(), O_WRONLY); - if (fd == -1) { - qWarning() << "Unable to open the camera" << deviceName - << "for write to set the parameter value:" << qt_error_string(errno); - return; - } - - struct v4l2_control control; - ::memset(&control, 0, sizeof(control)); - control.id = (*sourceValueInfo).cid; - - switch (parameter) { - - case QCameraImageProcessingControl::WhiteBalancePreset: { - const QCameraImageProcessing::WhiteBalanceMode m = - value.value<QCameraImageProcessing::WhiteBalanceMode>(); - if (m != QCameraImageProcessing::WhiteBalanceAuto - && m != QCameraImageProcessing::WhiteBalanceManual) { - qt_safe_close(fd); - return; - } - - control.value = (m == QCameraImageProcessing::WhiteBalanceAuto); - } - break; - - case QCameraImageProcessingControl::ColorTemperature: - control.value = value.toInt(); - break; - - case QCameraImageProcessingControl::ContrastAdjustment: // falling back - case QCameraImageProcessingControl::SaturationAdjustment: // falling back - case QCameraImageProcessingControl::BrightnessAdjustment: // falling back - case QCameraImageProcessingControl::SharpeningAdjustment: - control.value = sourceImageProcessingParameterValue( - value.toReal(), (*sourceValueInfo)); - break; - - default: - qt_safe_close(fd); - return; - } - - if (::ioctl(fd, VIDIOC_S_CTRL, &control) != 0) - qWarning() << "Unable to set the parameter value:" << parameter << ":" << qt_error_string(errno); - - qt_safe_close(fd); -} - -void CameraBinV4LImageProcessing::updateParametersInfo( - QCamera::Status cameraStatus) -{ - if (cameraStatus == QCamera::UnloadedStatus) - m_parametersInfo.clear(); - else if (cameraStatus == QCamera::LoadedStatus) { - const QString deviceName = m_session->device(); - const int fd = qt_safe_open(deviceName.toLocal8Bit().constData(), O_RDONLY); - if (fd == -1) { - qWarning() << "Unable to open the camera" << deviceName - << "for read to query the parameter info:" << qt_error_string(errno); - return; - } - - constexpr struct SupportedParameterEntry { - quint32 cid; - QCameraImageProcessingControl::ProcessingParameter parameter; - } supportedParametersEntries[] = { - { V4L2_CID_AUTO_WHITE_BALANCE, QCameraImageProcessingControl::WhiteBalancePreset }, - { V4L2_CID_WHITE_BALANCE_TEMPERATURE, QCameraImageProcessingControl::ColorTemperature }, - { V4L2_CID_CONTRAST, QCameraImageProcessingControl::ContrastAdjustment }, - { V4L2_CID_SATURATION, QCameraImageProcessingControl::SaturationAdjustment }, - { V4L2_CID_BRIGHTNESS, QCameraImageProcessingControl::BrightnessAdjustment }, - { V4L2_CID_SHARPNESS, QCameraImageProcessingControl::SharpeningAdjustment } - }; - - for (auto supportedParametersEntrie : supportedParametersEntries) { - struct v4l2_queryctrl queryControl; - ::memset(&queryControl, 0, sizeof(queryControl)); - queryControl.id = supportedParametersEntrie.cid; - - if (::ioctl(fd, VIDIOC_QUERYCTRL, &queryControl) != 0) { - qWarning() << "Unable to query the parameter info:" << supportedParametersEntrie.parameter - << ":" << qt_error_string(errno); - continue; - } - - SourceParameterValueInfo sourceValueInfo; - sourceValueInfo.cid = queryControl.id; - sourceValueInfo.defaultValue = queryControl.default_value; - sourceValueInfo.maximumValue = queryControl.maximum; - sourceValueInfo.minimumValue = queryControl.minimum; - - m_parametersInfo.insert(supportedParametersEntrie.parameter, sourceValueInfo); - } - - qt_safe_close(fd); - } -} - -qreal CameraBinV4LImageProcessing::scaledImageProcessingParameterValue( - qint32 sourceValue, const SourceParameterValueInfo &sourceValueInfo) -{ - if (sourceValue == sourceValueInfo.defaultValue) - return 0.0f; - - if (sourceValue < sourceValueInfo.defaultValue) - return ((sourceValue - sourceValueInfo.minimumValue) - / qreal(sourceValueInfo.defaultValue - sourceValueInfo.minimumValue)) - + (-1.0f); - - return ((sourceValue - sourceValueInfo.defaultValue) - / qreal(sourceValueInfo.maximumValue - sourceValueInfo.defaultValue)); -} - -qint32 CameraBinV4LImageProcessing::sourceImageProcessingParameterValue( - qreal scaledValue, const SourceParameterValueInfo &valueRange) -{ - if (qFuzzyIsNull(scaledValue)) - return valueRange.defaultValue; - - if (scaledValue < 0.0f) - return ((scaledValue - (-1.0f)) * (valueRange.defaultValue - valueRange.minimumValue)) - + valueRange.minimumValue; - - return (scaledValue * (valueRange.maximumValue - valueRange.defaultValue)) - + valueRange.defaultValue; -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinv4limageprocessing.h b/src/plugins/gstreamer/camerabin/camerabinv4limageprocessing.h deleted file mode 100644 index a38dc78da..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinv4limageprocessing.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Denis Shienkov <denis.shienkov@gmail.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CAMERABINV4LIMAGEPROCESSINGCONTROL_H -#define CAMERABINV4LIMAGEPROCESSINGCONTROL_H - -#include <qcamera.h> -#include <qcameraimageprocessingcontrol.h> - -QT_BEGIN_NAMESPACE - -class CameraBinSession; - -class CameraBinV4LImageProcessing : public QCameraImageProcessingControl -{ - Q_OBJECT - -public: - CameraBinV4LImageProcessing(CameraBinSession *session); - virtual ~CameraBinV4LImageProcessing(); - - bool isParameterSupported(ProcessingParameter) const override; - bool isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const override; - QVariant parameter(ProcessingParameter parameter) const override; - void setParameter(ProcessingParameter parameter, const QVariant &value) override; - -public slots: - void updateParametersInfo(QCamera::Status cameraStatus); - -private: - struct SourceParameterValueInfo { - SourceParameterValueInfo() - : cid(0) - { - } - - qint32 defaultValue; - qint32 minimumValue; - qint32 maximumValue; - quint32 cid; // V4L control id - }; - - static qreal scaledImageProcessingParameterValue( - qint32 sourceValue, const SourceParameterValueInfo &sourceValueInfo); - static qint32 sourceImageProcessingParameterValue( - qreal scaledValue, const SourceParameterValueInfo &valueRange); -private: - CameraBinSession *m_session; - QMap<ProcessingParameter, SourceParameterValueInfo> m_parametersInfo; -}; - -QT_END_NAMESPACE - -#endif // CAMERABINV4LIMAGEPROCESSINGCONTROL_H diff --git a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp deleted file mode 100644 index 5bba2ddb5..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include "camerabinvideoencoder.h" -#include "camerabinsession.h" -#include "camerabincontainer.h" -#include <private/qgstutils_p.h> - -#include <QtCore/qdebug.h> - -QT_BEGIN_NAMESPACE - -CameraBinVideoEncoder::CameraBinVideoEncoder(CameraBinSession *session) - :QVideoEncoderSettingsControl(session) - , m_session(session) -#if QT_CONFIG(gstreamer_encodingprofiles) - , m_codecs(QGstCodecsInfo::VideoEncoder) -#endif -{ -} - -CameraBinVideoEncoder::~CameraBinVideoEncoder() -{ -} - -QList<QSize> CameraBinVideoEncoder::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const -{ - if (continuous) - *continuous = false; - - QPair<int,int> rate = rateAsRational(settings.frameRate()); - - //select the closest supported rational rate to settings.frameRate() - - return m_session->supportedResolutions(rate, continuous, QCamera::CaptureVideo); -} - -QList< qreal > CameraBinVideoEncoder::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const -{ - if (continuous) - *continuous = false; - - QList< qreal > res; - - const auto rates = m_session->supportedFrameRates(settings.resolution(), continuous); - for (const auto &rate : rates) { - if (rate.second > 0) - res << qreal(rate.first)/rate.second; - } - - return res; -} - -QStringList CameraBinVideoEncoder::supportedVideoCodecs() const -{ -#if QT_CONFIG(gstreamer_encodingprofiles) - return m_codecs.supportedCodecs(); -#else - return QStringList(); -#endif -} - -QString CameraBinVideoEncoder::videoCodecDescription(const QString &codecName) const -{ -#if QT_CONFIG(gstreamer_encodingprofiles) - return m_codecs.codecDescription(codecName); -#else - Q_UNUSED(codecName); - return QString(); -#endif -} - -QVideoEncoderSettings CameraBinVideoEncoder::videoSettings() const -{ - return m_videoSettings; -} - -void CameraBinVideoEncoder::setVideoSettings(const QVideoEncoderSettings &settings) -{ - if (m_videoSettings != settings) { - m_actualVideoSettings = settings; - m_videoSettings = settings; - emit settingsChanged(); - } -} - -QVideoEncoderSettings CameraBinVideoEncoder::actualVideoSettings() const -{ - return m_actualVideoSettings; -} - -void CameraBinVideoEncoder::setActualVideoSettings(const QVideoEncoderSettings &settings) -{ - m_actualVideoSettings = settings; -} - -void CameraBinVideoEncoder::resetActualSettings() -{ - m_actualVideoSettings = m_videoSettings; -} - - -QPair<int,int> CameraBinVideoEncoder::rateAsRational(qreal frameRate) const -{ - if (frameRate > 0.001) { - //convert to rational number - QList<int> denumCandidates; - denumCandidates << 1 << 2 << 3 << 5 << 10 << 25 << 30 << 50 << 100 << 1001 << 1000; - - qreal error = 1.0; - int num = 1; - int denum = 1; - - for (int curDenum : qAsConst(denumCandidates)) { - int curNum = qRound(frameRate*curDenum); - qreal curError = qAbs(qreal(curNum)/curDenum - frameRate); - - if (curError < error) { - error = curError; - num = curNum; - denum = curDenum; - } - - if (curError < 1e-8) - break; - } - - return QPair<int,int>(num,denum); - } - - return QPair<int,int>(); -} - -#if QT_CONFIG(gstreamer_encodingprofiles) - -GstEncodingProfile *CameraBinVideoEncoder::createProfile() -{ - QString codec = m_actualVideoSettings.codec(); - GstCaps *caps = !codec.isEmpty() ? gst_caps_from_string(codec.toLatin1()) : nullptr; - - if (!caps) - return nullptr; - - QString preset = m_actualVideoSettings.encodingOption(QStringLiteral("preset")).toString(); - GstEncodingVideoProfile *profile = gst_encoding_video_profile_new( - caps, - !preset.isEmpty() ? preset.toLatin1().constData() : NULL, //preset - NULL, //restriction - 1); //presence - - gst_caps_unref(caps); - - gst_encoding_video_profile_set_pass(profile, 0); - gst_encoding_video_profile_set_variableframerate(profile, TRUE); - - return (GstEncodingProfile *)profile; -} - -#endif - -void CameraBinVideoEncoder::applySettings(GstElement *encoder) -{ - GObjectClass * const objectClass = G_OBJECT_GET_CLASS(encoder); - const char * const name = qt_gst_element_get_factory_name(encoder); - - const int bitRate = m_actualVideoSettings.bitRate(); - if (bitRate == -1) { - // Bit rate is invalid, don't evaluate the remaining conditions. - } else if (g_object_class_find_property(objectClass, "bitrate")) { - g_object_set(G_OBJECT(encoder), "bitrate", bitRate, NULL); - } else if (g_object_class_find_property(objectClass, "target-bitrate")) { - g_object_set(G_OBJECT(encoder), "target-bitrate", bitRate, NULL); - } - - if (qstrcmp(name, "theoraenc") == 0) { - static const int qualities[] = { 8, 16, 32, 45, 60 }; - g_object_set(G_OBJECT(encoder), "quality", qualities[m_actualVideoSettings.quality()], NULL); - } else if (qstrncmp(name, "avenc_", 6) == 0) { - if (g_object_class_find_property(objectClass, "pass")) { - static const int modes[] = { 0, 2, 512, 1024 }; - g_object_set(G_OBJECT(encoder), "pass", modes[m_actualVideoSettings.encodingMode()], NULL); - } - if (g_object_class_find_property(objectClass, "quantizer")) { - static const double qualities[] = { 20, 8.0, 3.0, 2.5, 2.0 }; - g_object_set(G_OBJECT(encoder), "quantizer", qualities[m_actualVideoSettings.quality()], NULL); - } - } else if (qstrncmp(name, "omx", 3) == 0) { - if (!g_object_class_find_property(objectClass, "control-rate")) { - } else switch (m_actualVideoSettings.encodingMode()) { - case QMultimedia::ConstantBitRateEncoding: - g_object_set(G_OBJECT(encoder), "control-rate", 2, NULL); - break; - case QMultimedia::AverageBitRateEncoding: - g_object_set(G_OBJECT(encoder), "control-rate", 1, NULL); - break; - default: - g_object_set(G_OBJECT(encoder), "control-rate", 0, NULL); - } - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h deleted file mode 100644 index 24013ceab..000000000 --- a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CAMERABINVIDEOENCODE_H -#define CAMERABINVIDEOENCODE_H - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include <qvideoencodersettingscontrol.h> - -#include <QtCore/qstringlist.h> -#include <QtCore/qmap.h> -#include <QtCore/qset.h> - -#include <gst/gst.h> -#include <gst/pbutils/pbutils.h> - -#if QT_CONFIG(gstreamer_encodingprofiles) -#include <gst/pbutils/encoding-profile.h> -#include <private/qgstcodecsinfo_p.h> -#endif - -QT_BEGIN_NAMESPACE - -class CameraBinSession; - -class CameraBinVideoEncoder : public QVideoEncoderSettingsControl -{ - Q_OBJECT -public: - CameraBinVideoEncoder(CameraBinSession *session); - virtual ~CameraBinVideoEncoder(); - - QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings = QVideoEncoderSettings(), - bool *continuous = 0) const override; - - QList< qreal > supportedFrameRates(const QVideoEncoderSettings &settings = QVideoEncoderSettings(), - bool *continuous = 0) const override; - - QPair<int,int> rateAsRational(qreal) const; - - QStringList supportedVideoCodecs() const override; - QString videoCodecDescription(const QString &codecName) const override; - - QVideoEncoderSettings videoSettings() const override; - void setVideoSettings(const QVideoEncoderSettings &settings) override; - - QVideoEncoderSettings actualVideoSettings() const; - void setActualVideoSettings(const QVideoEncoderSettings&); - void resetActualSettings(); - -#if QT_CONFIG(gstreamer_encodingprofiles) - GstEncodingProfile *createProfile(); -#endif - - void applySettings(GstElement *encoder); - -Q_SIGNALS: - void settingsChanged(); - -private: - CameraBinSession *m_session; - -#if QT_CONFIG(gstreamer_encodingprofiles) - QGstCodecsInfo m_codecs; -#endif - - QVideoEncoderSettings m_actualVideoSettings; - QVideoEncoderSettings m_videoSettings; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/gstreamer/common.pri b/src/plugins/gstreamer/common.pri deleted file mode 100644 index 8e5c381ae..000000000 --- a/src/plugins/gstreamer/common.pri +++ /dev/null @@ -1,12 +0,0 @@ -QT += core-private multimedia-private network - -qtHaveModule(widgets) { - QT += widgets multimediawidgets-private - DEFINES += HAVE_WIDGETS -} - -QMAKE_USE += gstreamer - -qtConfig(gstreamer_app): \ - QMAKE_USE += gstreamer_app - diff --git a/src/plugins/gstreamer/gstreamer.json b/src/plugins/gstreamer/gstreamer.json deleted file mode 100644 index 0656cce4f..000000000 --- a/src/plugins/gstreamer/gstreamer.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["gstreamer"], - "Services": ["org.qt-project.qt.mediaplayer", "org.qt-project.qt.audiosource", "org.qt-project.qt.camera", "org.qt-project.qt.audiodecode"] -} diff --git a/src/plugins/gstreamer/gstreamer.pro b/src/plugins/gstreamer/gstreamer.pro deleted file mode 100644 index 5fb8f83c6..000000000 --- a/src/plugins/gstreamer/gstreamer.pro +++ /dev/null @@ -1,10 +0,0 @@ -TEMPLATE = subdirs - -SUBDIRS += \ - audiodecoder \ - camerabin \ - mediaplayer \ - mediacapture - -OTHER_FILES += \ - gstreamer.json diff --git a/src/plugins/gstreamer/mediacapture/CMakeLists.txt b/src/plugins/gstreamer/mediacapture/CMakeLists.txt deleted file mode 100644 index 763d9a3c9..000000000 --- a/src/plugins/gstreamer/mediacapture/CMakeLists.txt +++ /dev/null @@ -1,61 +0,0 @@ -# Generated from mediacapture.pro. - -##################################################################### -## QGstreamerCaptureServicePlugin Plugin: -##################################################################### - -qt_internal_add_plugin(QGstreamerCaptureServicePlugin - OUTPUT_NAME gstmediacapture - TYPE mediaservice - SOURCES - qgstreameraudioencode.cpp qgstreameraudioencode.h - qgstreamercameracontrol.cpp qgstreamercameracontrol.h - qgstreamercapturemetadatacontrol.cpp qgstreamercapturemetadatacontrol.h - qgstreamercaptureservice.cpp qgstreamercaptureservice.h - qgstreamercaptureserviceplugin.cpp qgstreamercaptureserviceplugin.h - qgstreamercapturesession.cpp qgstreamercapturesession.h - qgstreamerimagecapturecontrol.cpp qgstreamerimagecapturecontrol.h - qgstreamerimageencode.cpp qgstreamerimageencode.h - qgstreamermediacontainercontrol.cpp qgstreamermediacontainercontrol.h - qgstreamerrecordercontrol.cpp qgstreamerrecordercontrol.h - qgstreamervideoencode.cpp qgstreamervideoencode.h - INCLUDE_DIRECTORIES - ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC_LIBRARIES - Qt::Core - Qt::CorePrivate - Qt::Gui - Qt::MultimediaPrivate - Qt::Network - gstreamer - Qt::MultimediaPrivate -) - -## Scopes: -##################################################################### - -qt_internal_extend_target(QGstreamerCaptureServicePlugin CONDITION QT_FEATURE_linux_v4l AND use_gstreamer_camera - SOURCES - qgstreamerv4l2input.cpp qgstreamerv4l2input.h - DEFINES - USE_GSTREAMER_CAMERA -) - -#### Keys ignored in scope 2:.:.:mediacapture.pro:use_gstreamer_camera AND QT_FEATURE_linux_v4l: -# OTHER_FILES = "mediacapturecamera.json" - -#### Keys ignored in scope 3:.:.:mediacapture.pro:else: -# OTHER_FILES = "mediacapture.json" - -qt_internal_extend_target(QGstreamerCaptureServicePlugin CONDITION TARGET Qt::Widgets - DEFINES - HAVE_WIDGETS - PUBLIC_LIBRARIES - Qt::MultimediaWidgetsPrivate - Qt::Widgets -) - -qt_internal_extend_target(QGstreamerCaptureServicePlugin CONDITION QT_FEATURE_gstreamer_app - PUBLIC_LIBRARIES - gstreamer_app -) diff --git a/src/plugins/gstreamer/mediacapture/mediacapture.json b/src/plugins/gstreamer/mediacapture/mediacapture.json deleted file mode 100644 index 68ca3f55b..000000000 --- a/src/plugins/gstreamer/mediacapture/mediacapture.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["gstreamermediacapture"], - "Services": ["org.qt-project.qt.audiosource"] -} diff --git a/src/plugins/gstreamer/mediacapture/mediacapture.pro b/src/plugins/gstreamer/mediacapture/mediacapture.pro deleted file mode 100644 index c2982b199..000000000 --- a/src/plugins/gstreamer/mediacapture/mediacapture.pro +++ /dev/null @@ -1,52 +0,0 @@ -TARGET = gstmediacapture - -include(../common.pri) - -INCLUDEPATH += $$PWD - -HEADERS += $$PWD/qgstreamercaptureservice.h \ - $$PWD/qgstreamercapturesession.h \ - $$PWD/qgstreameraudioencode.h \ - $$PWD/qgstreamervideoencode.h \ - $$PWD/qgstreamerrecordercontrol.h \ - $$PWD/qgstreamermediacontainercontrol.h \ - $$PWD/qgstreamercameracontrol.h \ - $$PWD/qgstreamercapturemetadatacontrol.h \ - $$PWD/qgstreamerimagecapturecontrol.h \ - $$PWD/qgstreamerimageencode.h \ - $$PWD/qgstreamercaptureserviceplugin.h - -SOURCES += $$PWD/qgstreamercaptureservice.cpp \ - $$PWD/qgstreamercapturesession.cpp \ - $$PWD/qgstreameraudioencode.cpp \ - $$PWD/qgstreamervideoencode.cpp \ - $$PWD/qgstreamerrecordercontrol.cpp \ - $$PWD/qgstreamermediacontainercontrol.cpp \ - $$PWD/qgstreamercameracontrol.cpp \ - $$PWD/qgstreamercapturemetadatacontrol.cpp \ - $$PWD/qgstreamerimagecapturecontrol.cpp \ - $$PWD/qgstreamerimageencode.cpp \ - $$PWD/qgstreamercaptureserviceplugin.cpp - -# Camera usage with gstreamer needs to have -CONFIG += use_gstreamer_camera - -use_gstreamer_camera:qtConfig(linux_v4l) { - DEFINES += USE_GSTREAMER_CAMERA - - OTHER_FILES += \ - mediacapturecamera.json - - HEADERS += \ - $$PWD/qgstreamerv4l2input.h - SOURCES += \ - $$PWD/qgstreamerv4l2input.cpp - -} else { - OTHER_FILES += \ - mediacapture.json -} - -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = QGstreamerCaptureServicePlugin -load(qt_plugin) diff --git a/src/plugins/gstreamer/mediacapture/mediacapturecamera.json b/src/plugins/gstreamer/mediacapture/mediacapturecamera.json deleted file mode 100644 index f5fba17e6..000000000 --- a/src/plugins/gstreamer/mediacapture/mediacapturecamera.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["gstreamermediacapture"], - "Services": ["org.qt-project.qt.audiosource", "org.qt-project.qt.camera"] -} diff --git a/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp b/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp deleted file mode 100644 index 957d8c1d4..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreameraudioencode.h" -#include "qgstreamercapturesession.h" -#include "qgstreamermediacontainercontrol.h" -#include <private/qgstutils_p.h> - -#include <QtCore/qdebug.h> - -#include <math.h> - -QGstreamerAudioEncode::QGstreamerAudioEncode(QObject *parent) - :QAudioEncoderSettingsControl(parent) - , m_codecs(QGstCodecsInfo::AudioEncoder) -{ -} - -QGstreamerAudioEncode::~QGstreamerAudioEncode() -{ -} - -QStringList QGstreamerAudioEncode::supportedAudioCodecs() const -{ - return m_codecs.supportedCodecs(); -} - -QString QGstreamerAudioEncode::codecDescription(const QString &codecName) const -{ - return m_codecs.codecDescription(codecName); -} - -QStringList QGstreamerAudioEncode::supportedEncodingOptions(const QString &codec) const -{ - return m_codecs.codecOptions(codec); -} - -QVariant QGstreamerAudioEncode::encodingOption( - const QString &codec, const QString &name) const -{ - return m_options[codec].value(name); -} - -void QGstreamerAudioEncode::setEncodingOption( - const QString &codec, const QString &name, const QVariant &value) -{ - m_options[codec][name] = value; -} - -QList<int> QGstreamerAudioEncode::supportedSampleRates(const QAudioEncoderSettings &, bool *) const -{ - //TODO check element caps to find actual values - - return QList<int>(); -} - -QAudioEncoderSettings QGstreamerAudioEncode::audioSettings() const -{ - return m_audioSettings; -} - -void QGstreamerAudioEncode::setAudioSettings(const QAudioEncoderSettings &settings) -{ - m_audioSettings = settings; -} - - -GstElement *QGstreamerAudioEncode::createEncoder() -{ - QString codec = m_audioSettings.codec(); - GstElement *encoderElement = gst_element_factory_make(m_codecs.codecElement(codec).constData(), NULL); - if (!encoderElement) - return 0; - - GstBin * encoderBin = GST_BIN(gst_bin_new("audio-encoder-bin")); - - GstElement *sinkCapsFilter = gst_element_factory_make("capsfilter", NULL); - GstElement *srcCapsFilter = gst_element_factory_make("capsfilter", NULL); - - gst_bin_add_many(encoderBin, sinkCapsFilter, encoderElement, srcCapsFilter, NULL); - gst_element_link_many(sinkCapsFilter, encoderElement, srcCapsFilter, NULL); - - // add ghostpads - GstPad *pad = gst_element_get_static_pad(sinkCapsFilter, "sink"); - gst_element_add_pad(GST_ELEMENT(encoderBin), gst_ghost_pad_new("sink", pad)); - gst_object_unref(GST_OBJECT(pad)); - - pad = gst_element_get_static_pad(srcCapsFilter, "src"); - gst_element_add_pad(GST_ELEMENT(encoderBin), gst_ghost_pad_new("src", pad)); - gst_object_unref(GST_OBJECT(pad)); - - if (m_audioSettings.sampleRate() > 0 || m_audioSettings.channelCount() > 0) { - GstCaps *caps = gst_caps_new_empty(); - GstStructure *structure = qt_gst_structure_new_empty("audio/x-raw"); - - if (m_audioSettings.sampleRate() > 0) - gst_structure_set(structure, "rate", G_TYPE_INT, m_audioSettings.sampleRate(), NULL ); - - if (m_audioSettings.channelCount() > 0) - gst_structure_set(structure, "channels", G_TYPE_INT, m_audioSettings.channelCount(), NULL ); - - gst_caps_append_structure(caps,structure); - - g_object_set(G_OBJECT(sinkCapsFilter), "caps", caps, NULL); - - gst_caps_unref(caps); - } - - // Some encoders support several codecs. Setting a caps filter downstream with the desired - // codec (which is actually a string representation of the caps) will make sure we use the - // correct codec. - GstCaps *caps = gst_caps_from_string(codec.toUtf8().constData()); - g_object_set(G_OBJECT(srcCapsFilter), "caps", caps, NULL); - gst_caps_unref(caps); - - if (encoderElement) { - if (m_audioSettings.encodingMode() == QMultimedia::ConstantQualityEncoding) { - QMultimedia::EncodingQuality qualityValue = m_audioSettings.quality(); - - if (codec == QLatin1String("audio/x-vorbis")) { - double qualityTable[] = { - 0.1, //VeryLow - 0.3, //Low - 0.5, //Normal - 0.7, //High - 1.0 //VeryHigh - }; - g_object_set(G_OBJECT(encoderElement), "quality", qualityTable[qualityValue], NULL); - } else if (codec == QLatin1String("audio/mpeg")) { - g_object_set(G_OBJECT(encoderElement), "target", 0, NULL); //constant quality mode - qreal quality[] = { - 1, //VeryLow - 3, //Low - 5, //Normal - 7, //High - 9 //VeryHigh - }; - g_object_set(G_OBJECT(encoderElement), "quality", quality[qualityValue], NULL); - } else if (codec == QLatin1String("audio/x-speex")) { - //0-10 range with default 8 - double qualityTable[] = { - 2, //VeryLow - 5, //Low - 8, //Normal - 9, //High - 10 //VeryHigh - }; - g_object_set(G_OBJECT(encoderElement), "quality", qualityTable[qualityValue], NULL); - } else if (codec.startsWith("audio/AMR")) { - int band[] = { - 0, //VeryLow - 2, //Low - 4, //Normal - 6, //High - 7 //VeryHigh - }; - - g_object_set(G_OBJECT(encoderElement), "band-mode", band[qualityValue], NULL); - } - } else { - int bitrate = m_audioSettings.bitRate(); - if (bitrate > 0) { - if (codec == QLatin1String("audio/mpeg")) { - g_object_set(G_OBJECT(encoderElement), "target", 1, NULL); //constant bitrate mode - } - g_object_set(G_OBJECT(encoderElement), "bitrate", bitrate, NULL); - } - } - - QMap<QString, QVariant> options = m_options.value(codec); - for (auto it = options.cbegin(), end = options.cend(); it != end; ++it) { - const QString &option = it.key(); - const QVariant &value = it.value(); - - switch (value.typeId()) { - case QMetaType::Int: - g_object_set(G_OBJECT(encoderElement), option.toLatin1(), value.toInt(), NULL); - break; - case QMetaType::Bool: - g_object_set(G_OBJECT(encoderElement), option.toLatin1(), value.toBool(), NULL); - break; - case QMetaType::Double: - g_object_set(G_OBJECT(encoderElement), option.toLatin1(), value.toDouble(), NULL); - break; - case QMetaType::QString: - g_object_set(G_OBJECT(encoderElement), option.toLatin1(), value.toString().toUtf8().constData(), NULL); - break; - default: - qWarning() << "unsupported option type:" << option << value; - break; - } - - } - } - - return GST_ELEMENT(encoderBin); -} - - -QSet<QString> QGstreamerAudioEncode::supportedStreamTypes(const QString &codecName) const -{ - return m_codecs.supportedStreamTypes(codecName); -} diff --git a/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.h b/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.h deleted file mode 100644 index 0cfbb4e91..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERAUDIOENCODE_H -#define QGSTREAMERAUDIOENCODE_H - -#include <qaudioencodersettingscontrol.h> - -#include <QtCore/qstringlist.h> -#include <QtCore/qmap.h> -#include <QtCore/qset.h> - -#include <gst/gst.h> - -#include <qaudioformat.h> -#include <private/qgstcodecsinfo_p.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerCaptureSession; - -class QGstreamerAudioEncode : public QAudioEncoderSettingsControl -{ - Q_OBJECT -public: - QGstreamerAudioEncode(QObject *parent); - virtual ~QGstreamerAudioEncode(); - - QStringList supportedAudioCodecs() const override; - QString codecDescription(const QString &codecName) const override; - - QStringList supportedEncodingOptions(const QString &codec) const; - QVariant encodingOption(const QString &codec, const QString &name) const; - void setEncodingOption(const QString &codec, const QString &name, const QVariant &value); - - QList<int> supportedSampleRates(const QAudioEncoderSettings &settings = QAudioEncoderSettings(), - bool *isContinuous = 0) const override; - QList<int> supportedChannelCounts(const QAudioEncoderSettings &settings = QAudioEncoderSettings()) const; - QList<int> supportedSampleSizes(const QAudioEncoderSettings &settings = QAudioEncoderSettings()) const; - - QAudioEncoderSettings audioSettings() const override; - void setAudioSettings(const QAudioEncoderSettings &) override; - - GstElement *createEncoder(); - - QSet<QString> supportedStreamTypes(const QString &codecName) const; - -private: - QGstCodecsInfo m_codecs; - - QMap<QString, QMap<QString, QVariant> > m_options; - - QAudioEncoderSettings m_audioSettings; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercameracontrol.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercameracontrol.cpp deleted file mode 100644 index 5afbdd7cf..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamercameracontrol.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamercameracontrol.h" -#include "qgstreamerimageencode.h" - -#include <QtCore/qdebug.h> -#include <QtCore/qfile.h> - - -QGstreamerCameraControl::QGstreamerCameraControl(QGstreamerCaptureSession *session) - :QCameraControl(session), - m_captureMode(QCamera::CaptureStillImage), - m_session(session), - m_state(QCamera::UnloadedState), - m_status(QCamera::UnloadedStatus), - m_reloadPending(false) - -{ - connect(m_session, SIGNAL(stateChanged(QGstreamerCaptureSession::State)), - this, SLOT(updateStatus())); - - connect(m_session->imageEncodeControl(), SIGNAL(settingsChanged()), - SLOT(reloadLater())); - connect(m_session, SIGNAL(viewfinderChanged()), - SLOT(reloadLater())); - connect(m_session, SIGNAL(readyChanged(bool)), - SLOT(reloadLater())); - - m_session->setCaptureMode(QGstreamerCaptureSession::Image); -} - -QGstreamerCameraControl::~QGstreamerCameraControl() -{ -} - -void QGstreamerCameraControl::setCaptureMode(QCamera::CaptureModes mode) -{ - if (m_captureMode == mode || !isCaptureModeSupported(mode)) - return; - - m_captureMode = mode; - - switch (mode) { - case QCamera::CaptureViewfinder: - case QCamera::CaptureStillImage: - m_session->setCaptureMode(QGstreamerCaptureSession::Image); - break; - case QCamera::CaptureVideo: - m_session->setCaptureMode(QGstreamerCaptureSession::AudioAndVideo); - break; - case QCamera::CaptureVideo | QCamera::CaptureStillImage: - m_session->setCaptureMode(QGstreamerCaptureSession::AudioAndVideoAndImage); - break; - } - - emit captureModeChanged(mode); - updateStatus(); - reloadLater(); -} - -bool QGstreamerCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const -{ - //only CaptureStillImage and CaptureVideo bits are allowed - return (mode & (QCamera::CaptureStillImage | QCamera::CaptureVideo)) == mode; -} - -void QGstreamerCameraControl::setState(QCamera::State state) -{ - if (m_state == state) - return; - - m_state = state; - switch (state) { - case QCamera::UnloadedState: - case QCamera::LoadedState: - m_session->setState(QGstreamerCaptureSession::StoppedState); - break; - case QCamera::ActiveState: - //postpone changing to Active if the session is nor ready yet - if (m_session->isReady()) { - m_session->setState(QGstreamerCaptureSession::PreviewState); - } else { -#ifdef CAMEABIN_DEBUG - qDebug() << "Camera session is not ready yet, postpone activating"; -#endif - } - break; - } - - updateStatus(); - emit stateChanged(m_state); -} - -QCamera::State QGstreamerCameraControl::state() const -{ - return m_state; -} - -void QGstreamerCameraControl::updateStatus() -{ - QCamera::Status oldStatus = m_status; - - switch (m_state) { - case QCamera::UnloadedState: - m_status = QCamera::UnloadedStatus; - break; - case QCamera::LoadedState: - m_status = QCamera::LoadedStatus; - break; - case QCamera::ActiveState: - if (m_session->state() == QGstreamerCaptureSession::StoppedState) - m_status = QCamera::StartingStatus; - else - m_status = QCamera::ActiveStatus; - break; - } - - if (oldStatus != m_status) { - //qDebug() << "Status changed:" << m_status; - emit statusChanged(m_status); - } -} - -void QGstreamerCameraControl::reloadLater() -{ - //qDebug() << "reload pipeline requested"; - if (!m_reloadPending && m_state == QCamera::ActiveState) { - m_reloadPending = true; - m_session->setState(QGstreamerCaptureSession::StoppedState); - QMetaObject::invokeMethod(this, "reloadPipeline", Qt::QueuedConnection); - } -} - -void QGstreamerCameraControl::reloadPipeline() -{ - //qDebug() << "reload pipeline"; - if (m_reloadPending) { - m_reloadPending = false; - if (m_state == QCamera::ActiveState && m_session->isReady()) { - m_session->setState(QGstreamerCaptureSession::PreviewState); - } - } -} - -bool QGstreamerCameraControl::canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const -{ - Q_UNUSED(status); - - switch (changeType) { - case QCameraControl::CaptureMode: - case QCameraControl::ImageEncodingSettings: - case QCameraControl::VideoEncodingSettings: - case QCameraControl::Viewfinder: - return true; - default: - return false; - } -} diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercameracontrol.h b/src/plugins/gstreamer/mediacapture/qgstreamercameracontrol.h deleted file mode 100644 index dd082c031..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamercameracontrol.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QGSTREAMERCAMERACONTROL_H -#define QGSTREAMERCAMERACONTROL_H - -#include <QHash> -#include <qcameracontrol.h> -#include "qgstreamercapturesession.h" - -QT_BEGIN_NAMESPACE - -class QGstreamerCameraControl : public QCameraControl -{ - Q_OBJECT -public: - QGstreamerCameraControl( QGstreamerCaptureSession *session ); - virtual ~QGstreamerCameraControl(); - - bool isValid() const { return true; } - - QCamera::State state() const override; - void setState(QCamera::State state) override; - - QCamera::Status status() const override { return m_status; } - - QCamera::CaptureModes captureMode() const override { return m_captureMode; } - void setCaptureMode(QCamera::CaptureModes mode) override; - - bool isCaptureModeSupported(QCamera::CaptureModes mode) const override; - - bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const override; - - QCamera::LockTypes supportedLocks() const override - { - return QCamera::NoLock; - } - - QCamera::LockStatus lockStatus(QCamera::LockType /*lock*/) const override { return QCamera::Unlocked; } - - void searchAndLock(QCamera::LockTypes /*locks*/) override {} - void unlock(QCamera::LockTypes /*locks*/) override {} - - - QList<QCameraViewfinderSettings> supportedViewfinderSettings() const override { return {}; } - - QCameraViewfinderSettings viewfinderSettings() const override { return {}; } - void setViewfinderSettings(const QCameraViewfinderSettings &/*settings*/) override {} - -public slots: - void reloadLater(); - -private slots: - void updateStatus(); - void reloadPipeline(); - - -private: - QCamera::CaptureModes m_captureMode; - QGstreamerCaptureSession *m_session; - QCamera::State m_state; - QCamera::Status m_status; - bool m_reloadPending; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERCAMERACONTROL_H diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturemetadatacontrol.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercapturemetadatacontrol.cpp deleted file mode 100644 index 6139c57bf..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamercapturemetadatacontrol.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamercapturemetadatacontrol.h" - -#include <QtMultimedia/qmediametadata.h> - -#include <gst/gst.h> -#include <gst/gstversion.h> - - -typedef QMap<QString, QByteArray> QGstreamerMetaDataKeyLookup; -Q_GLOBAL_STATIC(QGstreamerMetaDataKeyLookup, metadataKeys) - -static const QGstreamerMetaDataKeyLookup *qt_gstreamerMetaDataKeys() -{ - if (metadataKeys->isEmpty()) { - metadataKeys->insert(QMediaMetaData::Title, GST_TAG_TITLE); - metadataKeys->insert(QMediaMetaData::SubTitle, 0); - //metadataKeys->insert(QMediaMetaData::Author, 0); - metadataKeys->insert(QMediaMetaData::Comment, GST_TAG_COMMENT); - metadataKeys->insert(QMediaMetaData::Description, GST_TAG_DESCRIPTION); - //metadataKeys->insert(QMediaMetaData::Category, 0); - metadataKeys->insert(QMediaMetaData::Genre, GST_TAG_GENRE); - //metadataKeys->insert(QMediaMetaData::Year, 0); - //metadataKeys->insert(QMediaMetaData::UserRating, 0); - - metadataKeys->insert(QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE); - - metadataKeys->insert(QMediaMetaData::Publisher, GST_TAG_ORGANIZATION); - metadataKeys->insert(QMediaMetaData::Copyright, GST_TAG_COPYRIGHT); - //metadataKeys->insert(QMediaMetaData::ParentalRating, 0); - //metadataKeys->insert(QMediaMetaData::RatingOrganisation, 0); - - // Media - //metadataKeys->insert(QMediaMetaData::Size, 0); - //metadataKeys->insert(QMediaMetaData::MediaType, 0); - metadataKeys->insert(QMediaMetaData::Duration, GST_TAG_DURATION); - - // Audio - metadataKeys->insert(QMediaMetaData::AudioBitRate, GST_TAG_BITRATE); - metadataKeys->insert(QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC); - //metadataKeys->insert(QMediaMetaData::ChannelCount, 0); - //metadataKeys->insert(QMediaMetaData::SampleRate, 0); - - // Music - metadataKeys->insert(QMediaMetaData::AlbumTitle, GST_TAG_ALBUM); - metadataKeys->insert(QMediaMetaData::AlbumArtist, GST_TAG_ARTIST); - metadataKeys->insert(QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER); - metadataKeys->insert(QMediaMetaData::Composer, GST_TAG_COMPOSER); - //metadataKeys->insert(QMediaMetaData::Conductor, 0); - //metadataKeys->insert(QMediaMetaData::Lyrics, 0); - //metadataKeys->insert(QMediaMetaData::Mood, 0); - metadataKeys->insert(QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER); - - //metadataKeys->insert(QMediaMetaData::CoverArtUrlSmall, 0); - //metadataKeys->insert(QMediaMetaData::CoverArtUrlLarge, 0); - - // Image/Video - //metadataKeys->insert(QMediaMetaData::Resolution, 0); - //metadataKeys->insert(QMediaMetaData::PixelAspectRatio, 0); - - // Video - //metadataKeys->insert(QMediaMetaData::VideoFrameRate, 0); - //metadataKeys->insert(QMediaMetaData::VideoBitRate, 0); - metadataKeys->insert(QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC); - - //metadataKeys->insert(QMediaMetaData::PosterUrl, 0); - - // Movie - //metadataKeys->insert(QMediaMetaData::ChapterNumber, 0); - //metadataKeys->insert(QMediaMetaData::Director, 0); - metadataKeys->insert(QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER); - //metadataKeys->insert(QMediaMetaData::Writer, 0); - - // Photos - //metadataKeys->insert(QMediaMetaData::CameraManufacturer, 0); - //metadataKeys->insert(QMediaMetaData::CameraModel, 0); - //metadataKeys->insert(QMediaMetaData::Event, 0); - //metadataKeys->insert(QMediaMetaData::Subject, 0 } - } - - return metadataKeys; -} - -QGstreamerCaptureMetaDataControl::QGstreamerCaptureMetaDataControl(QObject *parent) - :QMetaDataWriterControl(parent) -{ -} - -QVariant QGstreamerCaptureMetaDataControl::metaData(const QString &key) const -{ - QGstreamerMetaDataKeyLookup::const_iterator it = qt_gstreamerMetaDataKeys()->find(key); - if (it != qt_gstreamerMetaDataKeys()->constEnd()) - return m_values.value(it.value()); - - return QVariant(); -} - -void QGstreamerCaptureMetaDataControl::setMetaData(const QString &key, const QVariant &value) -{ - QGstreamerMetaDataKeyLookup::const_iterator it = qt_gstreamerMetaDataKeys()->find(key); - if (it != qt_gstreamerMetaDataKeys()->constEnd()) { - m_values.insert(it.value(), value); - - emit QMetaDataWriterControl::metaDataChanged(); - emit QMetaDataWriterControl::metaDataChanged(key, value); - emit metaDataChanged(m_values); - } -} - -QStringList QGstreamerCaptureMetaDataControl::availableMetaData() const -{ - QStringList res; - for (auto it = m_values.keyBegin(), end = m_values.keyEnd(); it != end; ++it) { - QString tag = qt_gstreamerMetaDataKeys()->key(*it); - if (!tag.isEmpty()) - res.append(tag); - } - - return res; -} diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturemetadatacontrol.h b/src/plugins/gstreamer/mediacapture/qgstreamercapturemetadatacontrol.h deleted file mode 100644 index 33782d1b6..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamercapturemetadatacontrol.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERCAPTUREMETADATACONTROL_H -#define QGSTREAMERCAPTUREMETADATACONTROL_H - -#include <qmetadatawritercontrol.h> -#include <qvariant.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerCaptureMetaDataControl : public QMetaDataWriterControl -{ - Q_OBJECT -public: - QGstreamerCaptureMetaDataControl(QObject *parent); - ~QGstreamerCaptureMetaDataControl() {} - - - bool isMetaDataAvailable() const override { return true; } - bool isWritable() const override { return true; } - - QVariant metaData(const QString &key) const override; - void setMetaData(const QString &key, const QVariant &value) override; - QStringList availableMetaData() const override; - -Q_SIGNALS: - void metaDataChanged(const QMap<QByteArray, QVariant>&); - -private: - QMap<QByteArray, QVariant> m_values; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERCAPTUREMETADATACONTROL_H diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp deleted file mode 100644 index b7695852b..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamercaptureservice.h" -#include "qgstreamercapturesession.h" -#include "qgstreamerrecordercontrol.h" -#include "qgstreamermediacontainercontrol.h" -#include "qgstreameraudioencode.h" -#include "qgstreamervideoencode.h" -#include "qgstreamerimageencode.h" -#include "qgstreamercameracontrol.h" -#include <private/qgstreamerbushelper_p.h> -#include "qgstreamercapturemetadatacontrol.h" - -#if defined(USE_GSTREAMER_CAMERA) -#include "qgstreamerv4l2input.h" -#endif - -#include "qgstreamerimagecapturecontrol.h" -#include <private/qgstreameraudioinputselector_p.h> -#include <private/qgstreamervideoinputdevicecontrol_p.h> -#include <private/qgstreameraudioprobecontrol_p.h> - -#include <private/qgstreamervideorenderer_p.h> -#include <private/qgstreamervideowindow_p.h> - -#if defined(HAVE_WIDGETS) -#include <private/qgstreamervideowidget_p.h> -#endif - -#include <qmediaserviceproviderplugin.h> - -QT_BEGIN_NAMESPACE - -QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObject *parent) - : QMediaService(parent) - , m_captureSession(0) - , m_cameraControl(0) -#if defined(USE_GSTREAMER_CAMERA) - , m_videoInput(0) -#endif - , m_metaDataControl(0) - , m_audioInputSelector(0) - , m_videoInputDevice(0) - , m_videoOutput(0) - , m_videoRenderer(0) - , m_videoWindow(0) -#if defined(HAVE_WIDGETS) - , m_videoWidgetControl(0) -#endif - , m_imageCaptureControl(0) - , m_audioProbeControl(0) -{ - if (service == Q_MEDIASERVICE_AUDIOSOURCE) { - m_captureSession = new QGstreamerCaptureSession(QGstreamerCaptureSession::Audio, this); - } - -#if defined(USE_GSTREAMER_CAMERA) - if (service == Q_MEDIASERVICE_CAMERA) { - m_captureSession = new QGstreamerCaptureSession(QGstreamerCaptureSession::AudioAndVideo, this); - m_cameraControl = new QGstreamerCameraControl(m_captureSession); - m_videoInput = new QGstreamerV4L2Input(this); - m_captureSession->setVideoInput(m_videoInput); - m_videoInputDevice = new QGstreamerVideoInputDeviceControl(this); - - connect(m_videoInputDevice, SIGNAL(selectedDeviceChanged(QString)), - m_videoInput, SLOT(setDevice(QString))); - - if (m_videoInputDevice->deviceCount()) - m_videoInput->setDevice(m_videoInputDevice->deviceName(m_videoInputDevice->selectedDevice())); - - m_videoRenderer = new QGstreamerVideoRenderer(this); - - m_videoWindow = new QGstreamerVideoWindow(this); - // If the GStreamer video sink is not available, don't provide the video window control since - // it won't work anyway. - if (!m_videoWindow->videoSink()) { - delete m_videoWindow; - m_videoWindow = 0; - } - -#if defined(HAVE_WIDGETS) - m_videoWidgetControl = new QGstreamerVideoWidgetControl(this); - - // If the GStreamer video sink is not available, don't provide the video widget control since - // it won't work anyway. QVideoWidget will fall back to QVideoRendererControl in that case. - if (!m_videoWidgetControl->videoSink()) { - delete m_videoWidgetControl; - m_videoWidgetControl = 0; - } -#endif - m_imageCaptureControl = new QGstreamerImageCaptureControl(m_captureSession); - } -#endif - - m_audioInputSelector = new QGstreamerAudioInputSelector(this); - connect(m_audioInputSelector, SIGNAL(activeInputChanged(QString)), m_captureSession, SLOT(setCaptureDevice(QString))); - - if (m_captureSession && m_audioInputSelector->availableInputs().size() > 0) - m_captureSession->setCaptureDevice(m_audioInputSelector->defaultInput()); - - m_metaDataControl = new QGstreamerCaptureMetaDataControl(this); - connect(m_metaDataControl, SIGNAL(metaDataChanged(QMap<QByteArray,QVariant>)), - m_captureSession, SLOT(setMetaData(QMap<QByteArray,QVariant>))); -} - -QGstreamerCaptureService::~QGstreamerCaptureService() -{ -} - -QObject *QGstreamerCaptureService::requestControl(const char *name) -{ - if (!m_captureSession) - return 0; - - if (qstrcmp(name,QAudioInputSelectorControl_iid) == 0) - return m_audioInputSelector; - - if (qstrcmp(name,QVideoDeviceSelectorControl_iid) == 0) - return m_videoInputDevice; - - if (qstrcmp(name,QMediaRecorderControl_iid) == 0) - return m_captureSession->recorderControl(); - - if (qstrcmp(name,QAudioEncoderSettingsControl_iid) == 0) - return m_captureSession->audioEncodeControl(); - - if (qstrcmp(name,QVideoEncoderSettingsControl_iid) == 0) - return m_captureSession->videoEncodeControl(); - - if (qstrcmp(name,QImageEncoderControl_iid) == 0) - return m_captureSession->imageEncodeControl(); - - - if (qstrcmp(name,QMediaContainerControl_iid) == 0) - return m_captureSession->mediaContainerControl(); - - if (qstrcmp(name,QCameraControl_iid) == 0) - return m_cameraControl; - - if (qstrcmp(name,QMetaDataWriterControl_iid) == 0) - return m_metaDataControl; - - if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) - return m_imageCaptureControl; - - if (qstrcmp(name,QMediaAudioProbeControl_iid) == 0) { - if (!m_audioProbeControl) { - m_audioProbeControl = new QGstreamerAudioProbeControl(this); - m_captureSession->addProbe(m_audioProbeControl); - } - m_audioProbeControl->ref.ref(); - return m_audioProbeControl; - } - - if (!m_videoOutput) { - if (qstrcmp(name, QVideoRendererControl_iid) == 0) { - m_videoOutput = m_videoRenderer; - } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) { - m_videoOutput = m_videoWindow; - } -#if defined(HAVE_WIDGETS) - else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) { - m_videoOutput = m_videoWidgetControl; - } -#endif - - if (m_videoOutput) { - m_captureSession->setVideoPreview(m_videoOutput); - return m_videoOutput; - } - } - - return 0; -} - -void QGstreamerCaptureService::releaseControl(QObject *control) -{ - if (!control) { - return; - } else if (control == m_videoOutput) { - m_videoOutput = 0; - m_captureSession->setVideoPreview(0); - } else if (control == m_audioProbeControl && !m_audioProbeControl->ref.deref()) { - m_captureSession->removeProbe(m_audioProbeControl); - delete m_audioProbeControl; - m_audioProbeControl = 0; - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h deleted file mode 100644 index a2be9c190..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERCAPTURESERVICE_H -#define QGSTREAMERCAPTURESERVICE_H - -#include <qmediaservice.h> - -#include <gst/gst.h> - -QT_BEGIN_NAMESPACE -class QAudioInputSelectorControl; -class QVideoDeviceSelectorControl; - -class QGstreamerAudioProbeControl; -class QGstreamerCaptureSession; -class QGstreamerCameraControl; -class QGstreamerMessage; -class QGstreamerBusHelper; -class QGstreamerVideoRenderer; -class QGstreamerVideoWindow; -class QGstreamerVideoWidgetControl; -class QGstreamerElementFactory; -class QGstreamerCaptureMetaDataControl; -class QGstreamerImageCaptureControl; -class QGstreamerV4L2Input; - -class QGstreamerCaptureService : public QMediaService -{ - Q_OBJECT - -public: - QGstreamerCaptureService(const QString &service, QObject *parent = 0); - virtual ~QGstreamerCaptureService(); - - QObject *requestControl(const char *name) override; - void releaseControl(QObject *) override; - -private: - void setAudioPreview(GstElement *); - - QGstreamerCaptureSession *m_captureSession; - QGstreamerCameraControl *m_cameraControl; -#if defined(USE_GSTREAMER_CAMERA) - QGstreamerV4L2Input *m_videoInput; -#endif - QGstreamerCaptureMetaDataControl *m_metaDataControl; - - QAudioInputSelectorControl *m_audioInputSelector; - QVideoDeviceSelectorControl *m_videoInputDevice; - - QObject *m_videoOutput; - - QGstreamerVideoRenderer *m_videoRenderer; - QGstreamerVideoWindow *m_videoWindow; -#if defined(HAVE_WIDGETS) - QGstreamerVideoWidgetControl *m_videoWidgetControl; -#endif - QGstreamerImageCaptureControl *m_imageCaptureControl; - - QGstreamerAudioProbeControl *m_audioProbeControl; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERCAPTURESERVICE_H diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp deleted file mode 100644 index 31f6c871c..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qstring.h> -#include <QtCore/qdebug.h> -#include <QtCore/QDir> -#include <QtCore/QDebug> - -#include "qgstreamercaptureserviceplugin.h" - -//#define QT_SUPPORTEDMIMETYPES_DEBUG - -#include "qgstreamercaptureservice.h" -#include <private/qgstutils_p.h> - -QMediaService* QGstreamerCaptureServicePlugin::create(const QString &key) -{ - QGstUtils::initializeGst(); - - if (key == QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE)) - return new QGstreamerCaptureService(key); - -#if defined(USE_GSTREAMER_CAMERA) - if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)) - return new QGstreamerCaptureService(key); -#endif - - qWarning() << "Gstreamer capture service plugin: unsupported key:" << key; - return 0; -} - -void QGstreamerCaptureServicePlugin::release(QMediaService *service) -{ - delete service; -} - -#if defined(USE_GSTREAMER_CAMERA) -QByteArray QGstreamerCaptureServicePlugin::defaultDevice(const QByteArray &service) const -{ - return service == Q_MEDIASERVICE_CAMERA - ? QGstUtils::enumerateCameras().value(0).name.toUtf8() - : QByteArray(); -} - -QList<QByteArray> QGstreamerCaptureServicePlugin::devices(const QByteArray &service) const -{ - return service == Q_MEDIASERVICE_CAMERA ? QGstUtils::cameraDevices() : QList<QByteArray>(); -} - -QString QGstreamerCaptureServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) -{ - return service == Q_MEDIASERVICE_CAMERA ? QGstUtils::cameraDescription(device) : QString(); -} - -QVariant QGstreamerCaptureServicePlugin::deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property) -{ - Q_UNUSED(service); - Q_UNUSED(device); - Q_UNUSED(property); - return QVariant(); -} - -#endif - -QMultimedia::SupportEstimate QGstreamerCaptureServicePlugin::hasSupport(const QString &mimeType, - const QStringList& codecs) const -{ - if (m_supportedMimeTypeSet.isEmpty()) - updateSupportedMimeTypes(); - - return QGstUtils::hasSupport(mimeType, codecs, m_supportedMimeTypeSet); -} - - -static bool isEncoderOrMuxer(GstElementFactory *factory) -{ - return gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_MUXER) - || gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_ENCODER); -} - -void QGstreamerCaptureServicePlugin::updateSupportedMimeTypes() const -{ - m_supportedMimeTypeSet = QGstUtils::supportedMimeTypes(isEncoderOrMuxer); -} - -QStringList QGstreamerCaptureServicePlugin::supportedMimeTypes() const -{ - return QStringList(); -} - diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.h b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.h deleted file mode 100644 index 0acc01257..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QGSTREAMERCAPTURESERVICEPLUGIN_H -#define QGSTREAMERCAPTURESERVICEPLUGIN_H - -#include <qmediaserviceproviderplugin.h> -#include <QtCore/qset.h> -#include <QtCore/QObject> - -QT_BEGIN_NAMESPACE - -class QGstreamerCaptureServicePlugin - : public QMediaServiceProviderPlugin -#if defined(USE_GSTREAMER_CAMERA) - , public QMediaServiceSupportedDevicesInterface -#endif - , public QMediaServiceSupportedFormatsInterface -{ - Q_OBJECT -#if defined(USE_GSTREAMER_CAMERA) - Q_INTERFACES(QMediaServiceSupportedDevicesInterface) -#endif - Q_INTERFACES(QMediaServiceSupportedFormatsInterface) -#if defined(USE_GSTREAMER_CAMERA) - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "mediacapturecamera.json") -#else - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "mediacapture.json") -#endif -public: - QMediaService* create(const QString &key) override; - void release(QMediaService *service) override; - -#if defined(USE_GSTREAMER_CAMERA) - QByteArray defaultDevice(const QByteArray &service) const override; - QList<QByteArray> devices(const QByteArray &service) const override; - QString deviceDescription(const QByteArray &service, const QByteArray &device) override; - QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property); -#endif - - QMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList &codecs) const override; - QStringList supportedMimeTypes() const override; - -private: - void updateSupportedMimeTypes() const; - - mutable QSet<QString> m_supportedMimeTypeSet; //for fast access -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERCAPTURESERVICEPLUGIN_H diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp deleted file mode 100644 index 6cc282637..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp +++ /dev/null @@ -1,1020 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamercapturesession.h" -#include "qgstreamerrecordercontrol.h" -#include "qgstreamermediacontainercontrol.h" -#include "qgstreameraudioencode.h" -#include "qgstreamervideoencode.h" -#include "qgstreamerimageencode.h" -#include <qmediarecorder.h> -#include <private/qgstreamervideorendererinterface_p.h> -#include <private/qgstreameraudioprobecontrol_p.h> -#include <private/qgstreamerbushelper_p.h> -#include <private/qgstutils_p.h> - -#include <gst/gsttagsetter.h> -#include <gst/gstversion.h> -#include <gst/video/video.h> - -#include <QtCore/qdebug.h> -#include <QtCore/qurl.h> -#include <QtCore/qset.h> -#include <QCoreApplication> -#include <QtCore/qmetaobject.h> -#include <QtCore/qfile.h> -#include <QtGui/qimage.h> - -QT_BEGIN_NAMESPACE - -QGstreamerCaptureSession::QGstreamerCaptureSession(QGstreamerCaptureSession::CaptureMode captureMode, QObject *parent) - :QObject(parent), - m_state(StoppedState), - m_pendingState(StoppedState), - m_waitingForEos(false), - m_pipelineMode(EmptyPipeline), - m_captureMode(captureMode), - m_audioProbe(0), - m_audioInputFactory(0), - m_audioPreviewFactory(0), - m_videoInputFactory(0), - m_viewfinder(0), - m_viewfinderInterface(0), - m_audioSrc(0), - m_audioTee(0), - m_audioPreviewQueue(0), - m_audioPreview(0), - m_audioVolume(0), - m_muted(false), - m_volume(1.0), - m_videoSrc(0), - m_videoTee(0), - m_videoPreviewQueue(0), - m_videoPreview(0), - m_imageCaptureBin(0), - m_encodeBin(0), - m_passImage(false), - m_passPrerollImage(false) -{ - m_pipeline = gst_pipeline_new("media-capture-pipeline"); - qt_gst_object_ref_sink(m_pipeline); - - m_bus = gst_element_get_bus(m_pipeline); - m_busHelper = new QGstreamerBusHelper(m_bus, this); - m_busHelper->installMessageFilter(this); - - m_audioEncodeControl = new QGstreamerAudioEncode(this); - m_videoEncodeControl = new QGstreamerVideoEncode(this); - m_imageEncodeControl = new QGstreamerImageEncode(this); - m_recorderControl = new QGstreamerRecorderControl(this); - connect(m_recorderControl, &QGstreamerRecorderControl::error, [](int e, const QString &str) { - qWarning() << QMediaRecorder::Error(e) << ":" << str.toLatin1().constData(); - }); - m_mediaContainerControl = new QGstreamerMediaContainerControl(this); -} - -QGstreamerCaptureSession::~QGstreamerCaptureSession() -{ - setState(StoppedState); - gst_element_set_state(m_pipeline, GST_STATE_NULL); - gst_object_unref(GST_OBJECT(m_bus)); - gst_object_unref(GST_OBJECT(m_pipeline)); -} - -void QGstreamerCaptureSession::setCaptureMode(CaptureMode mode) -{ - m_captureMode = mode; -} - -GstElement *QGstreamerCaptureSession::buildEncodeBin() -{ - GstElement *encodeBin = gst_bin_new("encode-bin"); - - GstElement *muxer = gst_element_factory_make( m_mediaContainerControl->formatElementName().constData(), "muxer"); - if (!muxer) { - qWarning() << "Could not create a media muxer element:" << m_mediaContainerControl->formatElementName(); - gst_object_unref(encodeBin); - return 0; - } - - // Output location was rejected in setOutputlocation() if not a local file - QUrl actualSink = QUrl::fromLocalFile(QDir::currentPath()).resolved(m_sink); - GstElement *fileSink = gst_element_factory_make("filesink", "filesink"); - g_object_set(G_OBJECT(fileSink), "location", QFile::encodeName(actualSink.toLocalFile()).constData(), NULL); - gst_bin_add_many(GST_BIN(encodeBin), muxer, fileSink, NULL); - - if (!gst_element_link(muxer, fileSink)) { - gst_object_unref(encodeBin); - return 0; - } - - if (m_captureMode & Audio) { - GstElement *audioConvert = gst_element_factory_make("audioconvert", "audioconvert"); - GstElement *audioQueue = gst_element_factory_make("queue", "audio-encode-queue"); - m_audioVolume = gst_element_factory_make("volume", "volume"); - gst_bin_add_many(GST_BIN(encodeBin), audioConvert, audioQueue, m_audioVolume, NULL); - - GstElement *audioEncoder = m_audioEncodeControl->createEncoder(); - if (!audioEncoder) { - gst_object_unref(encodeBin); - qWarning() << "Could not create an audio encoder element:" << m_audioEncodeControl->audioSettings().codec(); - return 0; - } - - gst_bin_add(GST_BIN(encodeBin), audioEncoder); - - if (!gst_element_link_many(audioConvert, audioQueue, m_audioVolume, audioEncoder, muxer, NULL)) { - m_audioVolume = 0; - gst_object_unref(encodeBin); - return 0; - } - - g_object_set(G_OBJECT(m_audioVolume), "mute", m_muted, NULL); - g_object_set(G_OBJECT(m_audioVolume), "volume", m_volume, NULL); - - // add ghostpads - GstPad *pad = gst_element_get_static_pad(audioConvert, "sink"); - gst_element_add_pad(GST_ELEMENT(encodeBin), gst_ghost_pad_new("audiosink", pad)); - gst_object_unref(GST_OBJECT(pad)); - } - - if (m_captureMode & Video) { - GstElement *videoQueue = gst_element_factory_make("queue", "video-encode-queue"); - GstElement *colorspace = gst_element_factory_make("videoconvert", "videoconvert-encoder"); - GstElement *videoscale = gst_element_factory_make("videoscale","videoscale-encoder"); - gst_bin_add_many(GST_BIN(encodeBin), videoQueue, colorspace, videoscale, NULL); - - GstElement *videoEncoder = m_videoEncodeControl->createEncoder(); - if (!videoEncoder) { - gst_object_unref(encodeBin); - qWarning() << "Could not create a video encoder element:" << m_videoEncodeControl->videoSettings().codec(); - return 0; - } - - gst_bin_add(GST_BIN(encodeBin), videoEncoder); - - if (!gst_element_link_many(videoQueue, colorspace, videoscale, videoEncoder, muxer, NULL)) { - gst_object_unref(encodeBin); - return 0; - } - - // add ghostpads - GstPad *pad = gst_element_get_static_pad(videoQueue, "sink"); - gst_element_add_pad(GST_ELEMENT(encodeBin), gst_ghost_pad_new("videosink", pad)); - gst_object_unref(GST_OBJECT(pad)); - } - - return encodeBin; -} - -GstElement *QGstreamerCaptureSession::buildAudioSrc() -{ - GstElement *audioSrc = 0; - if (m_audioInputFactory) - audioSrc = m_audioInputFactory->buildElement(); - else { - QString elementName = "alsasrc"; - QString device; - - if (m_captureDevice.startsWith("alsa:")) { - device = m_captureDevice.mid(QString("alsa:").length()); - } else if (m_captureDevice.startsWith("oss:")) { - elementName = "osssrc"; - device = m_captureDevice.mid(QString("oss:").length()); - } else if (m_captureDevice.startsWith("pulseaudio:")) { - elementName = "pulsesrc"; - } else { - elementName = "autoaudiosrc"; - } - - audioSrc = gst_element_factory_make(elementName.toLatin1().constData(), "audio_src"); - if (audioSrc && !device.isEmpty()) - g_object_set(G_OBJECT(audioSrc), "device", device.toLocal8Bit().constData(), NULL); - } - - if (!audioSrc) { - emit error(int(QMediaRecorder::ResourceError), tr("Could not create an audio source element")); - audioSrc = gst_element_factory_make("fakesrc", NULL); - } - - return audioSrc; -} - -GstElement *QGstreamerCaptureSession::buildAudioPreview() -{ - GstElement *previewElement = 0; - - if (m_audioPreviewFactory) { - previewElement = m_audioPreviewFactory->buildElement(); - } else { - - -#if 1 - previewElement = gst_element_factory_make("fakesink", "audio-preview"); -#else - GstElement *bin = gst_bin_new("audio-preview-bin"); - GstElement *visual = gst_element_factory_make("libvisual_lv_scope", "audio-preview"); - GstElement *sink = gst_element_factory_make("ximagesink", NULL); - gst_bin_add_many(GST_BIN(bin), visual, sink, NULL); - gst_element_link_many(visual,sink, NULL); - - - // add ghostpads - GstPad *pad = gst_element_get_static_pad(visual, "sink"); - Q_ASSERT(pad); - gst_element_add_pad(GST_ELEMENT(bin), gst_ghost_pad_new("audiosink", pad)); - gst_object_unref(GST_OBJECT(pad)); - - previewElement = bin; -#endif - } - - return previewElement; -} - -GstElement *QGstreamerCaptureSession::buildVideoSrc() -{ - GstElement *videoSrc = 0; - if (m_videoInputFactory) { - videoSrc = m_videoInputFactory->buildElement(); - } else { - videoSrc = gst_element_factory_make("videotestsrc", "video_test_src"); - //videoSrc = gst_element_factory_make("v4l2src", "video_test_src"); - } - - return videoSrc; -} - -GstElement *QGstreamerCaptureSession::buildVideoPreview() -{ - GstElement *previewElement = 0; - - if (m_viewfinderInterface) { - GstElement *bin = gst_bin_new("video-preview-bin"); - GstElement *colorspace = gst_element_factory_make("videoconvert", "videoconvert-preview"); - GstElement *capsFilter = gst_element_factory_make("capsfilter", "capsfilter-video-preview"); - GstElement *preview = m_viewfinderInterface->videoSink(); - - gst_bin_add_many(GST_BIN(bin), colorspace, capsFilter, preview, NULL); - gst_element_link(colorspace,capsFilter); - gst_element_link(capsFilter,preview); - - QSize resolution; - qreal frameRate = 0; - - if (m_captureMode & Video) { - QVideoEncoderSettings videoSettings = m_videoEncodeControl->videoSettings(); - resolution = videoSettings.resolution(); - frameRate = videoSettings.frameRate(); - } else if (m_captureMode & Image) { - resolution = m_imageEncodeControl->imageSettings().resolution(); - } - - GstCaps *caps = QGstUtils::videoFilterCaps(); - - if (!resolution.isEmpty()) { - gst_caps_set_simple(caps, "width", G_TYPE_INT, resolution.width(), NULL); - gst_caps_set_simple(caps, "height", G_TYPE_INT, resolution.height(), NULL); - } - if (frameRate > 0.001) { - QPair<int,int> rate = m_videoEncodeControl->rateAsRational(); - - //qDebug() << "frame rate:" << num << denum; - - gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, rate.first, rate.second, NULL); - } - - //qDebug() << "set video preview caps filter:" << gst_caps_to_string(caps); - - g_object_set(G_OBJECT(capsFilter), "caps", caps, NULL); - - gst_caps_unref(caps); - - // add ghostpads - GstPad *pad = gst_element_get_static_pad(colorspace, "sink"); - Q_ASSERT(pad); - gst_element_add_pad(GST_ELEMENT(bin), gst_ghost_pad_new("videosink", pad)); - gst_object_unref(GST_OBJECT(pad)); - - previewElement = bin; - } else { -#if 1 - previewElement = gst_element_factory_make("fakesink", "video-preview"); -#else - GstElement *bin = gst_bin_new("video-preview-bin"); - GstElement *colorspace = gst_element_factory_make("videoconvert", "videoconvert-preview"); - GstElement *preview = gst_element_factory_make("ximagesink", "video-preview"); - gst_bin_add_many(GST_BIN(bin), colorspace, preview, NULL); - gst_element_link(colorspace,preview); - - // add ghostpads - GstPad *pad = gst_element_get_static_pad(colorspace, "sink"); - Q_ASSERT(pad); - gst_element_add_pad(GST_ELEMENT(bin), gst_ghost_pad_new("videosink", pad)); - gst_object_unref(GST_OBJECT(pad)); - - previewElement = bin; -#endif - } - - return previewElement; -} - -void QGstreamerCaptureSession::probeCaps(GstCaps *caps) -{ - gst_video_info_from_caps(&m_previewInfo, caps); -} - -bool QGstreamerCaptureSession::probeBuffer(GstBuffer *buffer) -{ - if (m_passPrerollImage) { - m_passImage = false; - m_passPrerollImage = false; - - return true; - } else if (!m_passImage) { - return false; - } - - m_passImage = false; - - QImage img = QGstUtils::bufferToImage(buffer, m_previewInfo); - - if (img.isNull()) - return true; - - static QMetaMethod exposedSignal = QMetaMethod::fromSignal(&QGstreamerCaptureSession::imageExposed); - exposedSignal.invoke(this, - Qt::QueuedConnection, - Q_ARG(int,m_imageRequestId)); - - static QMetaMethod capturedSignal = QMetaMethod::fromSignal(&QGstreamerCaptureSession::imageCaptured); - capturedSignal.invoke(this, - Qt::QueuedConnection, - Q_ARG(int,m_imageRequestId), - Q_ARG(QImage,img)); - - return true; -} - -static gboolean saveImageFilter(GstElement *element, - GstBuffer *buffer, - GstPad *pad, - void *appdata) -{ - Q_UNUSED(element); - Q_UNUSED(pad); - QGstreamerCaptureSession *session = (QGstreamerCaptureSession *)appdata; - - QString fileName = session->m_imageFileName; - - if (!fileName.isEmpty()) { - QFile f(fileName); - if (f.open(QFile::WriteOnly)) { - GstMapInfo info; - if (gst_buffer_map(buffer, &info, GST_MAP_READ)) { - f.write(reinterpret_cast<const char *>(info.data), info.size); - gst_buffer_unmap(buffer, &info); - } - f.close(); - - static QMetaMethod savedSignal = QMetaMethod::fromSignal(&QGstreamerCaptureSession::imageSaved); - savedSignal.invoke(session, - Qt::QueuedConnection, - Q_ARG(int,session->m_imageRequestId), - Q_ARG(QString,fileName)); - } - } - - return TRUE; -} - -GstElement *QGstreamerCaptureSession::buildImageCapture() -{ - GstElement *bin = gst_bin_new("image-capture-bin"); - GstElement *queue = gst_element_factory_make("queue", "queue-image-capture"); - GstElement *colorspace = gst_element_factory_make("videoconvert", "videoconvert-image-capture"); - GstElement *encoder = gst_element_factory_make("jpegenc", "image-encoder"); - GstElement *sink = gst_element_factory_make("fakesink","sink-image-capture"); - - GstPad *pad = gst_element_get_static_pad(queue, "src"); - Q_ASSERT(pad); - - addProbeToPad(pad, false); - - gst_object_unref(GST_OBJECT(pad)); - - g_object_set(G_OBJECT(sink), "signal-handoffs", TRUE, NULL); - g_signal_connect(G_OBJECT(sink), "handoff", G_CALLBACK(saveImageFilter), this); - - gst_bin_add_many(GST_BIN(bin), queue, colorspace, encoder, sink, NULL); - gst_element_link_many(queue, colorspace, encoder, sink, NULL); - - // add ghostpads - pad = gst_element_get_static_pad(queue, "sink"); - Q_ASSERT(pad); - gst_element_add_pad(GST_ELEMENT(bin), gst_ghost_pad_new("imagesink", pad)); - gst_object_unref(GST_OBJECT(pad)); - - m_passImage = false; - m_passPrerollImage = true; - m_imageFileName = QString(); - - return bin; -} - -void QGstreamerCaptureSession::captureImage(int requestId, const QString &fileName) -{ - m_imageRequestId = requestId; - m_imageFileName = fileName; - m_passImage = true; -} - - -#define REMOVE_ELEMENT(element) { if (element) {gst_bin_remove(GST_BIN(m_pipeline), element); element = 0;} } -#define UNREF_ELEMENT(element) { if (element) { gst_object_unref(GST_OBJECT(element)); element = 0; } } - -bool QGstreamerCaptureSession::rebuildGraph(QGstreamerCaptureSession::PipelineMode newMode) -{ - removeAudioBufferProbe(); - REMOVE_ELEMENT(m_audioSrc); - REMOVE_ELEMENT(m_audioPreview); - REMOVE_ELEMENT(m_audioPreviewQueue); - REMOVE_ELEMENT(m_audioTee); - REMOVE_ELEMENT(m_videoSrc); - REMOVE_ELEMENT(m_videoPreview); - REMOVE_ELEMENT(m_videoPreviewQueue); - REMOVE_ELEMENT(m_videoTee); - REMOVE_ELEMENT(m_encodeBin); - REMOVE_ELEMENT(m_imageCaptureBin); - m_audioVolume = 0; - - bool ok = true; - - switch (newMode) { - case EmptyPipeline: - break; - case PreviewPipeline: - if (m_captureMode & Audio) { - m_audioSrc = buildAudioSrc(); - m_audioPreview = buildAudioPreview(); - - ok &= m_audioSrc && m_audioPreview; - - if (ok) { - gst_bin_add_many(GST_BIN(m_pipeline), m_audioSrc, m_audioPreview, NULL); - ok &= gst_element_link(m_audioSrc, m_audioPreview); - } else { - UNREF_ELEMENT(m_audioSrc); - UNREF_ELEMENT(m_audioPreview); - } - } - if (m_captureMode & Video || m_captureMode & Image) { - m_videoSrc = buildVideoSrc(); - m_videoTee = gst_element_factory_make("tee", "video-preview-tee"); - m_videoPreviewQueue = gst_element_factory_make("queue", "video-preview-queue"); - m_videoPreview = buildVideoPreview(); - m_imageCaptureBin = buildImageCapture(); - - ok &= m_videoSrc && m_videoTee && m_videoPreviewQueue && m_videoPreview && m_imageCaptureBin; - - if (ok) { - gst_bin_add_many(GST_BIN(m_pipeline), m_videoSrc, m_videoTee, - m_videoPreviewQueue, m_videoPreview, - m_imageCaptureBin, NULL); - - ok &= gst_element_link(m_videoSrc, m_videoTee); - ok &= gst_element_link(m_videoTee, m_videoPreviewQueue); - ok &= gst_element_link(m_videoPreviewQueue, m_videoPreview); - ok &= gst_element_link(m_videoTee, m_imageCaptureBin); - } else { - UNREF_ELEMENT(m_videoSrc); - UNREF_ELEMENT(m_videoTee); - UNREF_ELEMENT(m_videoPreviewQueue); - UNREF_ELEMENT(m_videoPreview); - UNREF_ELEMENT(m_imageCaptureBin); - } - } - break; - case RecordingPipeline: - m_encodeBin = buildEncodeBin(); - gst_bin_add(GST_BIN(m_pipeline), m_encodeBin); - - if (m_captureMode & Audio) { - m_audioSrc = buildAudioSrc(); - ok &= m_audioSrc != 0; - - gst_bin_add(GST_BIN(m_pipeline), m_audioSrc); - ok &= gst_element_link(m_audioSrc, m_encodeBin); - } - - if (m_captureMode & Video) { - m_videoSrc = buildVideoSrc(); - ok &= m_videoSrc != 0; - - gst_bin_add(GST_BIN(m_pipeline), m_videoSrc); - ok &= gst_element_link(m_videoSrc, m_encodeBin); - } - - if (!m_metaData.isEmpty()) - setMetaData(m_metaData); - - break; - case PreviewAndRecordingPipeline: - m_encodeBin = buildEncodeBin(); - if (m_encodeBin) - gst_bin_add(GST_BIN(m_pipeline), m_encodeBin); - - ok &= m_encodeBin != 0; - - if (ok && m_captureMode & Audio) { - m_audioSrc = buildAudioSrc(); - m_audioPreview = buildAudioPreview(); - m_audioTee = gst_element_factory_make("tee", NULL); - m_audioPreviewQueue = gst_element_factory_make("queue", NULL); - - ok &= m_audioSrc && m_audioPreview && m_audioTee && m_audioPreviewQueue; - - if (ok) { - gst_bin_add_many(GST_BIN(m_pipeline), m_audioSrc, m_audioTee, - m_audioPreviewQueue, m_audioPreview, NULL); - ok &= gst_element_link(m_audioSrc, m_audioTee); - ok &= gst_element_link(m_audioTee, m_audioPreviewQueue); - ok &= gst_element_link(m_audioPreviewQueue, m_audioPreview); - ok &= gst_element_link(m_audioTee, m_encodeBin); - } else { - UNREF_ELEMENT(m_audioSrc); - UNREF_ELEMENT(m_audioPreview); - UNREF_ELEMENT(m_audioTee); - UNREF_ELEMENT(m_audioPreviewQueue); - } - } - - if (ok && (m_captureMode & Video || m_captureMode & Image)) { - m_videoSrc = buildVideoSrc(); - m_videoPreview = buildVideoPreview(); - m_videoTee = gst_element_factory_make("tee", NULL); - m_videoPreviewQueue = gst_element_factory_make("queue", NULL); - - ok &= m_videoSrc && m_videoPreview && m_videoTee && m_videoPreviewQueue; - - if (ok) { - gst_bin_add_many(GST_BIN(m_pipeline), m_videoSrc, m_videoTee, - m_videoPreviewQueue, m_videoPreview, NULL); - ok &= gst_element_link(m_videoSrc, m_videoTee); - ok &= gst_element_link(m_videoTee, m_videoPreviewQueue); - ok &= gst_element_link(m_videoPreviewQueue, m_videoPreview); - } else { - UNREF_ELEMENT(m_videoSrc); - UNREF_ELEMENT(m_videoTee); - UNREF_ELEMENT(m_videoPreviewQueue); - UNREF_ELEMENT(m_videoPreview); - } - - if (ok && (m_captureMode & Video)) - ok &= gst_element_link(m_videoTee, m_encodeBin); - } - - if (!m_metaData.isEmpty()) - setMetaData(m_metaData); - - - break; - } - - if (!ok) { - emit error(int(QMediaRecorder::FormatError),tr("Failed to build media capture pipeline.")); - } - - dumpGraph( QString("rebuild_graph_%1_%2").arg(m_pipelineMode).arg(newMode) ); -#ifdef QT_GST_CAPTURE_DEBUG - if (m_encodeBin) { - QString fileName = QString("rebuild_graph_encode_%1_%2").arg(m_pipelineMode).arg(newMode); - GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(m_encodeBin), GST_DEBUG_GRAPH_SHOW_ALL, fileName.toLatin1()); - } -#endif - - if (ok) { - addAudioBufferProbe(); - m_pipelineMode = newMode; - } else { - m_pipelineMode = EmptyPipeline; - - REMOVE_ELEMENT(m_audioSrc); - REMOVE_ELEMENT(m_audioPreview); - REMOVE_ELEMENT(m_audioPreviewQueue); - REMOVE_ELEMENT(m_audioTee); - REMOVE_ELEMENT(m_videoSrc); - REMOVE_ELEMENT(m_videoPreview); - REMOVE_ELEMENT(m_videoPreviewQueue); - REMOVE_ELEMENT(m_videoTee); - REMOVE_ELEMENT(m_encodeBin); - } - - return ok; -} - -void QGstreamerCaptureSession::dumpGraph(const QString &fileName) -{ -#ifdef QT_GST_CAPTURE_DEBUG - GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(m_pipeline), - GstDebugGraphDetails(/*GST_DEBUG_GRAPH_SHOW_ALL |*/ GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES), - fileName.toLatin1()); -#else - Q_UNUSED(fileName); -#endif -} - -QUrl QGstreamerCaptureSession::outputLocation() const -{ - return m_sink; -} - -bool QGstreamerCaptureSession::setOutputLocation(const QUrl& sink) -{ - if (!sink.isRelative() && !sink.isLocalFile()) { - qWarning("Output location must be a local file"); - return false; - } - - m_sink = sink; - return true; -} - -void QGstreamerCaptureSession::setAudioInput(QGstreamerElementFactory *audioInput) -{ - m_audioInputFactory = audioInput; -} - -void QGstreamerCaptureSession::setAudioPreview(QGstreamerElementFactory *audioPreview) -{ - m_audioPreviewFactory = audioPreview; -} - -void QGstreamerCaptureSession::setVideoInput(QGstreamerVideoInput *videoInput) -{ - m_videoInputFactory = videoInput; -} - -void QGstreamerCaptureSession::setVideoPreview(QObject *viewfinder) -{ - m_viewfinderInterface = qobject_cast<QGstreamerVideoRendererInterface*>(viewfinder); - if (!m_viewfinderInterface) - viewfinder = 0; - - if (m_viewfinder != viewfinder) { - bool oldReady = isReady(); - - if (m_viewfinder) { - disconnect(m_viewfinder, SIGNAL(sinkChanged()), - this, SIGNAL(viewfinderChanged())); - disconnect(m_viewfinder, SIGNAL(readyChanged(bool)), - this, SIGNAL(readyChanged(bool))); - - m_busHelper->removeMessageFilter(m_viewfinder); - } - - m_viewfinder = viewfinder; - //m_viewfinderHasChanged = true; - - if (m_viewfinder) { - connect(m_viewfinder, SIGNAL(sinkChanged()), - this, SIGNAL(viewfinderChanged())); - connect(m_viewfinder, SIGNAL(readyChanged(bool)), - this, SIGNAL(readyChanged(bool))); - - m_busHelper->installMessageFilter(m_viewfinder); - } - - emit viewfinderChanged(); - if (oldReady != isReady()) - emit readyChanged(isReady()); - } -} - -bool QGstreamerCaptureSession::isReady() const -{ - //it's possible to use QCamera without any viewfinder attached - return !m_viewfinderInterface || m_viewfinderInterface->isReady(); -} - -QGstreamerCaptureSession::State QGstreamerCaptureSession::state() const -{ - return m_state; -} - -QGstreamerCaptureSession::State QGstreamerCaptureSession::pendingState() const -{ - return m_pendingState; -} - -void QGstreamerCaptureSession::setState(QGstreamerCaptureSession::State newState) -{ - if (newState == m_pendingState && !m_waitingForEos) - return; - - m_pendingState = newState; - - PipelineMode newMode = EmptyPipeline; - - switch (newState) { - case PausedState: - case RecordingState: - newMode = PreviewAndRecordingPipeline; - break; - case PreviewState: - newMode = PreviewPipeline; - break; - case StoppedState: - newMode = EmptyPipeline; - break; - } - - if (newMode != m_pipelineMode) { - if (m_pipelineMode == PreviewAndRecordingPipeline) { - if (!m_waitingForEos) { - m_waitingForEos = true; - //qDebug() << "Waiting for EOS"; - // Unless gstreamer is in GST_STATE_PLAYING our EOS message will not be received. - gst_element_set_state(m_pipeline, GST_STATE_PLAYING); - //with live sources it's necessary to send EOS even to pipeline - //before going to STOPPED state - gst_element_send_event(m_pipeline, gst_event_new_eos()); - - return; - } else { - m_waitingForEos = false; - //qDebug() << "EOS received"; - } - } - - //select suitable default codecs/containers, if necessary - m_recorderControl->applySettings(); - - gst_element_set_state(m_pipeline, GST_STATE_NULL); - - if (!rebuildGraph(newMode)) { - m_pendingState = StoppedState; - m_state = StoppedState; - emit stateChanged(StoppedState); - - return; - } - } - - switch (newState) { - case PausedState: - gst_element_set_state(m_pipeline, GST_STATE_PAUSED); - break; - case RecordingState: - case PreviewState: - gst_element_set_state(m_pipeline, GST_STATE_PLAYING); - break; - case StoppedState: - gst_element_set_state(m_pipeline, GST_STATE_NULL); - } - - //we have to do it here, since gstreamer will not emit bus messages any more - if (newState == StoppedState) { - m_state = StoppedState; - emit stateChanged(StoppedState); - } -} - - -qint64 QGstreamerCaptureSession::duration() const -{ - gint64 duration = 0; - if (m_encodeBin && qt_gst_element_query_position(m_encodeBin, GST_FORMAT_TIME, &duration)) - return duration / 1000000; - else - return 0; -} - -void QGstreamerCaptureSession::setCaptureDevice(const QString &deviceName) -{ - m_captureDevice = deviceName; -} - -void QGstreamerCaptureSession::setMetaData(const QMap<QByteArray, QVariant> &data) -{ - //qDebug() << "QGstreamerCaptureSession::setMetaData" << data; - m_metaData = data; - - if (m_encodeBin) - QGstUtils::setMetaData(GST_BIN(m_encodeBin), data); -} - -bool QGstreamerCaptureSession::processBusMessage(const QGstreamerMessage &message) -{ - GstMessage* gm = message.rawMessage(); - - if (gm) { - if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ERROR) { - GError *err; - gchar *debug; - gst_message_parse_error (gm, &err, &debug); - emit error(int(QMediaRecorder::ResourceError),QString::fromUtf8(err->message)); - g_error_free (err); - g_free (debug); - } - - if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_pipeline)) { - switch (GST_MESSAGE_TYPE(gm)) { - case GST_MESSAGE_DURATION: - break; - - case GST_MESSAGE_EOS: - if (m_waitingForEos) - setState(m_pendingState); - break; - - case GST_MESSAGE_STATE_CHANGED: - { - - GstState oldState; - GstState newState; - GstState pending; - - gst_message_parse_state_changed(gm, &oldState, &newState, &pending); - - QStringList states; - states << "GST_STATE_VOID_PENDING" << "GST_STATE_NULL" << "GST_STATE_READY" << "GST_STATE_PAUSED" << "GST_STATE_PLAYING"; - - /* - qDebug() << QString("state changed: old: %1 new: %2 pending: %3") \ - .arg(states[oldState]) \ - .arg(states[newState]) \ - .arg(states[pending]); - - #define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v))) - - qDebug() << "Current session state:" << ENUM_NAME(QGstreamerCaptureSession,"State",m_state); - qDebug() << "Pending session state:" << ENUM_NAME(QGstreamerCaptureSession,"State",m_pendingState); - */ - - switch (newState) { - case GST_STATE_VOID_PENDING: - case GST_STATE_NULL: - case GST_STATE_READY: - if (m_state != StoppedState && m_pendingState == StoppedState) { - emit stateChanged(m_state = StoppedState); - dumpGraph("stopped"); - } - break; - case GST_STATE_PAUSED: - if (m_state != PausedState && m_pendingState == PausedState) - emit stateChanged(m_state = PausedState); - dumpGraph("paused"); - - if (m_pipelineMode == RecordingPipeline && !m_metaData.isEmpty()) - setMetaData(m_metaData); - break; - case GST_STATE_PLAYING: - { - if ((m_pendingState == PreviewState || m_pendingState == RecordingState) && - m_state != m_pendingState) - { - m_state = m_pendingState; - emit stateChanged(m_state); - } - - if (m_pipelineMode == PreviewPipeline) - dumpGraph("preview"); - else - dumpGraph("recording"); - } - break; - } - } - break; - default: - break; - } - //qDebug() << "New session state:" << ENUM_NAME(QGstreamerCaptureSession,"State",m_state); - } - } - return false; -} - -void QGstreamerCaptureSession::setMuted(bool muted) -{ - if (bool(m_muted) != muted) { - m_muted = muted; - if (m_audioVolume) - g_object_set(G_OBJECT(m_audioVolume), "mute", m_muted, NULL); - - emit mutedChanged(muted); - } -} - -void QGstreamerCaptureSession::setVolume(qreal volume) -{ - if (!qFuzzyCompare(double(volume), m_volume)) { - m_volume = volume; - if (m_audioVolume) - g_object_set(G_OBJECT(m_audioVolume), "volume", m_volume, NULL); - - emit volumeChanged(volume); - } -} - -void QGstreamerCaptureSession::addProbe(QGstreamerAudioProbeControl* probe) -{ - Q_ASSERT(!m_audioProbe); - m_audioProbe = probe; - addAudioBufferProbe(); -} - -void QGstreamerCaptureSession::removeProbe(QGstreamerAudioProbeControl* probe) -{ - Q_ASSERT(m_audioProbe == probe); - removeAudioBufferProbe(); - m_audioProbe = 0; -} - -GstPad *QGstreamerCaptureSession::getAudioProbePad() -{ - // first see if preview element is available - if (m_audioPreview) { - GstPad *pad = gst_element_get_static_pad(m_audioPreview, "sink"); - if (pad) - return pad; - } - - // preview element is not available, - // try to use sink pin of audio encoder. - if (m_encodeBin) { - GstElement *audioEncoder = gst_bin_get_by_name(GST_BIN(m_encodeBin), "audio-encoder-bin"); - if (audioEncoder) { - GstPad *pad = gst_element_get_static_pad(audioEncoder, "sink"); - gst_object_unref(audioEncoder); - if (pad) - return pad; - } - } - - return 0; -} - -void QGstreamerCaptureSession::removeAudioBufferProbe() -{ - if (!m_audioProbe) - return; - - GstPad *pad = getAudioProbePad(); - if (pad) { - m_audioProbe->removeProbeFromPad(pad); - gst_object_unref(GST_OBJECT(pad)); - } -} - -void QGstreamerCaptureSession::addAudioBufferProbe() -{ - if (!m_audioProbe) - return; - - GstPad *pad = getAudioProbePad(); - if (pad) { - m_audioProbe->addProbeToPad(pad); - gst_object_unref(GST_OBJECT(pad)); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h deleted file mode 100644 index 4e54ecc15..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h +++ /dev/null @@ -1,242 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERCAPTURESESSION_H -#define QGSTREAMERCAPTURESESSION_H - -#include <qmediarecordercontrol.h> -#include <qmediarecorder.h> - -#include <QtCore/qmutex.h> -#include <QtCore/qurl.h> - -#include <gst/gst.h> -#include <gst/video/video.h> - -#include <private/qgstreamerbushelper_p.h> -#include <private/qgstreamerbufferprobe_p.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerMessage; -class QGstreamerBusHelper; -class QGstreamerAudioEncode; -class QGstreamerVideoEncode; -class QGstreamerImageEncode; -class QGstreamerRecorderControl; -class QGstreamerMediaContainerControl; -class QGstreamerVideoRendererInterface; -class QGstreamerAudioProbeControl; - -class QGstreamerElementFactory -{ -public: - virtual GstElement *buildElement() = 0; - virtual void prepareWinId() {} -}; - -class QGstreamerVideoInput : public QGstreamerElementFactory -{ -public: - virtual QList<qreal> supportedFrameRates(const QSize &frameSize = QSize()) const = 0; - virtual QList<QSize> supportedResolutions(qreal frameRate = -1) const = 0; -}; - -class QGstreamerCaptureSession - : public QObject - , public QGstreamerBusMessageFilter - , private QGstreamerBufferProbe -{ - Q_OBJECT - Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged) - Q_ENUMS(State) - Q_ENUMS(CaptureMode) - Q_INTERFACES(QGstreamerBusMessageFilter) -public: - enum CaptureMode { Audio = 1, - Video = 2, - Image = 4, - AudioAndVideo = Audio | Video, - AudioAndVideoAndImage = Audio | Video | Image - }; - enum State { StoppedState, PreviewState, PausedState, RecordingState }; - - QGstreamerCaptureSession(CaptureMode captureMode, QObject *parent); - ~QGstreamerCaptureSession(); - - QGstreamerBusHelper *bus() { return m_busHelper; } - - CaptureMode captureMode() const { return m_captureMode; } - void setCaptureMode(CaptureMode); - - QUrl outputLocation() const; - bool setOutputLocation(const QUrl& sink); - - QGstreamerAudioEncode *audioEncodeControl() const { return m_audioEncodeControl; } - QGstreamerVideoEncode *videoEncodeControl() const { return m_videoEncodeControl; } - QGstreamerImageEncode *imageEncodeControl() const { return m_imageEncodeControl; } - - QGstreamerRecorderControl *recorderControl() const { return m_recorderControl; } - QGstreamerMediaContainerControl *mediaContainerControl() const { return m_mediaContainerControl; } - - QGstreamerElementFactory *audioInput() const { return m_audioInputFactory; } - void setAudioInput(QGstreamerElementFactory *audioInput); - - QGstreamerElementFactory *audioPreview() const { return m_audioPreviewFactory; } - void setAudioPreview(QGstreamerElementFactory *audioPreview); - - QGstreamerVideoInput *videoInput() const { return m_videoInputFactory; } - void setVideoInput(QGstreamerVideoInput *videoInput); - - QObject *videoPreview() const { return m_viewfinder; } - void setVideoPreview(QObject *viewfinder); - - void captureImage(int requestId, const QString &fileName); - - State state() const; - State pendingState() const; - - qint64 duration() const; - bool isMuted() const { return m_muted; } - qreal volume() const { return m_volume; } - - bool isReady() const; - - bool processBusMessage(const QGstreamerMessage &message) override; - - void addProbe(QGstreamerAudioProbeControl* probe); - void removeProbe(QGstreamerAudioProbeControl* probe); - -signals: - void stateChanged(QGstreamerCaptureSession::State state); - void durationChanged(qint64 duration); - void error(int error, const QString &errorString); - void imageExposed(int requestId); - void imageCaptured(int requestId, const QImage &img); - void imageSaved(int requestId, const QString &path); - void mutedChanged(bool); - void volumeChanged(qreal); - void readyChanged(bool); - void viewfinderChanged(); - -public slots: - void setState(QGstreamerCaptureSession::State); - void setCaptureDevice(const QString &deviceName); - - void dumpGraph(const QString &fileName); - - void setMetaData(const QMap<QByteArray, QVariant>&); - void setMuted(bool); - void setVolume(qreal volume); - -private: - void probeCaps(GstCaps *caps) override; - bool probeBuffer(GstBuffer *buffer) override; - - enum PipelineMode { EmptyPipeline, PreviewPipeline, RecordingPipeline, PreviewAndRecordingPipeline }; - - GstElement *buildEncodeBin(); - GstElement *buildAudioSrc(); - GstElement *buildAudioPreview(); - GstElement *buildVideoSrc(); - GstElement *buildVideoPreview(); - GstElement *buildImageCapture(); - - bool rebuildGraph(QGstreamerCaptureSession::PipelineMode newMode); - - GstPad *getAudioProbePad(); - void removeAudioBufferProbe(); - void addAudioBufferProbe(); - - QUrl m_sink; - QString m_captureDevice; - State m_state; - State m_pendingState; - bool m_waitingForEos; - PipelineMode m_pipelineMode; - QGstreamerCaptureSession::CaptureMode m_captureMode; - QMap<QByteArray, QVariant> m_metaData; - - QGstreamerAudioProbeControl *m_audioProbe; - - QGstreamerElementFactory *m_audioInputFactory; - QGstreamerElementFactory *m_audioPreviewFactory; - QGstreamerVideoInput *m_videoInputFactory; - QObject *m_viewfinder; - QGstreamerVideoRendererInterface *m_viewfinderInterface; - - QGstreamerAudioEncode *m_audioEncodeControl; - QGstreamerVideoEncode *m_videoEncodeControl; - QGstreamerImageEncode *m_imageEncodeControl; - QGstreamerRecorderControl *m_recorderControl; - QGstreamerMediaContainerControl *m_mediaContainerControl; - - QGstreamerBusHelper *m_busHelper; - GstBus* m_bus; - GstElement *m_pipeline; - - GstElement *m_audioSrc; - GstElement *m_audioTee; - GstElement *m_audioPreviewQueue; - GstElement *m_audioPreview; - GstElement *m_audioVolume; - gboolean m_muted; - double m_volume; - - GstElement *m_videoSrc; - GstElement *m_videoTee; - GstElement *m_videoPreviewQueue; - GstElement *m_videoPreview; - - GstElement *m_imageCaptureBin; - - GstElement *m_encodeBin; - - GstVideoInfo m_previewInfo; - -public: - bool m_passImage; - bool m_passPrerollImage; - QString m_imageFileName; - int m_imageRequestId; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERCAPTURESESSION_H diff --git a/src/plugins/gstreamer/mediacapture/qgstreamerimagecapturecontrol.cpp b/src/plugins/gstreamer/mediacapture/qgstreamerimagecapturecontrol.cpp deleted file mode 100644 index 120c19af6..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamerimagecapturecontrol.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamerimagecapturecontrol.h" -#include <QtCore/QDebug> -#include <QtCore/QDir> - -QGstreamerImageCaptureControl::QGstreamerImageCaptureControl(QGstreamerCaptureSession *session) - :QCameraImageCaptureControl(session), m_session(session), m_ready(false), m_lastId(0) -{ - connect(m_session, SIGNAL(stateChanged(QGstreamerCaptureSession::State)), SLOT(updateState())); - connect(m_session, SIGNAL(imageExposed(int)), this, SIGNAL(imageExposed(int))); - connect(m_session, SIGNAL(imageCaptured(int,QImage)), this, SIGNAL(imageCaptured(int,QImage))); - connect(m_session, SIGNAL(imageSaved(int,QString)), this, SIGNAL(imageSaved(int,QString))); -} - -QGstreamerImageCaptureControl::~QGstreamerImageCaptureControl() -{ -} - -bool QGstreamerImageCaptureControl::isReadyForCapture() const -{ - return m_ready; -} - -int QGstreamerImageCaptureControl::capture(const QString &fileName) -{ - m_lastId++; - - //it's allowed to request image capture while camera is starting - if (m_session->pendingState() == QGstreamerCaptureSession::StoppedState || - !(m_session->captureMode() & QGstreamerCaptureSession::Image)) { - //emit error in the next event loop, - //so application can associate it with returned request id. - QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, - Q_ARG(int, m_lastId), - Q_ARG(int, QCameraImageCapture::NotReadyError), - Q_ARG(QString,tr("Not ready to capture"))); - - return m_lastId; - } - - QString path = fileName; - if (path.isEmpty()) { - int lastImage = 0; - QDir outputDir = QDir::currentPath(); - const auto list = outputDir.entryList(QStringList() << "img_*.jpg"); - for (const QString &fileName : list) { - int imgNumber = QStringView{fileName}.mid(4, fileName.size()-8).toInt(); - lastImage = qMax(lastImage, imgNumber); - } - - path = QString("img_%1.jpg").arg(lastImage+1, - 4, //fieldWidth - 10, - QLatin1Char('0')); - } - - m_session->captureImage(m_lastId, path); - - return m_lastId; -} - -void QGstreamerImageCaptureControl::cancelCapture() -{ - -} - -void QGstreamerImageCaptureControl::updateState() -{ - bool ready = (m_session->state() == QGstreamerCaptureSession::PreviewState) && - (m_session->captureMode() & QGstreamerCaptureSession::Image); - - if (m_ready != ready) { - emit readyForCaptureChanged(m_ready = ready); - } -} diff --git a/src/plugins/gstreamer/mediacapture/qgstreamerimagecapturecontrol.h b/src/plugins/gstreamer/mediacapture/qgstreamerimagecapturecontrol.h deleted file mode 100644 index 75bca0b58..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamerimagecapturecontrol.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QGSTREAMERIMAGECAPTURECONTROL_H -#define QGSTREAMERIMAGECAPTURECONTROL_H - -#include <qcameraimagecapturecontrol.h> -#include "qgstreamercapturesession.h" - -QT_BEGIN_NAMESPACE - -class QGstreamerImageCaptureControl : public QCameraImageCaptureControl -{ - Q_OBJECT -public: - QGstreamerImageCaptureControl(QGstreamerCaptureSession *session); - virtual ~QGstreamerImageCaptureControl(); - - QCameraImageCapture::DriveMode driveMode() const override { return QCameraImageCapture::SingleImageCapture; } - void setDriveMode(QCameraImageCapture::DriveMode) override {} - - bool isReadyForCapture() const override; - int capture(const QString &fileName) override; - void cancelCapture() override; - - QCameraImageCapture::CaptureDestinations captureDestination() const override { return QCameraImageCapture::CaptureToBuffer; } - virtual void setCaptureDestination(QCameraImageCapture::CaptureDestinations /*destination*/) override {} - -private slots: - void updateState(); - -private: - QGstreamerCaptureSession *m_session; - bool m_ready; - int m_lastId; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERCAPTURECORNTROL_H diff --git a/src/plugins/gstreamer/mediacapture/qgstreamerimageencode.cpp b/src/plugins/gstreamer/mediacapture/qgstreamerimageencode.cpp deleted file mode 100644 index f9e6ce9ef..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamerimageencode.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamerimageencode.h" -#include "qgstreamercapturesession.h" - -#include <QtCore/qdebug.h> - -#include <math.h> - -QGstreamerImageEncode::QGstreamerImageEncode(QGstreamerCaptureSession *session) - :QImageEncoderControl(session), m_session(session) -{ -} - -QGstreamerImageEncode::~QGstreamerImageEncode() -{ -} - -QList<QSize> QGstreamerImageEncode::supportedResolutions(const QImageEncoderSettings &, bool *continuous) const -{ - if (continuous) - *continuous = m_session->videoInput() != 0; - - return m_session->videoInput() ? m_session->videoInput()->supportedResolutions() : QList<QSize>(); -} - -QStringList QGstreamerImageEncode::supportedImageCodecs() const -{ - return QStringList() << "jpeg"; -} - -QString QGstreamerImageEncode::imageCodecDescription(const QString &codecName) const -{ - if (codecName == "jpeg") - return tr("JPEG image encoder"); - - return QString(); -} - -QImageEncoderSettings QGstreamerImageEncode::imageSettings() const -{ - return m_settings; -} - -void QGstreamerImageEncode::setImageSettings(const QImageEncoderSettings &settings) -{ - if (m_settings != settings) { - m_settings = settings; - emit settingsChanged(); - } -} diff --git a/src/plugins/gstreamer/mediacapture/qgstreamerimageencode.h b/src/plugins/gstreamer/mediacapture/qgstreamerimageencode.h deleted file mode 100644 index f3ebd3e90..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamerimageencode.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERIMAGEENCODE_H -#define QGSTREAMERIMAGEENCODE_H - -#include <qimageencodercontrol.h> - -#include <QtCore/qstringlist.h> -#include <QtCore/qmap.h> - -#include <gst/gst.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerCaptureSession; - -class QGstreamerImageEncode : public QImageEncoderControl -{ - Q_OBJECT -public: - QGstreamerImageEncode(QGstreamerCaptureSession *session); - virtual ~QGstreamerImageEncode(); - - QList<QSize> supportedResolutions(const QImageEncoderSettings &settings = QImageEncoderSettings(), - bool *continuous = 0) const override; - - QStringList supportedImageCodecs() const override; - QString imageCodecDescription(const QString &codecName) const override; - - QImageEncoderSettings imageSettings() const override; - void setImageSettings(const QImageEncoderSettings &settings) override; - -Q_SIGNALS: - void settingsChanged(); - -private: - QImageEncoderSettings m_settings; - - QGstreamerCaptureSession *m_session; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/gstreamer/mediacapture/qgstreamermediacontainercontrol.cpp b/src/plugins/gstreamer/mediacapture/qgstreamermediacontainercontrol.cpp deleted file mode 100644 index 33351476d..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamermediacontainercontrol.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamermediacontainercontrol.h" - -#include <private/qgstutils_p.h> - -#include <QtCore/qdebug.h> - -QGstreamerMediaContainerControl::QGstreamerMediaContainerControl(QObject *parent) - :QMediaContainerControl(parent) - , m_containers(QGstCodecsInfo::Muxer) -{ -} - -QSet<QString> QGstreamerMediaContainerControl::supportedStreamTypes(const QString &container) const -{ - return m_containers.supportedStreamTypes(container); -} - -QString QGstreamerMediaContainerControl::containerExtension() const -{ - return QGstUtils::fileExtensionForMimeType(m_format); -} diff --git a/src/plugins/gstreamer/mediacapture/qgstreamermediacontainercontrol.h b/src/plugins/gstreamer/mediacapture/qgstreamermediacontainercontrol.h deleted file mode 100644 index 02c7346b1..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamermediacontainercontrol.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QGSTREAMERMEDIACONTAINERCONTROL_H -#define QGSTREAMERMEDIACONTAINERCONTROL_H - -#include <qmediacontainercontrol.h> -#include <QtCore/qstringlist.h> -#include <QtCore/qset.h> - -#include <private/qgstcodecsinfo_p.h> - -#include <gst/gst.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerMediaContainerControl : public QMediaContainerControl -{ -Q_OBJECT -public: - QGstreamerMediaContainerControl(QObject *parent); - ~QGstreamerMediaContainerControl() {} - - QStringList supportedContainers() const override { return m_containers.supportedCodecs(); } - QString containerFormat() const override { return m_format; } - void setContainerFormat(const QString &formatMimeType) override { m_format = formatMimeType; } - - QString containerDescription(const QString &formatMimeType) const override { return m_containers.codecDescription(formatMimeType); } - - QByteArray formatElementName() const { return m_containers.codecElement(containerFormat()); } - - QSet<QString> supportedStreamTypes(const QString &container) const; - - QString containerExtension() const; - -private: - QString m_format; - QGstCodecsInfo m_containers; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERMEDIACONTAINERCONTROL_H diff --git a/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp b/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp deleted file mode 100644 index d7f4ec035..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamerrecordercontrol.h" -#include "qgstreameraudioencode.h" -#include "qgstreamervideoencode.h" -#include "qgstreamermediacontainercontrol.h" -#include <QtCore/QDebug> -#include <QtGui/qdesktopservices.h> -#include <QStandardPaths> - -QGstreamerRecorderControl::QGstreamerRecorderControl(QGstreamerCaptureSession *session) - :QMediaRecorderControl(session), - m_session(session), - m_state(QMediaRecorder::StoppedState), - m_status(QMediaRecorder::UnloadedStatus) -{ - connect(m_session, SIGNAL(stateChanged(QGstreamerCaptureSession::State)), SLOT(updateStatus())); - connect(m_session, SIGNAL(error(int,QString)), SLOT(handleSessionError(int,QString))); - connect(m_session, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64))); - connect(m_session, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool))); - connect(m_session, SIGNAL(volumeChanged(qreal)), SIGNAL(volumeChanged(qreal))); - m_hasPreviewState = m_session->captureMode() != QGstreamerCaptureSession::Audio; -} - -QGstreamerRecorderControl::~QGstreamerRecorderControl() -{ -} - -QUrl QGstreamerRecorderControl::outputLocation() const -{ - return m_session->outputLocation(); -} - -bool QGstreamerRecorderControl::setOutputLocation(const QUrl &sink) -{ - m_outputLocation = sink; - m_session->setOutputLocation(sink); - return true; -} - - -QMediaRecorder::State QGstreamerRecorderControl::state() const -{ - return m_state; -} - -QMediaRecorder::Status QGstreamerRecorderControl::status() const -{ - static QMediaRecorder::Status statusTable[3][3] = { - //Stopped recorder state: - { QMediaRecorder::LoadedStatus, QMediaRecorder::FinalizingStatus, QMediaRecorder::FinalizingStatus }, - //Recording recorder state: - { QMediaRecorder::StartingStatus, QMediaRecorder::RecordingStatus, QMediaRecorder::PausedStatus }, - //Paused recorder state: - { QMediaRecorder::StartingStatus, QMediaRecorder::RecordingStatus, QMediaRecorder::PausedStatus } - }; - - QMediaRecorder::State sessionState = QMediaRecorder::StoppedState; - - switch ( m_session->state() ) { - case QGstreamerCaptureSession::RecordingState: - sessionState = QMediaRecorder::RecordingState; - break; - case QGstreamerCaptureSession::PausedState: - sessionState = QMediaRecorder::PausedState; - break; - case QGstreamerCaptureSession::PreviewState: - case QGstreamerCaptureSession::StoppedState: - sessionState = QMediaRecorder::StoppedState; - break; - } - - return statusTable[m_state][sessionState]; -} - -void QGstreamerRecorderControl::updateStatus() -{ - QMediaRecorder::Status newStatus = status(); - if (m_status != newStatus) { - m_status = newStatus; - emit statusChanged(m_status); - // If stop has been called and session state became stopped. - if (m_status == QMediaRecorder::LoadedStatus) - emit stateChanged(m_state); - } -} - -void QGstreamerRecorderControl::handleSessionError(int code, const QString &description) -{ - emit error(code, description); - stop(); -} - -qint64 QGstreamerRecorderControl::duration() const -{ - return m_session->duration(); -} - -void QGstreamerRecorderControl::setState(QMediaRecorder::State state) -{ - switch (state) { - case QMediaRecorder::StoppedState: - stop(); - break; - case QMediaRecorder::PausedState: - pause(); - break; - case QMediaRecorder::RecordingState: - record(); - break; - } -} - -void QGstreamerRecorderControl::record() -{ - if (m_state == QMediaRecorder::RecordingState) - return; - - m_state = QMediaRecorder::RecordingState; - - if (m_outputLocation.isEmpty()) { - QString container = m_session->mediaContainerControl()->containerExtension(); - if (container.isEmpty()) - container = "raw"; - - m_session->setOutputLocation(QUrl(generateFileName(defaultDir(), container))); - } - - m_session->dumpGraph("before-record"); - if (!m_hasPreviewState || m_session->state() != QGstreamerCaptureSession::StoppedState) { - m_session->setState(QGstreamerCaptureSession::RecordingState); - } else - emit error(QMediaRecorder::ResourceError, tr("Service has not been started")); - - m_session->dumpGraph("after-record"); - - emit stateChanged(m_state); - updateStatus(); - - emit actualLocationChanged(m_session->outputLocation()); -} - -void QGstreamerRecorderControl::pause() -{ - if (m_state == QMediaRecorder::PausedState) - return; - - m_state = QMediaRecorder::PausedState; - - m_session->dumpGraph("before-pause"); - if (!m_hasPreviewState || m_session->state() != QGstreamerCaptureSession::StoppedState) { - m_session->setState(QGstreamerCaptureSession::PausedState); - } else - emit error(QMediaRecorder::ResourceError, tr("Service has not been started")); - - emit stateChanged(m_state); - updateStatus(); -} - -void QGstreamerRecorderControl::stop() -{ - if (m_state == QMediaRecorder::StoppedState) - return; - - m_state = QMediaRecorder::StoppedState; - - if (!m_hasPreviewState) { - m_session->setState(QGstreamerCaptureSession::StoppedState); - } else { - if (m_session->state() != QGstreamerCaptureSession::StoppedState) - m_session->setState(QGstreamerCaptureSession::PreviewState); - } - - updateStatus(); -} - -void QGstreamerRecorderControl::applySettings() -{ - //Check the codecs are compatible with container, - //and choose the compatible codecs/container if omitted - QGstreamerAudioEncode *audioEncodeControl = m_session->audioEncodeControl(); - QGstreamerVideoEncode *videoEncodeControl = m_session->videoEncodeControl(); - QGstreamerMediaContainerControl *mediaContainerControl = m_session->mediaContainerControl(); - - bool needAudio = m_session->captureMode() & QGstreamerCaptureSession::Audio; - bool needVideo = m_session->captureMode() & QGstreamerCaptureSession::Video; - - QStringList containerCandidates; - if (mediaContainerControl->containerFormat().isEmpty()) - containerCandidates = mediaContainerControl->supportedContainers(); - else - containerCandidates << mediaContainerControl->containerFormat(); - - - QStringList audioCandidates; - if (needAudio) { - QAudioEncoderSettings audioSettings = audioEncodeControl->audioSettings(); - if (audioSettings.codec().isEmpty()) - audioCandidates = audioEncodeControl->supportedAudioCodecs(); - else - audioCandidates << audioSettings.codec(); - } - - QStringList videoCandidates; - if (needVideo) { - QVideoEncoderSettings videoSettings = videoEncodeControl->videoSettings(); - if (videoSettings.codec().isEmpty()) - videoCandidates = videoEncodeControl->supportedVideoCodecs(); - else - videoCandidates << videoSettings.codec(); - } - - QString container; - QString audioCodec; - QString videoCodec; - - for (const QString &containerCandidate : qAsConst(containerCandidates)) { - QSet<QString> supportedTypes = mediaContainerControl->supportedStreamTypes(containerCandidate); - - audioCodec.clear(); - videoCodec.clear(); - - if (needAudio) { - bool found = false; - for (const QString &audioCandidate : qAsConst(audioCandidates)) { - QSet<QString> audioTypes = audioEncodeControl->supportedStreamTypes(audioCandidate); - if (audioTypes.intersects(supportedTypes)) { - found = true; - audioCodec = audioCandidate; - break; - } - } - if (!found) - continue; - } - - if (needVideo) { - bool found = false; - for (const QString &videoCandidate : qAsConst(videoCandidates)) { - QSet<QString> videoTypes = videoEncodeControl->supportedStreamTypes(videoCandidate); - if (videoTypes.intersects(supportedTypes)) { - found = true; - videoCodec = videoCandidate; - break; - } - } - if (!found) - continue; - } - - container = containerCandidate; - break; - } - - if (container.isEmpty()) { - emit error(QMediaRecorder::FormatError, tr("Not compatible codecs and container format.")); - } else { - mediaContainerControl->setContainerFormat(container); - - if (needAudio) { - QAudioEncoderSettings audioSettings = audioEncodeControl->audioSettings(); - audioSettings.setCodec(audioCodec); - audioEncodeControl->setAudioSettings(audioSettings); - } - - if (needVideo) { - QVideoEncoderSettings videoSettings = videoEncodeControl->videoSettings(); - videoSettings.setCodec(videoCodec); - videoEncodeControl->setVideoSettings(videoSettings); - } - } -} - - -bool QGstreamerRecorderControl::isMuted() const -{ - return m_session->isMuted(); -} - -qreal QGstreamerRecorderControl::volume() const -{ - return m_session->volume(); -} - -void QGstreamerRecorderControl::setMuted(bool muted) -{ - m_session->setMuted(muted); -} - -void QGstreamerRecorderControl::setVolume(qreal volume) -{ - m_session->setVolume(volume); -} - -QDir QGstreamerRecorderControl::defaultDir() const -{ - QStringList dirCandidates; - - if (m_session->captureMode() & QGstreamerCaptureSession::Video) - dirCandidates << QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); - else - dirCandidates << QStandardPaths::writableLocation(QStandardPaths::MusicLocation); - - dirCandidates << QDir::home().filePath("Documents"); - dirCandidates << QDir::home().filePath("My Documents"); - dirCandidates << QDir::homePath(); - dirCandidates << QDir::currentPath(); - dirCandidates << QDir::tempPath(); - - for (const QString &path : qAsConst(dirCandidates)) { - QDir dir(path); - if (dir.exists() && QFileInfo(path).isWritable()) - return dir; - } - - return QDir(); -} - -QString QGstreamerRecorderControl::generateFileName(const QDir &dir, const QString &ext) const -{ - - int lastClip = 0; - const auto list = dir.entryList(QStringList() << QString("clip_*.%1").arg(ext)); - for (const QString &fileName : list) { - int imgNumber = QStringView{fileName}.mid(5, fileName.size()-6-ext.length()).toInt(); - lastClip = qMax(lastClip, imgNumber); - } - - QString name = QString("clip_%1.%2").arg(lastClip+1, - 4, //fieldWidth - 10, - QLatin1Char('0')).arg(ext); - - return dir.absoluteFilePath(name); -} diff --git a/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.h b/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.h deleted file mode 100644 index b80716f4c..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QGSTREAMERRECORDERCONTROL_H -#define QGSTREAMERRECORDERCONTROL_H - -#include <QtCore/QDir> - -#include <qmediarecordercontrol.h> -#include "qgstreamercapturesession.h" - -QT_BEGIN_NAMESPACE - -class QGstreamerRecorderControl : public QMediaRecorderControl -{ - Q_OBJECT - -public: - QGstreamerRecorderControl(QGstreamerCaptureSession *session); - virtual ~QGstreamerRecorderControl(); - - QUrl outputLocation() const override; - bool setOutputLocation(const QUrl &sink) override; - - QMediaRecorder::State state() const override; - QMediaRecorder::Status status() const override; - - qint64 duration() const override; - - bool isMuted() const override; - qreal volume() const override; - - void applySettings() override; - -public slots: - void setState(QMediaRecorder::State state) override; - void record(); - void pause(); - void stop(); - void setMuted(bool) override; - void setVolume(qreal volume) override; - -private slots: - void updateStatus(); - void handleSessionError(int code, const QString &description); - -private: - QDir defaultDir() const; - QString generateFileName(const QDir &dir, const QString &ext) const; - - QUrl m_outputLocation; - QGstreamerCaptureSession *m_session; - QMediaRecorder::State m_state; - QMediaRecorder::Status m_status; - bool m_hasPreviewState; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERCAPTURECORNTROL_H diff --git a/src/plugins/gstreamer/mediacapture/qgstreamerv4l2input.cpp b/src/plugins/gstreamer/mediacapture/qgstreamerv4l2input.cpp deleted file mode 100644 index 405437754..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamerv4l2input.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamerv4l2input.h" - -#include <QtCore/qdebug.h> -#include <QtCore/qfile.h> - -#include <private/qcore_unix_p.h> -#include <linux/videodev2.h> - -#include <algorithm> - -QT_BEGIN_NAMESPACE -static inline uint qHash(const QSize& key) { return uint(key.width()*256+key.height()); } - -static bool operator<(const QSize &s1, const QSize s2) -{ - return s1.width()*s1.height() < s2.width()*s2.height(); -} -QT_END_NAMESPACE - -QGstreamerV4L2Input::QGstreamerV4L2Input(QObject *parent) - :QObject(parent) -{ -} - -QGstreamerV4L2Input::~QGstreamerV4L2Input() -{ -} - -GstElement *QGstreamerV4L2Input::buildElement() -{ - GstElement *camera = gst_element_factory_make("v4l2src", "camera_source"); - if (camera && !m_device.isEmpty() ) - g_object_set(G_OBJECT(camera), "device", m_device.constData(), NULL); - - return camera; -} - -void QGstreamerV4L2Input::setDevice(const QByteArray &newDevice) -{ - if (m_device != newDevice) { - m_device = newDevice; - updateSupportedResolutions(newDevice); - } -} - -void QGstreamerV4L2Input::setDevice(const QString &device) -{ - setDevice(QFile::encodeName(device)); -} - -void QGstreamerV4L2Input::updateSupportedResolutions(const QByteArray &device) -{ - m_frameRates.clear(); - m_resolutions.clear(); - m_ratesByResolution.clear(); - - QSet<QSize> allResolutions; - QSet<int> allFrameRates; - - QFile f(device); - - if (!f.open(QFile::ReadOnly)) - return; - - int fd = f.handle(); - - //get the list of formats: - QList<quint32> supportedFormats; - - { - v4l2_fmtdesc fmt; - memset(&fmt, 0, sizeof(v4l2_fmtdesc)); - - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - int sanity = 0; - - for (fmt.index = 0;; fmt.index++) { - if (sanity++ > 8) - break; - if( ::ioctl(fd, VIDIOC_ENUM_FMT, &fmt) == -1) { - if(errno == EINVAL) - break; - } - supportedFormats.append(fmt.pixelformat); - } - } - - QList<QSize> commonSizes; - commonSizes << QSize(128, 96) - <<QSize(160,120) - <<QSize(176, 144) - <<QSize(320, 240) - <<QSize(352, 288) - <<QSize(640, 480) - <<QSize(1024, 768) - <<QSize(1280, 1024) - <<QSize(1600, 1200) - <<QSize(1920, 1200) - <<QSize(2048, 1536) - <<QSize(2560, 1600) - <<QSize(2580, 1936); - - QList<int> commonRates; - commonRates << 05*1000 << 75*1000 << 10*1000 << 15*1000 << 20*1000 - << 24*1000 << 25*1000 << 30*1000 << 50*1000 << 60*1000; - - - //get the list of resolutions: - - for (quint32 format : qAsConst(supportedFormats)) { - struct v4l2_frmsizeenum formatSize; - memset(&formatSize, 0, sizeof(formatSize)); - formatSize.pixel_format = format; - - QList<QSize> sizeList; - - if (0) { - char formatStr[5]; - memcpy(formatStr, &format, 4); - formatStr[4] = 0; - //qDebug() << "trying format" << formatStr; - } - - for (int i=0;;i++) { - formatSize.index = i; - if (ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &formatSize) < 0) - break; - - if (formatSize.type == V4L2_FRMSIZE_TYPE_DISCRETE) { - sizeList.append(QSize(formatSize.discrete.width, formatSize.discrete.height)); - } else { - - for (const QSize& candidate : qAsConst(commonSizes)) { - if (candidate.width() <= (int)formatSize.stepwise.max_width && - candidate.height() >= (int)formatSize.stepwise.min_width && - candidate.width() % formatSize.stepwise.step_width == 0 && - candidate.height() <= (int)formatSize.stepwise.max_height && - candidate.height() >= (int)formatSize.stepwise.min_height && - candidate.height() % formatSize.stepwise.step_height == 0) { - sizeList.append(candidate); - } - } - - if (!sizeList.contains(QSize(formatSize.stepwise.min_width, formatSize.stepwise.min_height))) - sizeList.prepend(QSize(formatSize.stepwise.min_width, formatSize.stepwise.min_height)); - - if (!sizeList.contains(QSize(formatSize.stepwise.max_width, formatSize.stepwise.max_height))) - sizeList.append(QSize(formatSize.stepwise.max_width, formatSize.stepwise.max_height)); - - break; //stepwise values are returned only for index 0 - } - - } - - //and frameRates for each resolution. - - for (const QSize &s : qAsConst(sizeList)) { - allResolutions.insert(s); - - struct v4l2_frmivalenum formatInterval; - memset(&formatInterval, 0, sizeof(formatInterval)); - formatInterval.pixel_format = format; - formatInterval.width = s.width(); - formatInterval.height = s.height(); - - QList<int> frameRates; //in 1/1000 of fps - - for (int i=0; ; i++) { - formatInterval.index = i; - - if (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &formatInterval) < 0) - break; - - if (formatInterval.type == V4L2_FRMIVAL_TYPE_DISCRETE) { - //converts seconds to fps*1000 - if (formatInterval.discrete.numerator) - frameRates.append(qRound(formatInterval.discrete.denominator*1000.0 / formatInterval.discrete.numerator)); - } else { - if (formatInterval.stepwise.min.numerator == 0 || - formatInterval.stepwise.max.numerator == 0) { - qWarning() << "received invalid frame interval"; - break; - } - - - int minRate = qRound(formatInterval.stepwise.min.denominator*1000.0 / - formatInterval.stepwise.min.numerator); - - int maxRate = qRound(formatInterval.stepwise.max.denominator*1000.0 / - formatInterval.stepwise.max.numerator); - - - for (int candidate : qAsConst(commonRates)) { - if (candidate >= minRate && candidate <= maxRate) - frameRates.append(candidate); - } - - if (!frameRates.contains(minRate)) - frameRates.prepend(minRate); - - if (!frameRates.contains(maxRate)) - frameRates.append(maxRate); - - break; //stepwise values are returned only for index 0 - } - } - allFrameRates.unite(QSet<int>{frameRates.constBegin(), frameRates.constEnd()}); - m_ratesByResolution[s].unite(QSet<int>{frameRates.constBegin(), frameRates.constEnd()}); - } - } - - f.close(); - - for (int rate : qAsConst(allFrameRates)) { - m_frameRates.append(rate/1000.0); - } - - std::sort(m_frameRates.begin(), m_frameRates.end()); - - m_resolutions = QList<QSize>{allResolutions.constBegin(), allResolutions.constEnd()}; - std::sort(m_resolutions.begin(), m_resolutions.end()); - - //qDebug() << "frame rates:" << m_frameRates; - //qDebug() << "resolutions:" << m_resolutions; -} - - -QList<qreal> QGstreamerV4L2Input::supportedFrameRates(const QSize &frameSize) const -{ - if (frameSize.isEmpty()) - return m_frameRates; - else { - QList<qreal> res; - const auto rates = m_ratesByResolution[frameSize]; - res.reserve(rates.size()); - for (int rate : rates) { - res.append(rate/1000.0); - } - return res; - } -} - -QList<QSize> QGstreamerV4L2Input::supportedResolutions(qreal frameRate) const -{ - Q_UNUSED(frameRate); - return m_resolutions; -} diff --git a/src/plugins/gstreamer/mediacapture/qgstreamerv4l2input.h b/src/plugins/gstreamer/mediacapture/qgstreamerv4l2input.h deleted file mode 100644 index a82c7cf4b..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamerv4l2input.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QGSTREAMERV4L2INPUT_H -#define QGSTREAMERV4L2INPUT_H - -#include <QtCore/qhash.h> -#include <QtCore/qbytearray.h> -#include <QtCore/qlist.h> -#include <QtCore/qsize.h> -#include "qgstreamercapturesession.h" - -QT_BEGIN_NAMESPACE - -class QGstreamerV4L2Input : public QObject, public QGstreamerVideoInput -{ - Q_OBJECT -public: - QGstreamerV4L2Input(QObject *parent = 0); - virtual ~QGstreamerV4L2Input(); - - GstElement *buildElement() override; - - QList<qreal> supportedFrameRates(const QSize &frameSize = QSize()) const override; - QList<QSize> supportedResolutions(qreal frameRate = -1) const override; - - QByteArray device() const; - -public slots: - void setDevice(const QByteArray &device); - void setDevice(const QString &device); - -private: - void updateSupportedResolutions(const QByteArray &device); - - QList<qreal> m_frameRates; - QList<QSize> m_resolutions; - - QHash<QSize, QSet<int> > m_ratesByResolution; - - QByteArray m_device; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERV4L2INPUT_H diff --git a/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp b/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp deleted file mode 100644 index fefb6edbd..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamervideoencode.h" -#include "qgstreamercapturesession.h" -#include "qgstreamermediacontainercontrol.h" -#include <private/qgstutils_p.h> -#include <QtCore/qdebug.h> - -#include <math.h> - -QGstreamerVideoEncode::QGstreamerVideoEncode(QGstreamerCaptureSession *session) - :QVideoEncoderSettingsControl(session), m_session(session) - , m_codecs(QGstCodecsInfo::VideoEncoder) -{ -} - -QGstreamerVideoEncode::~QGstreamerVideoEncode() -{ -} - -QList<QSize> QGstreamerVideoEncode::supportedResolutions(const QVideoEncoderSettings &, bool *continuous) const -{ - if (continuous) - *continuous = m_session->videoInput() != 0; - - return m_session->videoInput() ? m_session->videoInput()->supportedResolutions() : QList<QSize>(); -} - -QList< qreal > QGstreamerVideoEncode::supportedFrameRates(const QVideoEncoderSettings &, bool *continuous) const -{ - if (continuous) - *continuous = false; - - return m_session->videoInput() ? m_session->videoInput()->supportedFrameRates() : QList<qreal>(); -} - -QStringList QGstreamerVideoEncode::supportedVideoCodecs() const -{ - return m_codecs.supportedCodecs(); -} - -QString QGstreamerVideoEncode::videoCodecDescription(const QString &codecName) const -{ - return m_codecs.codecDescription(codecName); -} - -QStringList QGstreamerVideoEncode::supportedEncodingOptions(const QString &codec) const -{ - return m_codecs.codecOptions(codec); -} - -QVariant QGstreamerVideoEncode::encodingOption(const QString &codec, const QString &name) const -{ - return m_options[codec].value(name); -} - -void QGstreamerVideoEncode::setEncodingOption( - const QString &codec, const QString &name, const QVariant &value) -{ - m_options[codec][name] = value; -} - -QVideoEncoderSettings QGstreamerVideoEncode::videoSettings() const -{ - return m_videoSettings; -} - -void QGstreamerVideoEncode::setVideoSettings(const QVideoEncoderSettings &settings) -{ - m_videoSettings = settings; -} - -GstElement *QGstreamerVideoEncode::createEncoder() -{ - QString codec = m_videoSettings.codec(); - GstElement *encoderElement = gst_element_factory_make(m_codecs.codecElement(codec).constData(), "video-encoder"); - if (!encoderElement) - return 0; - - GstBin *encoderBin = GST_BIN(gst_bin_new("video-encoder-bin")); - - GstElement *sinkCapsFilter = gst_element_factory_make("capsfilter", "capsfilter-video"); - GstElement *srcCapsFilter = gst_element_factory_make("capsfilter", "capsfilter-video"); - gst_bin_add_many(encoderBin, sinkCapsFilter, srcCapsFilter, NULL); - - GstElement *colorspace = gst_element_factory_make("videoconvert", NULL); - gst_bin_add(encoderBin, colorspace); - gst_bin_add(encoderBin, encoderElement); - - gst_element_link_many(sinkCapsFilter, colorspace, encoderElement, srcCapsFilter, NULL); - - // add ghostpads - GstPad *pad = gst_element_get_static_pad(sinkCapsFilter, "sink"); - gst_element_add_pad(GST_ELEMENT(encoderBin), gst_ghost_pad_new("sink", pad)); - gst_object_unref(GST_OBJECT(pad)); - - pad = gst_element_get_static_pad(srcCapsFilter, "src"); - gst_element_add_pad(GST_ELEMENT(encoderBin), gst_ghost_pad_new("src", pad)); - gst_object_unref(GST_OBJECT(pad)); - - if (encoderElement) { - if (m_videoSettings.encodingMode() == QMultimedia::ConstantQualityEncoding) { - QMultimedia::EncodingQuality qualityValue = m_videoSettings.quality(); - - if (codec == QLatin1String("video/x-h264")) { - //constant quantizer mode - g_object_set(G_OBJECT(encoderElement), "pass", 4, NULL); - int qualityTable[] = { - 50, //VeryLow - 35, //Low - 21, //Normal - 15, //High - 8 //VeryHigh - }; - g_object_set(G_OBJECT(encoderElement), "quantizer", qualityTable[qualityValue], NULL); - } else if (codec == QLatin1String("video/x-xvid")) { - //constant quantizer mode - g_object_set(G_OBJECT(encoderElement), "pass", 3, NULL); - int qualityTable[] = { - 32, //VeryLow - 12, //Low - 5, //Normal - 3, //High - 2 //VeryHigh - }; - int quant = qualityTable[qualityValue]; - g_object_set(G_OBJECT(encoderElement), "quantizer", quant, NULL); - } else if (codec.startsWith(QLatin1String("video/mpeg"))) { - //constant quantizer mode - g_object_set(G_OBJECT(encoderElement), "pass", 2, NULL); - //quant from 1 to 30, default ~3 - double qualityTable[] = { - 20, //VeryLow - 8.0, //Low - 3.0, //Normal - 2.5, //High - 2.0 //VeryHigh - }; - double quant = qualityTable[qualityValue]; - g_object_set(G_OBJECT(encoderElement), "quantizer", quant, NULL); - } else if (codec == QLatin1String("video/x-theora")) { - int qualityTable[] = { - 8, //VeryLow - 16, //Low - 32, //Normal - 45, //High - 60 //VeryHigh - }; - //quality from 0 to 63 - int quality = qualityTable[qualityValue]; - g_object_set(G_OBJECT(encoderElement), "quality", quality, NULL); - } - } else { - int bitrate = m_videoSettings.bitRate(); - if (bitrate > 0) { - g_object_set(G_OBJECT(encoderElement), "bitrate", bitrate, NULL); - } - } - - QMap<QString,QVariant> options = m_options.value(codec); - for (auto it = options.cbegin(), end = options.cend(); it != end; ++it) { - const QString &option = it.key(); - const QVariant &value = it.value(); - - switch (value.typeId()) { - case QMetaType::Int: - g_object_set(G_OBJECT(encoderElement), option.toLatin1(), value.toInt(), NULL); - break; - case QMetaType::Bool: - g_object_set(G_OBJECT(encoderElement), option.toLatin1(), value.toBool(), NULL); - break; - case QMetaType::Double: - g_object_set(G_OBJECT(encoderElement), option.toLatin1(), value.toDouble(), NULL); - break; - case QMetaType::QString: - g_object_set(G_OBJECT(encoderElement), option.toLatin1(), value.toString().toUtf8().constData(), NULL); - break; - default: - qWarning() << "unsupported option type:" << option << value; - break; - } - - } - } - - if (!m_videoSettings.resolution().isEmpty() || m_videoSettings.frameRate() > 0.001) { - GstCaps *caps = QGstUtils::videoFilterCaps(); - - if (!m_videoSettings.resolution().isEmpty()) { - gst_caps_set_simple( - caps, - "width", G_TYPE_INT, m_videoSettings.resolution().width(), - "height", G_TYPE_INT, m_videoSettings.resolution().height(), - NULL); - } - - if (m_videoSettings.frameRate() > 0.001) { - QPair<int,int> rate = rateAsRational(); - gst_caps_set_simple( - caps, - "framerate", GST_TYPE_FRACTION, rate.first, rate.second, - NULL); - } - - //qDebug() << "set video caps filter:" << gst_caps_to_string(caps); - - g_object_set(G_OBJECT(sinkCapsFilter), "caps", caps, NULL); - - gst_caps_unref(caps); - } - - // Some encoders support several codecs. Setting a caps filter downstream with the desired - // codec (which is actually a string representation of the caps) will make sure we use the - // correct codec. - GstCaps *caps = gst_caps_from_string(codec.toUtf8().constData()); - g_object_set(G_OBJECT(srcCapsFilter), "caps", caps, NULL); - gst_caps_unref(caps); - - return GST_ELEMENT(encoderBin); -} - -QPair<int,int> QGstreamerVideoEncode::rateAsRational() const -{ - qreal frameRate = m_videoSettings.frameRate(); - - if (frameRate > 0.001) { - //convert to rational number - QList<int> denumCandidates; - denumCandidates << 1 << 2 << 3 << 5 << 10 << 1001 << 1000; - - qreal error = 1.0; - int num = 1; - int denum = 1; - - for (int curDenum : qAsConst(denumCandidates)) { - int curNum = qRound(frameRate*curDenum); - qreal curError = qAbs(qreal(curNum)/curDenum - frameRate); - - if (curError < error) { - error = curError; - num = curNum; - denum = curDenum; - } - - if (curError < 1e-8) - break; - } - - return QPair<int,int>(num,denum); - } - - return QPair<int,int>(); -} - - -QSet<QString> QGstreamerVideoEncode::supportedStreamTypes(const QString &codecName) const -{ - return m_codecs.supportedStreamTypes(codecName); -} diff --git a/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.h b/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.h deleted file mode 100644 index a35e2b456..000000000 --- a/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERVIDEOENCODE_H -#define QGSTREAMERVIDEOENCODE_H - -#include <qvideoencodersettingscontrol.h> - -#include <QtCore/qstringlist.h> -#include <QtCore/qmap.h> -#include <QtCore/qset.h> - -#include <private/qgstcodecsinfo_p.h> - -#include <gst/gst.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerCaptureSession; - -class QGstreamerVideoEncode : public QVideoEncoderSettingsControl -{ - Q_OBJECT -public: - QGstreamerVideoEncode(QGstreamerCaptureSession *session); - virtual ~QGstreamerVideoEncode(); - - QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings = QVideoEncoderSettings(), - bool *continuous = 0) const override; - - QList< qreal > supportedFrameRates(const QVideoEncoderSettings &settings = QVideoEncoderSettings(), - bool *continuous = 0) const override; - - QPair<int,int> rateAsRational() const; - - QStringList supportedVideoCodecs() const override; - QString videoCodecDescription(const QString &codecName) const override; - - QVideoEncoderSettings videoSettings() const override; - void setVideoSettings(const QVideoEncoderSettings &settings) override; - - QStringList supportedEncodingOptions(const QString &codec) const; - QVariant encodingOption(const QString &codec, const QString &name) const; - void setEncodingOption(const QString &codec, const QString &name, const QVariant &value); - - GstElement *createEncoder(); - - QSet<QString> supportedStreamTypes(const QString &codecName) const; - -private: - QGstreamerCaptureSession *m_session; - - QGstCodecsInfo m_codecs; - - QVideoEncoderSettings m_videoSettings; - QMap<QString, QMap<QString, QVariant> > m_options; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/gstreamer/mediaplayer/CMakeLists.txt b/src/plugins/gstreamer/mediaplayer/CMakeLists.txt deleted file mode 100644 index 5bbb26bb9..000000000 --- a/src/plugins/gstreamer/mediaplayer/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -# Generated from mediaplayer.pro. - -##################################################################### -## QGstreamerPlayerServicePlugin Plugin: -##################################################################### - -qt_internal_add_plugin(QGstreamerPlayerServicePlugin - OUTPUT_NAME gstmediaplayer - TYPE mediaservice - SOURCES - qgstreamermetadataprovider.cpp qgstreamermetadataprovider.h - qgstreamerplayerservice.cpp qgstreamerplayerservice.h - qgstreamerplayerserviceplugin.cpp qgstreamerplayerserviceplugin.h - qgstreamerstreamscontrol.cpp qgstreamerstreamscontrol.h - INCLUDE_DIRECTORIES - ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC_LIBRARIES - Qt::Core - Qt::CorePrivate - Qt::Gui - Qt::MultimediaPrivate - Qt::Network - gstreamer - Qt::MultimediaPrivate -) - -#### Keys ignored in scope 1:.:.:mediaplayer.pro:<TRUE>: -# OTHER_FILES = "mediaplayer.json" - -## Scopes: -##################################################################### - -qt_internal_extend_target(QGstreamerPlayerServicePlugin CONDITION TARGET Qt::Widgets - DEFINES - HAVE_WIDGETS - PUBLIC_LIBRARIES - Qt::MultimediaWidgetsPrivate - Qt::Widgets -) - -qt_internal_extend_target(QGstreamerPlayerServicePlugin CONDITION QT_FEATURE_gstreamer_app - PUBLIC_LIBRARIES - gstreamer_app -) diff --git a/src/plugins/gstreamer/mediaplayer/mediaplayer.json b/src/plugins/gstreamer/mediaplayer/mediaplayer.json deleted file mode 100644 index bd1a7e64d..000000000 --- a/src/plugins/gstreamer/mediaplayer/mediaplayer.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["gstreamermediaplayer"], - "Services": ["org.qt-project.qt.mediaplayer"] -} diff --git a/src/plugins/gstreamer/mediaplayer/mediaplayer.pro b/src/plugins/gstreamer/mediaplayer/mediaplayer.pro deleted file mode 100644 index c9dadd979..000000000 --- a/src/plugins/gstreamer/mediaplayer/mediaplayer.pro +++ /dev/null @@ -1,24 +0,0 @@ -TARGET = gstmediaplayer - -include(../common.pri) - -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/qgstreamerplayerservice.h \ - $$PWD/qgstreamerstreamscontrol.h \ - $$PWD/qgstreamermetadataprovider.h \ - $$PWD/qgstreamerplayerserviceplugin.h - -SOURCES += \ - $$PWD/qgstreamerplayerservice.cpp \ - $$PWD/qgstreamerstreamscontrol.cpp \ - $$PWD/qgstreamermetadataprovider.cpp \ - $$PWD/qgstreamerplayerserviceplugin.cpp - -OTHER_FILES += \ - mediaplayer.json - -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = QGstreamerPlayerServicePlugin -load(qt_plugin) diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp deleted file mode 100644 index 191878c9a..000000000 --- a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamermetadataprovider.h" -#include <private/qgstreamerplayersession_p.h> -#include <QDebug> -#include <QtMultimedia/qmediametadata.h> - -#include <gst/gstversion.h> -#include <private/qgstutils_p.h> - -QT_BEGIN_NAMESPACE - -typedef QMap<QByteArray, QString> QGstreamerMetaDataKeyLookup; -Q_GLOBAL_STATIC(QGstreamerMetaDataKeyLookup, metadataKeys) - -static const QGstreamerMetaDataKeyLookup *qt_gstreamerMetaDataKeys() -{ - if (metadataKeys->isEmpty()) { - metadataKeys->insert(GST_TAG_TITLE, QMediaMetaData::Title); - //metadataKeys->insert(0, QMediaMetaData::SubTitle); - //metadataKeys->insert(0, QMediaMetaData::Author); - metadataKeys->insert(GST_TAG_COMMENT, QMediaMetaData::Comment); - metadataKeys->insert(GST_TAG_DESCRIPTION, QMediaMetaData::Description); - //metadataKeys->insert(0, QMediaMetaData::Category); - metadataKeys->insert(GST_TAG_GENRE, QMediaMetaData::Genre); - metadataKeys->insert("year", QMediaMetaData::Year); - //metadataKeys->insert(0, QMediaMetaData::UserRating); - - metadataKeys->insert(GST_TAG_LANGUAGE_CODE, QMediaMetaData::Language); - - metadataKeys->insert(GST_TAG_ORGANIZATION, QMediaMetaData::Publisher); - metadataKeys->insert(GST_TAG_COPYRIGHT, QMediaMetaData::Copyright); - //metadataKeys->insert(0, QMediaMetaData::ParentalRating); - //metadataKeys->insert(0, QMediaMetaData::RatingOrganisation); - - // Media - //metadataKeys->insert(0, QMediaMetaData::Size); - //metadataKeys->insert(0,QMediaMetaData::MediaType ); - metadataKeys->insert(GST_TAG_DURATION, QMediaMetaData::Duration); - - // Audio - metadataKeys->insert(GST_TAG_BITRATE, QMediaMetaData::AudioBitRate); - metadataKeys->insert(GST_TAG_AUDIO_CODEC, QMediaMetaData::AudioCodec); - //metadataKeys->insert(0, QMediaMetaData::ChannelCount); - //metadataKeys->insert(0, QMediaMetaData::SampleRate); - - // Music - metadataKeys->insert(GST_TAG_ALBUM, QMediaMetaData::AlbumTitle); - metadataKeys->insert(GST_TAG_ALBUM_ARTIST, QMediaMetaData::AlbumArtist); - metadataKeys->insert(GST_TAG_ARTIST, QMediaMetaData::ContributingArtist); - //metadataKeys->insert(0, QMediaMetaData::Conductor); - //metadataKeys->insert(0, QMediaMetaData::Lyrics); - //metadataKeys->insert(0, QMediaMetaData::Mood); - metadataKeys->insert(GST_TAG_TRACK_NUMBER, QMediaMetaData::TrackNumber); - - //metadataKeys->insert(0, QMediaMetaData::CoverArtUrlSmall); - //metadataKeys->insert(0, QMediaMetaData::CoverArtUrlLarge); - metadataKeys->insert(GST_TAG_PREVIEW_IMAGE, QMediaMetaData::ThumbnailImage); - metadataKeys->insert(GST_TAG_IMAGE, QMediaMetaData::CoverArtImage); - - // Image/Video - metadataKeys->insert("resolution", QMediaMetaData::Resolution); - metadataKeys->insert("pixel-aspect-ratio", QMediaMetaData::PixelAspectRatio); - metadataKeys->insert(GST_TAG_IMAGE_ORIENTATION, QMediaMetaData::Orientation); - - // Video - //metadataKeys->insert(0, QMediaMetaData::VideoFrameRate); - //metadataKeys->insert(0, QMediaMetaData::VideoBitRate); - metadataKeys->insert(GST_TAG_VIDEO_CODEC, QMediaMetaData::VideoCodec); - - //metadataKeys->insert(0, QMediaMetaData::PosterUrl); - - // Movie - //metadataKeys->insert(0, QMediaMetaData::ChapterNumber); - //metadataKeys->insert(0, QMediaMetaData::Director); - metadataKeys->insert(GST_TAG_PERFORMER, QMediaMetaData::LeadPerformer); - //metadataKeys->insert(0, QMediaMetaData::Writer); - - // Photos - //metadataKeys->insert(0, QMediaMetaData::CameraManufacturer); - //metadataKeys->insert(0, QMediaMetaData::CameraModel); - //metadataKeys->insert(0, QMediaMetaData::Event); - //metadataKeys->insert(0, QMediaMetaData::Subject); - } - - return metadataKeys; -} - -QGstreamerMetaDataProvider::QGstreamerMetaDataProvider(QGstreamerPlayerSession *session, QObject *parent) - :QMetaDataReaderControl(parent), m_session(session) -{ - connect(m_session, SIGNAL(tagsChanged()), SLOT(updateTags())); -} - -QGstreamerMetaDataProvider::~QGstreamerMetaDataProvider() -{ -} - -bool QGstreamerMetaDataProvider::isMetaDataAvailable() const -{ - return !m_session->tags().isEmpty(); -} - -bool QGstreamerMetaDataProvider::isWritable() const -{ - return false; -} - -QVariant QGstreamerMetaDataProvider::metaData(const QString &key) const -{ - if (key == QMediaMetaData::Orientation) - return QGstUtils::fromGStreamerOrientation(m_tags.value(key)); - return m_tags.value(key); -} - -QStringList QGstreamerMetaDataProvider::availableMetaData() const -{ - return m_tags.keys(); -} - -void QGstreamerMetaDataProvider::updateTags() -{ - QVariantMap oldTags = m_tags; - m_tags.clear(); - bool changed = false; - - const auto tags = m_session->tags(); - for (auto i = tags.cbegin(), end = tags.cend(); i != end; ++i) { - //use gstreamer native keys for elements not in our key map - QString key = qt_gstreamerMetaDataKeys()->value(i.key(), i.key()); - m_tags.insert(key, i.value()); - if (i.value() != oldTags.value(key)) { - changed = true; - emit metaDataChanged(key, i.value()); - } - } - - if (oldTags.isEmpty() != m_tags.isEmpty()) { - emit metaDataAvailableChanged(isMetaDataAvailable()); - changed = true; - } - - if (changed) - emit metaDataChanged(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.h b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.h deleted file mode 100644 index 6529c3fb1..000000000 --- a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERMETADATAPROVIDER_H -#define QGSTREAMERMETADATAPROVIDER_H - -#include <qmetadatareadercontrol.h> -#include <qvariant.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerPlayerSession; - -class QGstreamerMetaDataProvider : public QMetaDataReaderControl -{ - Q_OBJECT -public: - QGstreamerMetaDataProvider( QGstreamerPlayerSession *session, QObject *parent ); - virtual ~QGstreamerMetaDataProvider(); - - bool isMetaDataAvailable() const override; - bool isWritable() const; - - QVariant metaData(const QString &key) const override; - QStringList availableMetaData() const override; - -private slots: - void updateTags(); - -private: - QGstreamerPlayerSession *m_session = nullptr; - QVariantMap m_tags; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERMETADATAPROVIDER_H diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp deleted file mode 100644 index 3033b04e0..000000000 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include <QtCore/qvariant.h> -#include <QtCore/qdebug.h> - -#if defined(HAVE_WIDGETS) -#include <QtWidgets/qwidget.h> -#endif - -#include "qgstreamerplayerservice.h" -#include "qgstreamermetadataprovider.h" - -#if defined(HAVE_WIDGETS) -#include <private/qgstreamervideowidget_p.h> -#endif -#include <private/qgstreamervideowindow_p.h> -#include <private/qgstreamervideorenderer_p.h> - -#include "qgstreamerstreamscontrol.h" -#include <private/qgstreameraudioprobecontrol_p.h> -#include <private/qgstreamervideoprobecontrol_p.h> -#include <private/qgstreamerplayersession_p.h> -#include <private/qgstreamerplayercontrol_p.h> - -QT_BEGIN_NAMESPACE - -QGstreamerPlayerService::QGstreamerPlayerService(QObject *parent) - : QMediaService(parent) -{ - m_session = new QGstreamerPlayerSession(this); - m_control = new QGstreamerPlayerControl(m_session, this); - m_metaData = new QGstreamerMetaDataProvider(m_session, this); - m_streamsControl = new QGstreamerStreamsControl(m_session,this); - m_videoRenderer = new QGstreamerVideoRenderer(this); - m_videoWindow = new QGstreamerVideoWindow(this); - // If the GStreamer video sink is not available, don't provide the video window control since - // it won't work anyway. - if (!m_videoWindow->videoSink()) { - delete m_videoWindow; - m_videoWindow = 0; - } - -#if defined(HAVE_WIDGETS) - m_videoWidget = new QGstreamerVideoWidgetControl(this); - - // If the GStreamer video sink is not available, don't provide the video widget control since - // it won't work anyway. - // QVideoWidget will fall back to QVideoRendererControl in that case. - if (!m_videoWidget->videoSink()) { - delete m_videoWidget; - m_videoWidget = 0; - } -#endif -} - -QGstreamerPlayerService::~QGstreamerPlayerService() -{ -} - -QObject *QGstreamerPlayerService::requestControl(const char *name) -{ - if (qstrcmp(name,QMediaPlayerControl_iid) == 0) - return m_control; - - if (qstrcmp(name,QMetaDataReaderControl_iid) == 0) - return m_metaData; - - if (qstrcmp(name,QMediaStreamsControl_iid) == 0) - return m_streamsControl; - - if (qstrcmp(name, QMediaVideoProbeControl_iid) == 0) { - if (!m_videoProbeControl) { - increaseVideoRef(); - m_videoProbeControl = new QGstreamerVideoProbeControl(this); - m_session->addProbe(m_videoProbeControl); - } - m_videoProbeControl->ref.ref(); - return m_videoProbeControl; - } - - if (qstrcmp(name, QMediaAudioProbeControl_iid) == 0) { - if (!m_audioProbeControl) { - m_audioProbeControl = new QGstreamerAudioProbeControl(this); - m_session->addProbe(m_audioProbeControl); - } - m_audioProbeControl->ref.ref(); - return m_audioProbeControl; - } - - if (!m_videoOutput) { - if (qstrcmp(name, QVideoRendererControl_iid) == 0) - m_videoOutput = m_videoRenderer; - else if (qstrcmp(name, QVideoWindowControl_iid) == 0) - m_videoOutput = m_videoWindow; -#if defined(HAVE_WIDGETS) - else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) - m_videoOutput = m_videoWidget; -#endif - - if (m_videoOutput) { - increaseVideoRef(); - m_control->setVideoOutput(m_videoOutput); - return m_videoOutput; - } - } - - return 0; -} - -void QGstreamerPlayerService::releaseControl(QObject *control) -{ - if (!control) - return; - - if (control == m_videoOutput) { - m_videoOutput = 0; - m_control->setVideoOutput(0); - decreaseVideoRef(); - } else if (control == m_videoProbeControl && !m_videoProbeControl->ref.deref()) { - m_session->removeProbe(m_videoProbeControl); - delete m_videoProbeControl; - m_videoProbeControl = 0; - decreaseVideoRef(); - } else if (control == m_audioProbeControl && !m_audioProbeControl->ref.deref()) { - m_session->removeProbe(m_audioProbeControl); - delete m_audioProbeControl; - m_audioProbeControl = 0; - } -} - -void QGstreamerPlayerService::increaseVideoRef() -{ - m_videoReferenceCount++; -} - -void QGstreamerPlayerService::decreaseVideoRef() -{ - m_videoReferenceCount--; -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.h deleted file mode 100644 index e69eb7c04..000000000 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERPLAYERSERVICE_H -#define QGSTREAMERPLAYERSERVICE_H - -#include <QtCore/qobject.h> -#include <QtCore/qiodevice.h> - -#include <qmediaservice.h> - -QT_BEGIN_NAMESPACE -class QMediaPlayerControl; - -class QGstreamerMetaData; -class QGstreamerPlayerControl; -class QGstreamerPlayerSession; -class QGstreamerMetaDataProvider; -class QGstreamerStreamsControl; -class QGstreamerVideoRenderer; -class QGstreamerVideoWindow; -class QGstreamerVideoWidgetControl; -class QGStreamerAvailabilityControl; -class QGstreamerAudioProbeControl; -class QGstreamerVideoProbeControl; - -class QGstreamerPlayerService : public QMediaService -{ - Q_OBJECT -public: - QGstreamerPlayerService(QObject *parent = 0); - ~QGstreamerPlayerService(); - - QObject *requestControl(const char *name) override; - void releaseControl(QObject *control) override; - -private: - QGstreamerPlayerControl *m_control = nullptr; - QGstreamerPlayerSession *m_session = nullptr; - QGstreamerMetaDataProvider *m_metaData = nullptr; - QGstreamerStreamsControl *m_streamsControl = nullptr; - - QGstreamerAudioProbeControl *m_audioProbeControl = nullptr; - QGstreamerVideoProbeControl *m_videoProbeControl = nullptr; - - QObject *m_videoOutput = nullptr; - QObject *m_videoRenderer = nullptr; - QGstreamerVideoWindow *m_videoWindow = nullptr; -#if defined(HAVE_WIDGETS) - QGstreamerVideoWidgetControl *m_videoWidget = nullptr; -#endif - - void increaseVideoRef(); - void decreaseVideoRef(); - int m_videoReferenceCount = 0; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp deleted file mode 100644 index 48f23b1f7..000000000 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include <QtCore/qstring.h> -#include <QtCore/qdebug.h> -#include <QtCore/QDir> -#include <QtCore/QDebug> - -#include "qgstreamerplayerserviceplugin.h" - -//#define QT_SUPPORTEDMIMETYPES_DEBUG - -#include "qgstreamerplayerservice.h" -#include <private/qgstutils_p.h> - -QMediaService* QGstreamerPlayerServicePlugin::create(const QString &key) -{ - QGstUtils::initializeGst(); - - if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) - return new QGstreamerPlayerService; - - qWarning() << "Gstreamer service plugin: unsupported key:" << key; - return 0; -} - -void QGstreamerPlayerServicePlugin::release(QMediaService *service) -{ - delete service; -} - -QMultimedia::SupportEstimate QGstreamerPlayerServicePlugin::hasSupport(const QString &mimeType, - const QStringList &codecs) const -{ - if (m_supportedMimeTypeSet.isEmpty()) - updateSupportedMimeTypes(); - - return QGstUtils::hasSupport(mimeType, codecs, m_supportedMimeTypeSet); -} - -static bool isDecoderOrDemuxer(GstElementFactory *factory) -{ - return gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_DEMUXER) - || gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_DECODER); -} - -void QGstreamerPlayerServicePlugin::updateSupportedMimeTypes() const -{ - m_supportedMimeTypeSet = QGstUtils::supportedMimeTypes(isDecoderOrDemuxer); -} - -QStringList QGstreamerPlayerServicePlugin::supportedMimeTypes() const -{ - return QStringList(); -} - diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.h deleted file mode 100644 index a1f7cc293..000000000 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QGSTREAMERPLAYERSERVICEPLUGIN_H -#define QGSTREAMERPLAYERSERVICEPLUGIN_H - -#include <qmediaserviceproviderplugin.h> -#include <QtCore/qset.h> -#include <QtCore/QObject> - -QT_BEGIN_NAMESPACE - - -class QGstreamerPlayerServicePlugin - : public QMediaServiceProviderPlugin - , public QMediaServiceSupportedFormatsInterface -{ - Q_OBJECT - Q_INTERFACES(QMediaServiceSupportedFormatsInterface) - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "mediaplayer.json") -public: - QMediaService* create(const QString &key) override; - void release(QMediaService *service) override; - - QMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList &codecs) const override; - QStringList supportedMimeTypes() const override; - -private: - void updateSupportedMimeTypes() const; - - mutable QSet<QString> m_supportedMimeTypeSet; //for fast access -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERPLAYERSERVICEPLUGIN_H - diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerstreamscontrol.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerstreamscontrol.cpp deleted file mode 100644 index 4f5c3f0b2..000000000 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerstreamscontrol.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamerstreamscontrol.h" -#include <private/qgstreamerplayersession_p.h> - -QGstreamerStreamsControl::QGstreamerStreamsControl(QGstreamerPlayerSession *session, QObject *parent) - :QMediaStreamsControl(parent), m_session(session) -{ - connect(m_session, SIGNAL(streamsChanged()), SIGNAL(streamsChanged())); -} - -QGstreamerStreamsControl::~QGstreamerStreamsControl() -{ -} - -int QGstreamerStreamsControl::streamCount() -{ - return m_session->streamCount(); -} - -QMediaStreamsControl::StreamType QGstreamerStreamsControl::streamType(int streamNumber) -{ - return m_session->streamType(streamNumber); -} - -QVariant QGstreamerStreamsControl::metaData(int streamNumber, const QString &key) -{ - return m_session->streamProperties(streamNumber).value(key); -} - -bool QGstreamerStreamsControl::isActive(int streamNumber) -{ - return streamNumber != -1 && streamNumber == m_session->activeStream(streamType(streamNumber)); -} - -void QGstreamerStreamsControl::setActive(int streamNumber, bool state) -{ - QMediaStreamsControl::StreamType type = m_session->streamType(streamNumber); - if (type == QMediaStreamsControl::UnknownStream) - return; - - if (state) - m_session->setActiveStream(type, streamNumber); - else { - //only one active stream of certain type is supported - if (m_session->activeStream(type) == streamNumber) - m_session->setActiveStream(type, -1); - } -} - diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerstreamscontrol.h b/src/plugins/gstreamer/mediaplayer/qgstreamerstreamscontrol.h deleted file mode 100644 index 41932095c..000000000 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerstreamscontrol.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERSTREAMSCONTROL_H -#define QGSTREAMERSTREAMSCONTROL_H - -#include <qmediastreamscontrol.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerPlayerSession; - -class QGstreamerStreamsControl : public QMediaStreamsControl -{ - Q_OBJECT -public: - QGstreamerStreamsControl(QGstreamerPlayerSession *session, QObject *parent); - virtual ~QGstreamerStreamsControl(); - - int streamCount() override; - StreamType streamType(int streamNumber) override; - - QVariant metaData(int streamNumber, const QString &key) override; - - bool isActive(int streamNumber) override; - void setActive(int streamNumber, bool state) override; - -private: - QGstreamerPlayerSession *m_session = nullptr; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERSTREAMSCONTROL_H - diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 64e0edeb0..cff104ed7 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -11,22 +11,3 @@ qtHaveModule(quick) { SUBDIRS += videonode } -android { - SUBDIRS += android -} - -qnx { - qtConfig(mmrenderer): SUBDIRS += qnx -} - -win32: { - qtConfig(wmf): SUBDIRS += wmf -} - -qtConfig(gstreamer): SUBDIRS += gstreamer - -darwin:!watchos { - qtConfig(avfoundation): SUBDIRS += avfoundation -} - - diff --git a/src/plugins/qnx/CMakeLists.txt b/src/plugins/qnx/CMakeLists.txt deleted file mode 100644 index a663693b0..000000000 --- a/src/plugins/qnx/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -# Generated from qnx.pro. - -##################################################################### -## NeutrinoServicePlugin Plugin: -##################################################################### - -qt_internal_add_plugin(NeutrinoServicePlugin - OUTPUT_NAME qtmedia_qnx - TYPE mediaservice - SOURCES - common/windowgrabber.cpp common/windowgrabber.h - mediaplayer/mmrenderermediaplayercontrol.cpp mediaplayer/mmrenderermediaplayercontrol.h - mediaplayer/mmrenderermediaplayerservice.cpp mediaplayer/mmrenderermediaplayerservice.h - mediaplayer/mmrenderermetadata.cpp mediaplayer/mmrenderermetadata.h - mediaplayer/mmrenderermetadatareadercontrol.cpp mediaplayer/mmrenderermetadatareadercontrol.h - mediaplayer/mmrendererplayervideorenderercontrol.cpp mediaplayer/mmrendererplayervideorenderercontrol.h - mediaplayer/mmrendererutil.cpp mediaplayer/mmrendererutil.h - mediaplayer/mmrenderervideowindowcontrol.cpp mediaplayer/mmrenderervideowindowcontrol.h - mediaplayer/mmreventmediaplayercontrol.cpp mediaplayer/mmreventmediaplayercontrol.h - mediaplayer/mmreventthread.cpp mediaplayer/mmreventthread.h - neutrinoserviceplugin.cpp neutrinoserviceplugin.h - INCLUDE_DIRECTORIES - common - mediaplayer - PUBLIC_LIBRARIES - Qt::Core - Qt::CorePrivate - Qt::Gui - Qt::GuiPrivate - Qt::MultimediaPrivate - mmrenderer - screen -) - -#### Keys ignored in scope 1:.:.:qnx.pro:<TRUE>: -# OTHER_FILES = "neutrino_mediaservice.json" diff --git a/src/plugins/qnx/camera/bbcameraaudioencodersettingscontrol.cpp b/src/plugins/qnx/camera/bbcameraaudioencodersettingscontrol.cpp deleted file mode 100644 index 96686830f..000000000 --- a/src/plugins/qnx/camera/bbcameraaudioencodersettingscontrol.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbcameraaudioencodersettingscontrol.h" - -#include "bbcamerasession.h" - -QT_BEGIN_NAMESPACE - -BbCameraAudioEncoderSettingsControl::BbCameraAudioEncoderSettingsControl(BbCameraSession *session, QObject *parent) - : QAudioEncoderSettingsControl(parent) - , m_session(session) -{ -} - -QStringList BbCameraAudioEncoderSettingsControl::supportedAudioCodecs() const -{ - return QStringList() << QLatin1String("none") << QLatin1String("aac") << QLatin1String("raw"); -} - -QString BbCameraAudioEncoderSettingsControl::codecDescription(const QString &codecName) const -{ - if (codecName == QLatin1String("none")) - return tr("No compression"); - else if (codecName == QLatin1String("aac")) - return tr("AAC compression"); - else if (codecName == QLatin1String("raw")) - return tr("PCM uncompressed"); - - return QString(); -} - -QList<int> BbCameraAudioEncoderSettingsControl::supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const -{ - Q_UNUSED(settings); - Q_UNUSED(continuous); - - // no API provided by BB10 yet - return QList<int>(); -} - -QAudioEncoderSettings BbCameraAudioEncoderSettingsControl::audioSettings() const -{ - return m_session->audioSettings(); -} - -void BbCameraAudioEncoderSettingsControl::setAudioSettings(const QAudioEncoderSettings &settings) -{ - m_session->setAudioSettings(settings); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbcameraaudioencodersettingscontrol.h b/src/plugins/qnx/camera/bbcameraaudioencodersettingscontrol.h deleted file mode 100644 index 38c01f86c..000000000 --- a/src/plugins/qnx/camera/bbcameraaudioencodersettingscontrol.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBCAMERAAUDIOENCODERSETTINGSCONTROL_H -#define BBCAMERAAUDIOENCODERSETTINGSCONTROL_H - -#include <qaudioencodersettingscontrol.h> - -QT_BEGIN_NAMESPACE - -class BbCameraSession; - -class BbCameraAudioEncoderSettingsControl : public QAudioEncoderSettingsControl -{ - Q_OBJECT -public: - explicit BbCameraAudioEncoderSettingsControl(BbCameraSession *session, QObject *parent = 0); - - QStringList supportedAudioCodecs() const override; - QString codecDescription(const QString &codecName) const override; - QList<int> supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous = 0) const override; - QAudioEncoderSettings audioSettings() const override; - void setAudioSettings(const QAudioEncoderSettings &settings) override; - -private: - BbCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbcameracontrol.cpp b/src/plugins/qnx/camera/bbcameracontrol.cpp deleted file mode 100644 index d47b31dc9..000000000 --- a/src/plugins/qnx/camera/bbcameracontrol.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbcameracontrol.h" - -#include "bbcamerasession.h" - -QT_BEGIN_NAMESPACE - -BbCameraControl::BbCameraControl(BbCameraSession *session, QObject *parent) - : QCameraControl(parent) - , m_session(session) -{ - connect(m_session, SIGNAL(statusChanged(QCamera::Status)), this, SIGNAL(statusChanged(QCamera::Status))); - connect(m_session, SIGNAL(stateChanged(QCamera::State)), this, SIGNAL(stateChanged(QCamera::State))); - connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString))); - connect(m_session, SIGNAL(captureModeChanged(QCamera::CaptureModes)), this, SIGNAL(captureModeChanged(QCamera::CaptureModes))); - - connect(m_session, SIGNAL(cameraOpened()), SLOT(cameraOpened())); - connect(m_session, SIGNAL(focusStatusChanged(int)), SLOT(focusStatusChanged(int))); -} - -QCamera::State BbCameraControl::state() const -{ - return m_session->state(); -} - -void BbCameraControl::setState(QCamera::State state) -{ - m_session->setState(state); -} - -QCamera::CaptureModes BbCameraControl::captureMode() const -{ - return m_session->captureMode(); -} - -void BbCameraControl::setCaptureMode(QCamera::CaptureModes mode) -{ - m_session->setCaptureMode(mode); -} - -QCamera::Status BbCameraControl::status() const -{ - return m_session->status(); -} - -bool BbCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const -{ - return m_session->isCaptureModeSupported(mode); -} - -bool BbCameraControl::canChangeProperty(PropertyChangeType /* changeType */, QCamera::Status /* status */) const -{ - return false; -} - -QCamera::LockTypes BbCameraControl::supportedLocks() const -{ - return (QCamera::LockFocus | QCamera::LockExposure | QCamera::LockWhiteBalance); -} - -QCamera::LockStatus BbCameraControl::lockStatus(QCamera::LockType lock) const -{ - if (!m_supportedLockTypes.testFlag(lock) || (m_session->handle() == CAMERA_HANDLE_INVALID)) - return QCamera::Locked; - - switch (lock) { - case QCamera::LockExposure: - return m_exposureLockStatus; - case QCamera::LockWhiteBalance: - return m_whiteBalanceLockStatus; - case QCamera::LockFocus: - return m_focusLockStatus; - default: - return QCamera::Locked; - } -} - -void BbCameraControl::searchAndLock(QCamera::LockTypes locks) -{ - if (m_session->handle() == CAMERA_HANDLE_INVALID) - return; - - // filter out unsupported locks - locks &= m_supportedLockTypes; - - m_currentLockTypes |= locks; - - uint32_t lockModes = CAMERA_3A_NONE; - - switch (m_locksApplyMode) { - case IndependentMode: - if (m_currentLockTypes & QCamera::LockExposure) - lockModes |= CAMERA_3A_AUTOEXPOSURE; - if (m_currentLockTypes & QCamera::LockWhiteBalance) - lockModes |= CAMERA_3A_AUTOWHITEBALANCE; - if (m_currentLockTypes & QCamera::LockFocus) - lockModes |= CAMERA_3A_AUTOFOCUS; - break; - case FocusExposureBoundMode: - if ((m_currentLockTypes & QCamera::LockExposure) || (m_currentLockTypes & QCamera::LockFocus)) - lockModes = (CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOFOCUS); - break; - case AllBoundMode: - lockModes = (CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOFOCUS | CAMERA_3A_AUTOWHITEBALANCE); - break; - case FocusOnlyMode: - lockModes = CAMERA_3A_AUTOFOCUS; - break; - } - - const camera_error_t result = camera_set_3a_lock(m_session->handle(), lockModes); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to set lock modes:" << result; - } else { - if (lockModes & CAMERA_3A_AUTOFOCUS) { - // handled by focusStatusChanged() - } - - if (lockModes & CAMERA_3A_AUTOEXPOSURE) { - m_exposureLockStatus = QCamera::Locked; - emit lockStatusChanged(QCamera::LockExposure, QCamera::Locked, QCamera::LockAcquired); - } - - if (lockModes & CAMERA_3A_AUTOWHITEBALANCE) { - m_whiteBalanceLockStatus = QCamera::Locked; - emit lockStatusChanged(QCamera::LockWhiteBalance, QCamera::Locked, QCamera::LockAcquired); - } - } -} - -void BbCameraControl::unlock(QCamera::LockTypes locks) -{ - // filter out unsupported locks - locks &= m_supportedLockTypes; - - m_currentLockTypes &= ~locks; - - uint32_t lockModes = CAMERA_3A_NONE; - - switch (m_locksApplyMode) { - case IndependentMode: - if (m_currentLockTypes & QCamera::LockExposure) - lockModes |= CAMERA_3A_AUTOEXPOSURE; - if (m_currentLockTypes & QCamera::LockWhiteBalance) - lockModes |= CAMERA_3A_AUTOWHITEBALANCE; - if (m_currentLockTypes & QCamera::LockFocus) - lockModes |= CAMERA_3A_AUTOFOCUS; - break; - case FocusExposureBoundMode: - if ((m_currentLockTypes & QCamera::LockExposure) || (m_currentLockTypes & QCamera::LockFocus)) - lockModes = (CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOFOCUS); - break; - case AllBoundMode: - lockModes = (CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOFOCUS | CAMERA_3A_AUTOWHITEBALANCE); - break; - case FocusOnlyMode: - lockModes = CAMERA_3A_AUTOFOCUS; - break; - } - - const camera_error_t result = camera_set_3a_lock(m_session->handle(), lockModes); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to set lock modes:" << result; - } else { - if (locks.testFlag(QCamera::LockFocus)) { - // handled by focusStatusChanged() - } - - if (locks.testFlag(QCamera::LockExposure)) { - m_exposureLockStatus = QCamera::Unlocked; - emit lockStatusChanged(QCamera::LockExposure, QCamera::Unlocked, QCamera::UserRequest); - } - - if (locks.testFlag(QCamera::LockWhiteBalance)) { - m_whiteBalanceLockStatus = QCamera::Unlocked; - emit lockStatusChanged(QCamera::LockWhiteBalance, QCamera::Unlocked, QCamera::UserRequest); - } - } -} - -void BbCameraControl::cameraOpened() -{ - // retrieve information about lock apply modes - int supported = 0; - uint32_t modes[20]; - - const camera_error_t result = camera_get_3a_lock_modes(m_session->handle(), 20, &supported, modes); - - if (result == CAMERA_EOK) { - // see API documentation of camera_get_3a_lock_modes for explanation of case discrimination below - if (supported == 4) { - m_locksApplyMode = IndependentMode; - } else if (supported == 3) { - m_locksApplyMode = FocusExposureBoundMode; - } else if (supported == 2) { - if (modes[0] == (CAMERA_3A_AUTOFOCUS | CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOWHITEBALANCE)) - m_locksApplyMode = AllBoundMode; - else - m_locksApplyMode = FocusOnlyMode; - } - } - - // retrieve information about supported lock types - m_supportedLockTypes = QCamera::NoLock; - - if (camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOFOCUS)) - m_supportedLockTypes |= QCamera::LockFocus; - - if (camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOEXPOSURE)) - m_supportedLockTypes |= QCamera::LockExposure; - - if (camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOWHITEBALANCE)) - m_supportedLockTypes |= QCamera::LockWhiteBalance; - - m_focusLockStatus = QCamera::Unlocked; - m_exposureLockStatus = QCamera::Unlocked; - m_whiteBalanceLockStatus = QCamera::Unlocked; -} - -void BbCameraControl::focusStatusChanged(int value) -{ - const camera_focusstate_t focusState = static_cast<camera_focusstate_t>(value); - - switch (focusState) { - case CAMERA_FOCUSSTATE_NONE: - m_focusLockStatus = QCamera::Unlocked; - emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::UserRequest); - break; - case CAMERA_FOCUSSTATE_WAITING: - case CAMERA_FOCUSSTATE_SEARCHING: - m_focusLockStatus = QCamera::Searching; - emit lockStatusChanged(QCamera::LockFocus, QCamera::Searching, QCamera::UserRequest); - break; - case CAMERA_FOCUSSTATE_FAILED: - m_focusLockStatus = QCamera::Unlocked; - emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::LockFailed); - break; - case CAMERA_FOCUSSTATE_LOCKED: - m_focusLockStatus = QCamera::Locked; - emit lockStatusChanged(QCamera::LockFocus, QCamera::Locked, QCamera::LockAcquired); - break; - case CAMERA_FOCUSSTATE_SCENECHANGE: - m_focusLockStatus = QCamera::Unlocked; - emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::LockTemporaryLost); - break; - default: - break; - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbcameracontrol.h b/src/plugins/qnx/camera/bbcameracontrol.h deleted file mode 100644 index 8401b5b26..000000000 --- a/src/plugins/qnx/camera/bbcameracontrol.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBCAMERACONTROL_H -#define BBCAMERACONTROL_H - -#include <qcameracontrol.h> - -QT_BEGIN_NAMESPACE - -class BbCameraSession; - -class BbCameraControl : public QCameraControl -{ - Q_OBJECT -public: - explicit BbCameraControl(BbCameraSession *session, QObject *parent = 0); - - QCamera::State state() const override; - void setState(QCamera::State state) override; - - QCamera::Status status() const override; - - QCamera::CaptureModes captureMode() const override; - void setCaptureMode(QCamera::CaptureModes) override; - bool isCaptureModeSupported(QCamera::CaptureModes mode) const override; - - bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const override; - - enum LocksApplyMode - { - IndependentMode, - FocusExposureBoundMode, - AllBoundMode, - FocusOnlyMode - }; - - QCamera::LockTypes supportedLocks() const override; - QCamera::LockStatus lockStatus(QCamera::LockType lock) const override; - void searchAndLock(QCamera::LockTypes locks) override; - void unlock(QCamera::LockTypes locks) override; - -private Q_SLOTS: - void cameraOpened(); - void focusStatusChanged(int value); - -private: - BbCameraSession *m_session; - - LocksApplyMode m_locksApplyMode = IndependentMode; - QCamera::LockStatus m_focusLockStatus = QCamera::Unlocked; - QCamera::LockStatus m_exposureLockStatus = QCamera::Unlocked; - QCamera::LockStatus m_whiteBalanceLockStatus = QCamera::Unlocked; - QCamera::LockTypes m_currentLockTypes = QCamera::NoLock; - QCamera::LockTypes m_supportedLockTypes = QCamera::NoLock; - -private: - BbCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbcameraexposurecontrol.cpp b/src/plugins/qnx/camera/bbcameraexposurecontrol.cpp deleted file mode 100644 index c02c50119..000000000 --- a/src/plugins/qnx/camera/bbcameraexposurecontrol.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbcameraexposurecontrol.h" - -#include "bbcamerasession.h" - -#include <QDebug> - -QT_BEGIN_NAMESPACE - -BbCameraExposureControl::BbCameraExposureControl(BbCameraSession *session, QObject *parent) - : QCameraExposureControl(parent) - , m_session(session) - , m_requestedExposureMode(QCameraExposure::ExposureAuto) -{ - connect(m_session, SIGNAL(statusChanged(QCamera::Status)), this, SLOT(statusChanged(QCamera::Status))); -} - -bool BbCameraExposureControl::isParameterSupported(ExposureParameter parameter) const -{ - switch (parameter) { - case QCameraExposureControl::ISO: - return false; - case QCameraExposureControl::Aperture: - return false; - case QCameraExposureControl::ShutterSpeed: - return false; - case QCameraExposureControl::ExposureCompensation: - return false; - case QCameraExposureControl::FlashPower: - return false; - case QCameraExposureControl::FlashCompensation: - return false; - case QCameraExposureControl::TorchPower: - return false; - case QCameraExposureControl::ExposureMode: - return true; - case QCameraExposureControl::MeteringMode: - return false; - default: - return false; - } -} - -QVariantList BbCameraExposureControl::supportedParameterRange(ExposureParameter parameter, bool *continuous) const -{ - if (parameter != QCameraExposureControl::ExposureMode) // no other parameter supported by BB10 API at the moment - return QVariantList(); - - if (m_session->status() != QCamera::ActiveStatus) // we can query supported exposure modes only with active viewfinder - return QVariantList(); - - if (continuous) - *continuous = false; - - int supported = 0; - camera_scenemode_t modes[20]; - const camera_error_t result = camera_get_scene_modes(m_session->handle(), 20, &supported, modes); - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve supported scene modes:" << result; - return QVariantList(); - } - - QVariantList exposureModes; - for (int i = 0; i < supported; ++i) { - switch (modes[i]) { - case CAMERA_SCENE_AUTO: - exposureModes << QVariant::fromValue(QCameraExposure::ExposureAuto); - break; - case CAMERA_SCENE_SPORTS: - exposureModes << QVariant::fromValue(QCameraExposure::ExposureSports); - break; - case CAMERA_SCENE_CLOSEUP: - exposureModes << QVariant::fromValue(QCameraExposure::ExposurePortrait); - break; - case CAMERA_SCENE_ACTION: - exposureModes << QVariant::fromValue(QCameraExposure::ExposureSports); - break; - case CAMERA_SCENE_BEACHANDSNOW: - exposureModes << QVariant::fromValue(QCameraExposure::ExposureBeach) << QVariant::fromValue(QCameraExposure::ExposureSnow); - break; - case CAMERA_SCENE_NIGHT: - exposureModes << QVariant::fromValue(QCameraExposure::ExposureNight); - break; - default: break; - } - } - - return exposureModes; -} - -QVariant BbCameraExposureControl::requestedValue(ExposureParameter parameter) const -{ - if (parameter != QCameraExposureControl::ExposureMode) // no other parameter supported by BB10 API at the moment - return QVariant(); - - return QVariant::fromValue(m_requestedExposureMode); -} - -QVariant BbCameraExposureControl::actualValue(ExposureParameter parameter) const -{ - if (parameter != QCameraExposureControl::ExposureMode) // no other parameter supported by BB10 API at the moment - return QVariantList(); - - if (m_session->status() != QCamera::ActiveStatus) // we can query actual scene modes only with active viewfinder - return QVariantList(); - - camera_scenemode_t sceneMode = CAMERA_SCENE_DEFAULT; - const camera_error_t result = camera_get_scene_mode(m_session->handle(), &sceneMode); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve scene mode:" << result; - return QVariant(); - } - - switch (sceneMode) { - case CAMERA_SCENE_AUTO: - return QVariant::fromValue(QCameraExposure::ExposureAuto); - case CAMERA_SCENE_SPORTS: - return QVariant::fromValue(QCameraExposure::ExposureSports); - case CAMERA_SCENE_CLOSEUP: - return QVariant::fromValue(QCameraExposure::ExposurePortrait); - case CAMERA_SCENE_ACTION: - return QVariant::fromValue(QCameraExposure::ExposureSports); - case CAMERA_SCENE_BEACHANDSNOW: - return (m_requestedExposureMode == QCameraExposure::ExposureBeach ? QVariant::fromValue(QCameraExposure::ExposureBeach) - : QVariant::fromValue(QCameraExposure::ExposureSnow)); - case CAMERA_SCENE_NIGHT: - return QVariant::fromValue(QCameraExposure::ExposureNight); - default: - break; - } - - return QVariant(); -} - -bool BbCameraExposureControl::setValue(ExposureParameter parameter, const QVariant& value) -{ - if (parameter != QCameraExposureControl::ExposureMode) // no other parameter supported by BB10 API at the moment - return false; - - if (m_session->status() != QCamera::ActiveStatus) // we can set actual scene modes only with active viewfinder - return false; - - camera_scenemode_t sceneMode = CAMERA_SCENE_DEFAULT; - - if (value.isValid()) { - m_requestedExposureMode = value.value<QCameraExposure::ExposureMode>(); - emit requestedValueChanged(QCameraExposureControl::ExposureMode); - - switch (m_requestedExposureMode) { - case QCameraExposure::ExposureAuto: - sceneMode = CAMERA_SCENE_AUTO; - break; - case QCameraExposure::ExposureSports: - sceneMode = CAMERA_SCENE_SPORTS; - break; - case QCameraExposure::ExposurePortrait: - sceneMode = CAMERA_SCENE_CLOSEUP; - break; - case QCameraExposure::ExposureBeach: - sceneMode = CAMERA_SCENE_BEACHANDSNOW; - break; - case QCameraExposure::ExposureSnow: - sceneMode = CAMERA_SCENE_BEACHANDSNOW; - break; - case QCameraExposure::ExposureNight: - sceneMode = CAMERA_SCENE_NIGHT; - break; - default: - sceneMode = CAMERA_SCENE_DEFAULT; - break; - } - } - - const camera_error_t result = camera_set_scene_mode(m_session->handle(), sceneMode); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to set scene mode:" << result; - return false; - } - - emit actualValueChanged(QCameraExposureControl::ExposureMode); - - return true; -} - -void BbCameraExposureControl::statusChanged(QCamera::Status status) -{ - if (status == QCamera::ActiveStatus || status == QCamera::LoadedStatus) - emit parameterRangeChanged(QCameraExposureControl::ExposureMode); -} - -QCameraExposure::FlashModes BbCameraExposureControl::flashMode() const -{ - return m_flashMode; -} - -void BbCameraExposureControl::setFlashMode(QCameraExposure::FlashModes mode) -{ - if (m_flashMode == mode) - return; - - if (m_session->status() != QCamera::ActiveStatus) // can only be changed when viewfinder is active - return; - - if (m_flashMode == QCameraExposure::FlashVideoLight) { - const camera_error_t result = camera_config_videolight(m_session->handle(), CAMERA_VIDEOLIGHT_OFF); - if (result != CAMERA_EOK) - qWarning() << "Unable to switch off video light:" << result; - } - - m_flashMode = mode; - - if (m_flashMode == QCameraExposure::FlashVideoLight) { - const camera_error_t result = camera_config_videolight(m_session->handle(), CAMERA_VIDEOLIGHT_ON); - if (result != CAMERA_EOK) - qWarning() << "Unable to switch on video light:" << result; - } else { - camera_flashmode_t flashMode = CAMERA_FLASH_AUTO; - - if (m_flashMode.testFlag(QCameraExposure::FlashAuto)) flashMode = CAMERA_FLASH_AUTO; - else if (mode.testFlag(QCameraExposure::FlashOff)) flashMode = CAMERA_FLASH_OFF; - else if (mode.testFlag(QCameraExposure::FlashOn)) flashMode = CAMERA_FLASH_ON; - - const camera_error_t result = camera_config_flash(m_session->handle(), flashMode); - if (result != CAMERA_EOK) - qWarning() << "Unable to configure flash:" << result; - } -} - -bool BbCameraExposureControl::isFlashModeSupported(QCameraExposure::FlashModes mode) const -{ - bool supportsVideoLight = false; - if (m_session->handle() != CAMERA_HANDLE_INVALID) { - supportsVideoLight = camera_has_feature(m_session->handle(), CAMERA_FEATURE_VIDEOLIGHT); - } - - return (mode == QCameraExposure::FlashOff || - mode == QCameraExposure::FlashOn || - mode == QCameraExposure::FlashAuto || - ((mode == QCameraExposure::FlashVideoLight) && supportsVideoLight)); -} - -bool BbCameraExposureControl::isFlashReady() const -{ - //TODO: check for flash charge-level here?!? - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbcameraexposurecontrol.h b/src/plugins/qnx/camera/bbcameraexposurecontrol.h deleted file mode 100644 index 33fd9a7d9..000000000 --- a/src/plugins/qnx/camera/bbcameraexposurecontrol.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBCAMERAEXPOSURECONTROL_H -#define BBCAMERAEXPOSURECONTROL_H - -#include <qcameraexposurecontrol.h> - -QT_BEGIN_NAMESPACE - -class BbCameraSession; - -class BbCameraExposureControl : public QCameraExposureControl -{ - Q_OBJECT -public: - explicit BbCameraExposureControl(BbCameraSession *session, QObject *parent = 0); - - bool isParameterSupported(ExposureParameter parameter) const override; - QVariantList supportedParameterRange(ExposureParameter parameter, bool *continuous) const override; - - QVariant requestedValue(ExposureParameter parameter) const override; - QVariant actualValue(ExposureParameter parameter) const override; - bool setValue(ExposureParameter parameter, const QVariant& value) override; - - QCameraExposure::FlashModes flashMode() const override; - void setFlashMode(QCameraExposure::FlashModes mode) override; - bool isFlashModeSupported(QCameraExposure::FlashModes mode) const override; - bool isFlashReady() const override; - -private Q_SLOTS: - void statusChanged(QCamera::Status status); - -private: - BbCameraSession *m_session; - QCameraExposure::ExposureMode m_requestedExposureMode; - - QCameraExposure::FlashModes m_flashMode = QCameraExposure::FlashAuto; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbcamerafocuscontrol.cpp b/src/plugins/qnx/camera/bbcamerafocuscontrol.cpp deleted file mode 100644 index 8db39a7dd..000000000 --- a/src/plugins/qnx/camera/bbcamerafocuscontrol.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbcamerafocuscontrol.h" - -#include "bbcamerasession.h" - -#include <QDebug> - -QT_BEGIN_NAMESPACE - -BbCameraFocusControl::BbCameraFocusControl(BbCameraSession *session, QObject *parent) - : QCameraFocusControl(parent) - , m_session(session) - , m_focusMode(QCameraFocus::FocusModes()) - , m_focusPointMode(QCameraFocus::FocusPointAuto) - , m_customFocusPoint(QPointF(0, 0)) -{ - connect(m_session, SIGNAL(statusChanged(QCamera::Status)), this, SLOT(statusChanged(QCamera::Status))); -} - -QCameraFocus::FocusModes BbCameraFocusControl::focusMode() const -{ - camera_focusmode_t focusMode = CAMERA_FOCUSMODE_OFF; - - const camera_error_t result = camera_get_focus_mode(m_session->handle(), &focusMode); - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve focus mode from camera:" << result; - return QCameraFocus::FocusModes(); - } - - switch (focusMode) { - case CAMERA_FOCUSMODE_EDOF: - return QCameraFocus::HyperfocalFocus; - case CAMERA_FOCUSMODE_MANUAL: - return QCameraFocus::ManualFocus; - case CAMERA_FOCUSMODE_AUTO: - return QCameraFocus::AutoFocus; - case CAMERA_FOCUSMODE_MACRO: - return QCameraFocus::MacroFocus; - case CAMERA_FOCUSMODE_CONTINUOUS_AUTO: - return QCameraFocus::ContinuousFocus; - case CAMERA_FOCUSMODE_CONTINUOUS_MACRO: // fall through - case CAMERA_FOCUSMODE_OFF: // fall through - default: - return QCameraFocus::FocusModes(); - } -} - -void BbCameraFocusControl::setFocusMode(QCameraFocus::FocusModes mode) -{ - if (m_focusMode == mode) - return; - - camera_focusmode_t focusMode = CAMERA_FOCUSMODE_OFF; - - if (mode == QCameraFocus::HyperfocalFocus) - focusMode = CAMERA_FOCUSMODE_EDOF; - else if (mode == QCameraFocus::ManualFocus) - focusMode = CAMERA_FOCUSMODE_MANUAL; - else if (mode == QCameraFocus::AutoFocus) - focusMode = CAMERA_FOCUSMODE_AUTO; - else if (mode == QCameraFocus::MacroFocus) - focusMode = CAMERA_FOCUSMODE_MACRO; - else if (mode == QCameraFocus::ContinuousFocus) - focusMode = CAMERA_FOCUSMODE_CONTINUOUS_AUTO; - - const camera_error_t result = camera_set_focus_mode(m_session->handle(), focusMode); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to set focus mode:" << result; - return; - } - - m_focusMode = mode; - emit focusModeChanged(m_focusMode); -} - -bool BbCameraFocusControl::isFocusModeSupported(QCameraFocus::FocusModes mode) const -{ - if (m_session->state() == QCamera::UnloadedState) - return false; - - if (mode == QCameraFocus::HyperfocalFocus) - return false; //TODO how to check? - else if (mode == QCameraFocus::ManualFocus) - return camera_has_feature(m_session->handle(), CAMERA_FEATURE_MANUALFOCUS); - else if (mode == QCameraFocus::AutoFocus) - return camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOFOCUS); - else if (mode == QCameraFocus::MacroFocus) - return camera_has_feature(m_session->handle(), CAMERA_FEATURE_MACROFOCUS); - else if (mode == QCameraFocus::ContinuousFocus) - return camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOFOCUS); - - return false; -} - -QCameraFocus::FocusPointMode BbCameraFocusControl::focusPointMode() const -{ - return m_focusPointMode; -} - -void BbCameraFocusControl::setFocusPointMode(QCameraFocus::FocusPointMode mode) -{ - if (m_session->status() != QCamera::ActiveStatus) - return; - - if (m_focusPointMode == mode) - return; - - m_focusPointMode = mode; - emit focusPointModeChanged(m_focusPointMode); - - if (m_focusPointMode == QCameraFocus::FocusPointAuto) { - //TODO: is this correct? - const camera_error_t result = camera_set_focus_regions(m_session->handle(), 0, 0); - if (result != CAMERA_EOK) { - qWarning() << "Unable to set focus region:" << result; - return; - } - - emit focusZonesChanged(); - } else if (m_focusPointMode == QCameraFocus::FocusPointCenter) { - // get the size of the viewfinder - int viewfinderWidth = 0; - int viewfinderHeight = 0; - - if (!retrieveViewfinderSize(&viewfinderWidth, &viewfinderHeight)) - return; - - // define a 40x40 pixel focus region in the center of the viewfinder - camera_region_t focusRegion; - focusRegion.left = (viewfinderWidth / 2) - 20; - focusRegion.top = (viewfinderHeight / 2) - 20; - focusRegion.width = 40; - focusRegion.height = 40; - - camera_error_t result = camera_set_focus_regions(m_session->handle(), 1, &focusRegion); - if (result != CAMERA_EOK) { - qWarning() << "Unable to set focus region:" << result; - return; - } - - // re-set focus mode to apply focus region changes - camera_focusmode_t focusMode = CAMERA_FOCUSMODE_OFF; - result = camera_get_focus_mode(m_session->handle(), &focusMode); - camera_set_focus_mode(m_session->handle(), focusMode); - - emit focusZonesChanged(); - - } else if (m_focusPointMode == QCameraFocus::FocusPointFaceDetection) { - //TODO: implement later - } else if (m_focusPointMode == QCameraFocus::FocusPointCustom) { - updateCustomFocusRegion(); - } -} - -bool BbCameraFocusControl::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const -{ - if (m_session->state() == QCamera::UnloadedState) - return false; - - if (mode == QCameraFocus::FocusPointAuto) { - return camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOFOCUS); - } else if (mode == QCameraFocus::FocusPointCenter) { - return camera_has_feature(m_session->handle(), CAMERA_FEATURE_REGIONFOCUS); - } else if (mode == QCameraFocus::FocusPointFaceDetection) { - return false; //TODO: implement via custom region in combination with face detection in viewfinder - } else if (mode == QCameraFocus::FocusPointCustom) { - return camera_has_feature(m_session->handle(), CAMERA_FEATURE_REGIONFOCUS); - } - - return false; -} - -QPointF BbCameraFocusControl::customFocusPoint() const -{ - return m_customFocusPoint; -} - -void BbCameraFocusControl::setCustomFocusPoint(const QPointF &point) -{ - if (m_customFocusPoint == point) - return; - - m_customFocusPoint = point; - emit customFocusPointChanged(m_customFocusPoint); - - updateCustomFocusRegion(); -} - -QCameraFocusZoneList BbCameraFocusControl::focusZones() const -{ - if (m_session->state() == QCamera::UnloadedState) - return QCameraFocusZoneList(); - - camera_region_t regions[20]; - int supported = 0; - int asked = 0; - camera_error_t result = camera_get_focus_regions(m_session->handle(), 20, &supported, &asked, regions); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve focus regions:" << result; - return QCameraFocusZoneList(); - } - - // retrieve width and height of viewfinder - int viewfinderWidth = 0; - int viewfinderHeight = 0; - if (m_session->captureMode() & QCamera::CaptureStillImage) - result = camera_get_photovf_property(m_session->handle(), - CAMERA_IMGPROP_WIDTH, &viewfinderWidth, - CAMERA_IMGPROP_HEIGHT, &viewfinderHeight); - else if (m_session->captureMode() & QCamera::CaptureVideo) - result = camera_get_videovf_property(m_session->handle(), - CAMERA_IMGPROP_WIDTH, &viewfinderWidth, - CAMERA_IMGPROP_HEIGHT, &viewfinderHeight); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve viewfinder size:" << result; - return QCameraFocusZoneList(); - } - - QCameraFocusZoneList list; - for (int i = 0; i < asked; ++i) { - const int x = regions[i].left; - const int y = regions[i].top; - const int width = regions[i].width; - const int height = regions[i].height; - - QRectF rect(static_cast<float>(x)/static_cast<float>(viewfinderWidth), - static_cast<float>(y)/static_cast<float>(viewfinderHeight), - static_cast<float>(width)/static_cast<float>(viewfinderWidth), - static_cast<float>(height)/static_cast<float>(viewfinderHeight)); - - list << QCameraFocusZone(rect, QCameraFocusZone::Focused); //TODO: how to know if a zone is unused/selected/focused?!? - } - - return list; -} - -void BbCameraFocusControl::updateCustomFocusRegion() -{ - // get the size of the viewfinder - int viewfinderWidth = 0; - int viewfinderHeight = 0; - - if (!retrieveViewfinderSize(&viewfinderWidth, &viewfinderHeight)) - return; - - // define a 40x40 pixel focus region around the custom focus point - camera_region_t focusRegion; - focusRegion.left = qMax(0, static_cast<int>(m_customFocusPoint.x() * viewfinderWidth) - 20); - focusRegion.top = qMax(0, static_cast<int>(m_customFocusPoint.y() * viewfinderHeight) - 20); - focusRegion.width = 40; - focusRegion.height = 40; - - camera_error_t result = camera_set_focus_regions(m_session->handle(), 1, &focusRegion); - if (result != CAMERA_EOK) { - qWarning() << "Unable to set focus region:" << result; - return; - } - - // re-set focus mode to apply focus region changes - camera_focusmode_t focusMode = CAMERA_FOCUSMODE_OFF; - result = camera_get_focus_mode(m_session->handle(), &focusMode); - camera_set_focus_mode(m_session->handle(), focusMode); - - emit focusZonesChanged(); -} - -bool BbCameraFocusControl::retrieveViewfinderSize(int *width, int *height) -{ - if (!width || !height) - return false; - - camera_error_t result = CAMERA_EOK; - if (m_session->captureMode() & QCamera::CaptureStillImage) - result = camera_get_photovf_property(m_session->handle(), - CAMERA_IMGPROP_WIDTH, width, - CAMERA_IMGPROP_HEIGHT, height); - else if (m_session->captureMode() & QCamera::CaptureVideo) - result = camera_get_videovf_property(m_session->handle(), - CAMERA_IMGPROP_WIDTH, width, - CAMERA_IMGPROP_HEIGHT, height); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve viewfinder size:" << result; - return false; - } - - return true; -} - - -qreal BbCameraFocusControl::maximumOpticalZoom() const -{ - //TODO: optical zoom support not available in BB10 API yet - return 1.0; -} - -qreal BbCameraFocusControl::maximumDigitalZoom() const -{ - return m_maximumZoomFactor; -} - -qreal BbCameraFocusControl::requestedOpticalZoom() const -{ - //TODO: optical zoom support not available in BB10 API yet - return 1.0; -} - -qreal BbCameraFocusControl::requestedDigitalZoom() const -{ - return currentDigitalZoom(); -} - -qreal BbCameraFocusControl::currentOpticalZoom() const -{ - //TODO: optical zoom support not available in BB10 API yet - return 1.0; -} - -qreal BbCameraFocusControl::currentDigitalZoom() const -{ - if (m_session->status() != QCamera::ActiveStatus) - return 1.0; - - unsigned int zoomFactor = 0; - camera_error_t result = CAMERA_EOK; - - if (m_session->captureMode() & QCamera::CaptureStillImage) - result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_ZOOMFACTOR, &zoomFactor); - else if (m_session->captureMode() & QCamera::CaptureVideo) - result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_ZOOMFACTOR, &zoomFactor); - - if (result != CAMERA_EOK) - return 1.0; - - return zoomFactor; -} - -void BbCameraFocusControl::zoomTo(qreal optical, qreal digital) -{ - Q_UNUSED(optical); - - if (m_session->status() != QCamera::ActiveStatus) - return; - - const qreal actualZoom = qBound(m_minimumZoomFactor, digital, m_maximumZoomFactor); - - const camera_error_t result = camera_set_zoom(m_session->handle(), actualZoom, false); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to change zoom factor:" << result; - return; - } - - if (m_requestedZoomFactor != digital) { - m_requestedZoomFactor = digital; - emit requestedDigitalZoomChanged(m_requestedZoomFactor); - } - - emit currentDigitalZoomChanged(actualZoom); -} - -void BbCameraFocusControl::statusChanged(QCamera::Status status) -{ - if (status == QCamera::ActiveStatus) { - // retrieve information about zoom limits - unsigned int maximumZoomLimit = 0; - unsigned int minimumZoomLimit = 0; - bool smoothZoom = false; - - const camera_error_t result = camera_get_zoom_limits(m_session->handle(), &maximumZoomLimit, &minimumZoomLimit, &smoothZoom); - if (result == CAMERA_EOK) { - const qreal oldMaximumZoomFactor = m_maximumZoomFactor; - m_maximumZoomFactor = maximumZoomLimit; - - if (oldMaximumZoomFactor != m_maximumZoomFactor) - emit maximumDigitalZoomChanged(m_maximumZoomFactor); - - m_minimumZoomFactor = minimumZoomLimit; - m_supportsSmoothZoom = smoothZoom; - } else { - m_maximumZoomFactor = 1.0; - m_minimumZoomFactor = 1.0; - m_supportsSmoothZoom = false; - } - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbcamerafocuscontrol.h b/src/plugins/qnx/camera/bbcamerafocuscontrol.h deleted file mode 100644 index 1434b778d..000000000 --- a/src/plugins/qnx/camera/bbcamerafocuscontrol.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBCAMERAFOCUSCONTROL_H -#define BBCAMERAFOCUSCONTROL_H - -#include <qcamerafocuscontrol.h> - -QT_BEGIN_NAMESPACE - -class BbCameraSession; - -class BbCameraFocusControl : public QCameraFocusControl -{ - Q_OBJECT -public: - explicit BbCameraFocusControl(BbCameraSession *session, QObject *parent = 0); - - QCameraFocus::FocusModes focusMode() const override; - void setFocusMode(QCameraFocus::FocusModes mode) override; - bool isFocusModeSupported(QCameraFocus::FocusModes mode) const override; - QCameraFocus::FocusPointMode focusPointMode() const override; - void setFocusPointMode(QCameraFocus::FocusPointMode mode) override; - bool isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const override; - QPointF customFocusPoint() const override; - void setCustomFocusPoint(const QPointF &point) override; - QCameraFocusZoneList focusZones() const override; - - qreal maximumOpticalZoom() const override; - qreal maximumDigitalZoom() const override; - qreal requestedOpticalZoom() const override; - qreal requestedDigitalZoom() const override; - qreal currentOpticalZoom() const override; - qreal currentDigitalZoom() const override; - void zoomTo(qreal optical, qreal digital) override; - -private Q_SLOTS: - void statusChanged(QCamera::Status status); - -private: - void updateCustomFocusRegion(); - bool retrieveViewfinderSize(int *width, int *height); - - BbCameraSession *m_session; - - QCameraFocus::FocusModes m_focusMode; - QCameraFocus::FocusPointMode m_focusPointMode; - QPointF m_customFocusPoint; - - qreal m_minimumZoomFactor; - qreal m_maximumZoomFactor; - bool m_supportsSmoothZoom; - qreal m_requestedZoomFactor; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbcameraimagecapturecontrol.cpp b/src/plugins/qnx/camera/bbcameraimagecapturecontrol.cpp deleted file mode 100644 index a2ae3a11d..000000000 --- a/src/plugins/qnx/camera/bbcameraimagecapturecontrol.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbcameraimagecapturecontrol.h" - -#include "bbcamerasession.h" - -QT_BEGIN_NAMESPACE - -BbCameraImageCaptureControl::BbCameraImageCaptureControl(BbCameraSession *session, QObject *parent) - : QCameraImageCaptureControl(parent) - , m_session(session) -{ - connect(m_session, SIGNAL(readyForCaptureChanged(bool)), this, SIGNAL(readyForCaptureChanged(bool))); - connect(m_session, SIGNAL(imageExposed(int)), this, SIGNAL(imageExposed(int))); - connect(m_session, SIGNAL(imageCaptured(int,QImage)), this, SIGNAL(imageCaptured(int,QImage))); - connect(m_session, SIGNAL(imageMetadataAvailable(int,QString,QVariant)), this, SIGNAL(imageMetadataAvailable(int,QString,QVariant))); - connect(m_session, SIGNAL(imageAvailable(int,QVideoFrame)), this, SIGNAL(imageAvailable(int,QVideoFrame))); - connect(m_session, SIGNAL(imageSaved(int,QString)), this, SIGNAL(imageSaved(int,QString))); - connect(m_session, SIGNAL(imageCaptureError(int,int,QString)), this, SIGNAL(error(int,int,QString))); -} - -bool BbCameraImageCaptureControl::isReadyForCapture() const -{ - return m_session->isReadyForCapture(); -} - -QCameraImageCapture::DriveMode BbCameraImageCaptureControl::driveMode() const -{ - return m_session->driveMode(); -} - -void BbCameraImageCaptureControl::setDriveMode(QCameraImageCapture::DriveMode mode) -{ - m_session->setDriveMode(mode); -} - -int BbCameraImageCaptureControl::capture(const QString &fileName) -{ - return m_session->capture(fileName); -} - -void BbCameraImageCaptureControl::cancelCapture() -{ - m_session->cancelCapture(); -} - -QCameraImageCapture::CaptureDestinations BbCameraImageCaptureControl::captureDestination() const -{ - return m_session->captureDestination(); -} - -void BbCameraImageCaptureControl::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) -{ - m_session->setCaptureDestination(destination); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbcameraimagecapturecontrol.h b/src/plugins/qnx/camera/bbcameraimagecapturecontrol.h deleted file mode 100644 index 8ecebd4ba..000000000 --- a/src/plugins/qnx/camera/bbcameraimagecapturecontrol.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBCAMERAIMAGECAPTURECONTROL_H -#define BBCAMERAIMAGECAPTURECONTROL_H - -#include <qcameraimagecapturecontrol.h> - -QT_BEGIN_NAMESPACE - -class BbCameraSession; - -class BbCameraImageCaptureControl : public QCameraImageCaptureControl -{ - Q_OBJECT -public: - explicit BbCameraImageCaptureControl(BbCameraSession *session, QObject *parent = 0); - - bool isReadyForCapture() const override; - - QCameraImageCapture::DriveMode driveMode() const override; - void setDriveMode(QCameraImageCapture::DriveMode mode) override; - - int capture(const QString &fileName) override; - void cancelCapture() override; - - QCameraImageCapture::CaptureDestinations captureDestination() const override; - void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) override; - -private: - BbCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbcameraimageprocessingcontrol.cpp b/src/plugins/qnx/camera/bbcameraimageprocessingcontrol.cpp deleted file mode 100644 index 250a85ca0..000000000 --- a/src/plugins/qnx/camera/bbcameraimageprocessingcontrol.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbcameraimageprocessingcontrol.h" - -#include "bbcamerasession.h" - -#include <QDebug> - -QT_BEGIN_NAMESPACE - -BbCameraImageProcessingControl::BbCameraImageProcessingControl(BbCameraSession *session, QObject *parent) - : QCameraImageProcessingControl(parent) - , m_session(session) -{ -} - -bool BbCameraImageProcessingControl::isParameterSupported(ProcessingParameter parameter) const -{ - return (parameter == QCameraImageProcessingControl::WhiteBalancePreset); -} - -bool BbCameraImageProcessingControl::isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const -{ - if (parameter != QCameraImageProcessingControl::WhiteBalancePreset) - return false; - - if (m_session->handle() == CAMERA_HANDLE_INVALID) - return false; - - int supported = 0; - camera_whitebalancemode_t modes[20]; - const camera_error_t result = camera_get_whitebalance_modes(m_session->handle(), 20, &supported, modes); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve supported whitebalance modes:" << result; - return false; - } - - QSet<QCameraImageProcessing::WhiteBalanceMode> supportedModes; - for (int i = 0; i < supported; ++i) { - switch (modes[i]) { - case CAMERA_WHITEBALANCEMODE_AUTO: - supportedModes.insert(QCameraImageProcessing::WhiteBalanceAuto); - break; - case CAMERA_WHITEBALANCEMODE_MANUAL: - supportedModes.insert(QCameraImageProcessing::WhiteBalanceManual); - break; - default: - break; - } - } - - return supportedModes.contains(value.value<QCameraImageProcessing::WhiteBalanceMode>()); -} - -QVariant BbCameraImageProcessingControl::parameter(ProcessingParameter parameter) const -{ - if (parameter != QCameraImageProcessingControl::WhiteBalancePreset) - return QVariant(); - - if (m_session->handle() == CAMERA_HANDLE_INVALID) - return QVariant(); - - camera_whitebalancemode_t mode; - const camera_error_t result = camera_get_whitebalance_mode(m_session->handle(), &mode); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve current whitebalance mode:" << result; - return QVariant(); - } - - switch (mode) { - case CAMERA_WHITEBALANCEMODE_AUTO: - return QVariant::fromValue(QCameraImageProcessing::WhiteBalanceAuto); - case CAMERA_WHITEBALANCEMODE_MANUAL: - return QVariant::fromValue(QCameraImageProcessing::WhiteBalanceManual); - default: - return QVariant(); - } -} - -void BbCameraImageProcessingControl::setParameter(ProcessingParameter parameter, const QVariant &value) -{ - if (parameter != QCameraImageProcessingControl::WhiteBalancePreset) - return; - - if (m_session->handle() == CAMERA_HANDLE_INVALID) - return; - - camera_whitebalancemode_t mode = CAMERA_WHITEBALANCEMODE_DEFAULT; - switch (value.value<QCameraImageProcessing::WhiteBalanceMode>()) { - case QCameraImageProcessing::WhiteBalanceAuto: - mode = CAMERA_WHITEBALANCEMODE_AUTO; - break; - case QCameraImageProcessing::WhiteBalanceManual: - mode = CAMERA_WHITEBALANCEMODE_MANUAL; - break; - default: - break; - } - - const camera_error_t result = camera_set_whitebalance_mode(m_session->handle(), mode); - - if (result != CAMERA_EOK) - qWarning() << "Unable to set whitebalance mode:" << result; -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbcameraimageprocessingcontrol.h b/src/plugins/qnx/camera/bbcameraimageprocessingcontrol.h deleted file mode 100644 index 0eefdd2a1..000000000 --- a/src/plugins/qnx/camera/bbcameraimageprocessingcontrol.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBCAMERAIMAGEPROCESSINGCONTROL_H -#define BBCAMERAIMAGEPROCESSINGCONTROL_H - -#include <qcameraimageprocessingcontrol.h> - -QT_BEGIN_NAMESPACE - -class BbCameraSession; - -class BbCameraImageProcessingControl : public QCameraImageProcessingControl -{ - Q_OBJECT -public: - explicit BbCameraImageProcessingControl(BbCameraSession *session, QObject *parent = 0); - - bool isParameterSupported(ProcessingParameter) const override; - bool isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const override; - QVariant parameter(ProcessingParameter parameter) const override; - void setParameter(ProcessingParameter parameter, const QVariant &value) override; - -private: - BbCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbcameramediarecordercontrol.cpp b/src/plugins/qnx/camera/bbcameramediarecordercontrol.cpp deleted file mode 100644 index 3cb9ed38d..000000000 --- a/src/plugins/qnx/camera/bbcameramediarecordercontrol.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbcameramediarecordercontrol.h" - -#include "bbcamerasession.h" - -#include <QDebug> -#include <QUrl> - -#include <audio/audio_manager_device.h> -#include <audio/audio_manager_volume.h> - -QT_BEGIN_NAMESPACE - -static audio_manager_device_t currentAudioInputDevice() -{ - audio_manager_device_t device = AUDIO_DEVICE_HEADSET; - - const int result = audio_manager_get_default_input_device(&device); - if (result != EOK) { - qWarning() << "Unable to retrieve default audio input device:" << result; - return AUDIO_DEVICE_HEADSET; - } - - return device; -} - -BbCameraMediaRecorderControl::BbCameraMediaRecorderControl(BbCameraSession *session, QObject *parent) - : QMediaRecorderControl(parent) - , m_session(session) -{ - connect(m_session, SIGNAL(videoStateChanged(QMediaRecorder::State)), this, SIGNAL(stateChanged(QMediaRecorder::State))); - connect(m_session, SIGNAL(videoStatusChanged(QMediaRecorder::Status)), this, SIGNAL(statusChanged(QMediaRecorder::Status))); - connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64))); - connect(m_session, SIGNAL(actualLocationChanged(QUrl)), this, SIGNAL(actualLocationChanged(QUrl))); - connect(m_session, SIGNAL(videoError(int,QString)), this, SIGNAL(error(int,QString))); -} - -QUrl BbCameraMediaRecorderControl::outputLocation() const -{ - return m_session->outputLocation(); -} - -bool BbCameraMediaRecorderControl::setOutputLocation(const QUrl &location) -{ - return m_session->setOutputLocation(location); -} - -QMediaRecorder::State BbCameraMediaRecorderControl::state() const -{ - return m_session->videoState(); -} - -QMediaRecorder::Status BbCameraMediaRecorderControl::status() const -{ - return m_session->videoStatus(); -} - -qint64 BbCameraMediaRecorderControl::duration() const -{ - return m_session->duration(); -} - -bool BbCameraMediaRecorderControl::isMuted() const -{ - bool muted = false; - - const int result = audio_manager_get_input_mute(currentAudioInputDevice(), &muted); - if (result != EOK) { - emit const_cast<BbCameraMediaRecorderControl*>(this)->error(QMediaRecorder::ResourceError, tr("Unable to retrieve mute status")); - return false; - } - - return muted; -} - -qreal BbCameraMediaRecorderControl::volume() const -{ - double level = 0.0; - - const int result = audio_manager_get_input_level(currentAudioInputDevice(), &level); - if (result != EOK) { - emit const_cast<BbCameraMediaRecorderControl*>(this)->error(QMediaRecorder::ResourceError, tr("Unable to retrieve audio input volume")); - return 0.0; - } - - return (level / 100); -} - -void BbCameraMediaRecorderControl::applySettings() -{ - m_session->applyVideoSettings(); -} - -void BbCameraMediaRecorderControl::setState(QMediaRecorder::State state) -{ - m_session->setVideoState(state); -} - -void BbCameraMediaRecorderControl::setMuted(bool muted) -{ - const int result = audio_manager_set_input_mute(currentAudioInputDevice(), muted); - if (result != EOK) { - emit error(QMediaRecorder::ResourceError, tr("Unable to set mute status")); - } else { - emit mutedChanged(muted); - } -} - -void BbCameraMediaRecorderControl::setVolume(qreal volume) -{ - const int result = audio_manager_set_input_level(currentAudioInputDevice(), (volume * 100)); - if (result != EOK) { - emit error(QMediaRecorder::ResourceError, tr("Unable to set audio input volume")); - } else { - emit volumeChanged(volume); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbcameramediarecordercontrol.h b/src/plugins/qnx/camera/bbcameramediarecordercontrol.h deleted file mode 100644 index af46479a5..000000000 --- a/src/plugins/qnx/camera/bbcameramediarecordercontrol.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBCAMERAMEDIARECORDERCONTROL_H -#define BBCAMERAMEDIARECORDERCONTROL_H - -#include <qmediarecordercontrol.h> - -QT_BEGIN_NAMESPACE - -class BbCameraSession; - -class BbCameraMediaRecorderControl : public QMediaRecorderControl -{ - Q_OBJECT -public: - explicit BbCameraMediaRecorderControl(BbCameraSession *session, QObject *parent = 0); - - QUrl outputLocation() const override; - bool setOutputLocation(const QUrl &location) override; - QMediaRecorder::State state() const override; - QMediaRecorder::Status status() const override; - qint64 duration() const override; - bool isMuted() const override; - qreal volume() const override; - void applySettings() override; - -public Q_SLOTS: - void setState(QMediaRecorder::State state) override; - void setMuted(bool muted) override; - void setVolume(qreal volume) override; - -private: - BbCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbcameraorientationhandler.cpp b/src/plugins/qnx/camera/bbcameraorientationhandler.cpp deleted file mode 100644 index d600f3db0..000000000 --- a/src/plugins/qnx/camera/bbcameraorientationhandler.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbcameraorientationhandler.h" - -#include <QAbstractEventDispatcher> -#include <QGuiApplication> -#include <QScreen> -#include <QDebug> - -#include <bps/orientation.h> - -QT_BEGIN_NAMESPACE - -BbCameraOrientationHandler::BbCameraOrientationHandler(QObject *parent) - : QObject(parent) - , m_orientation(0) -{ - QCoreApplication::eventDispatcher()->installNativeEventFilter(this); - int result = orientation_request_events(0); - if (result == BPS_FAILURE) - qWarning() << "Unable to register for orientation change events"; - - orientation_direction_t direction = ORIENTATION_FACE_UP; - int angle = 0; - - result = orientation_get(&direction, &angle); - if (result == BPS_FAILURE) { - qWarning() << "Unable to retrieve initial orientation"; - } else { - m_orientation = angle; - } -} - -BbCameraOrientationHandler::~BbCameraOrientationHandler() -{ - const int result = orientation_stop_events(0); - if (result == BPS_FAILURE) - qWarning() << "Unable to unregister for orientation change events"; - - QCoreApplication::eventDispatcher()->removeNativeEventFilter(this); -} - -bool BbCameraOrientationHandler::nativeEventFilter(const QByteArray&, void *message, qintptr *) -{ - bps_event_t* const event = static_cast<bps_event_t*>(message); - if (!event || bps_event_get_domain(event) != orientation_get_domain()) - return false; - - const int angle = orientation_event_get_angle(event); - if (angle != m_orientation) { - if (angle == 180) // The screen does not rotate at 180 degrees - return false; - - m_orientation = angle; - emit orientationChanged(m_orientation); - } - - return false; // do not drop the event -} - -int BbCameraOrientationHandler::viewfinderOrientation() const -{ - // On a keyboard device we do not rotate the screen at all - if (qGuiApp->primaryScreen()->nativeOrientation() - != qGuiApp->primaryScreen()->primaryOrientation()) { - return m_orientation; - } - - return 0; -} - -int BbCameraOrientationHandler::orientation() const -{ - return m_orientation; -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbcameraorientationhandler.h b/src/plugins/qnx/camera/bbcameraorientationhandler.h deleted file mode 100644 index af80bd4e1..000000000 --- a/src/plugins/qnx/camera/bbcameraorientationhandler.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBCAMERAORIENTATIONHANDLER_H -#define BBCAMERAORIENTATIONHANDLER_H - -#include <QAbstractNativeEventFilter> -#include <QObject> - -QT_BEGIN_NAMESPACE - -class BbCameraOrientationHandler : public QObject, public QAbstractNativeEventFilter -{ - Q_OBJECT -public: - explicit BbCameraOrientationHandler(QObject *parent = 0); - ~BbCameraOrientationHandler(); - - bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override; - - int orientation() const; - - int viewfinderOrientation() const; - -Q_SIGNALS: - void orientationChanged(int degree); - -private: - int m_orientation; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbcameraservice.cpp b/src/plugins/qnx/camera/bbcameraservice.cpp deleted file mode 100644 index cd0a6b13c..000000000 --- a/src/plugins/qnx/camera/bbcameraservice.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbcameraservice.h" - -#include "bbcameraaudioencodersettingscontrol.h" -#include "bbcameracontrol.h" -#include "bbcameraexposurecontrol.h" -#include "bbcamerafocuscontrol.h" -#include "bbcameraimagecapturecontrol.h" -#include "bbcameraimageprocessingcontrol.h" -#include "bbcameramediarecordercontrol.h" -#include "bbcamerasession.h" -#include "bbcameravideoencodersettingscontrol.h" -#include "bbcameraviewfindersettingscontrol.h" -#include "bbimageencodercontrol.h" -#include "bbvideodeviceselectorcontrol.h" -#include "bbvideorenderercontrol.h" - -#include <QDebug> -#include <QVariant> - -QT_BEGIN_NAMESPACE - -BbCameraService::BbCameraService(QObject *parent) - : QMediaService(parent) - , m_cameraSession(new BbCameraSession(this)) - , m_cameraAudioEncoderSettingsControl(new BbCameraAudioEncoderSettingsControl(m_cameraSession, this)) - , m_cameraControl(new BbCameraControl(m_cameraSession, this)) - , m_cameraExposureControl(new BbCameraExposureControl(m_cameraSession, this)) - , m_cameraFocusControl(new BbCameraFocusControl(m_cameraSession, this)) - , m_cameraImageCaptureControl(new BbCameraImageCaptureControl(m_cameraSession, this)) - , m_cameraImageProcessingControl(new BbCameraImageProcessingControl(m_cameraSession, this)) - , m_cameraMediaRecorderControl(new BbCameraMediaRecorderControl(m_cameraSession, this)) - , m_cameraVideoEncoderSettingsControl(new BbCameraVideoEncoderSettingsControl(m_cameraSession, this)) - , m_cameraViewfinderSettingsControl(new BbCameraViewfinderSettingsControl(m_cameraSession, this)) - , m_imageEncoderControl(new BbImageEncoderControl(m_cameraSession, this)) - , m_videoDeviceSelectorControl(new BbVideoDeviceSelectorControl(m_cameraSession, this)) - , m_videoRendererControl(new BbVideoRendererControl(m_cameraSession, this)) -{ -} - -BbCameraService::~BbCameraService() -{ -} - -QMediaControl* BbCameraService::requestControl(const char *name) -{ - if (qstrcmp(name, QAudioEncoderSettingsControl_iid) == 0) - return m_cameraAudioEncoderSettingsControl; - else if (qstrcmp(name, QCameraControl_iid) == 0) - return m_cameraControl; - else if (qstrcmp(name, QCameraExposureControl_iid) == 0) - return m_cameraExposureControl; - else if (qstrcmp(name, QCameraFocusControl_iid) == 0) - return m_cameraFocusControl; - else if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) - return m_cameraImageCaptureControl; - else if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0) - return m_cameraImageProcessingControl; - else if (qstrcmp(name, QMediaRecorderControl_iid) == 0) - return m_cameraMediaRecorderControl; - else if (qstrcmp(name, QVideoEncoderSettingsControl_iid) == 0) - return m_cameraVideoEncoderSettingsControl; - else if (qstrcmp(name, QCameraViewfinderSettingsControl_iid) == 0) - return m_cameraViewfinderSettingsControl; - else if (qstrcmp(name, QImageEncoderControl_iid) == 0) - return m_imageEncoderControl; - else if (qstrcmp(name, QVideoDeviceSelectorControl_iid) == 0) - return m_videoDeviceSelectorControl; - else if (qstrcmp(name, QVideoRendererControl_iid) == 0) - return m_videoRendererControl; - - return 0; -} - -void BbCameraService::releaseControl(QMediaControl *control) -{ - Q_UNUSED(control); - - // Implemented as a singleton, so we do nothing. -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbcameraservice.h b/src/plugins/qnx/camera/bbcameraservice.h deleted file mode 100644 index 307b47668..000000000 --- a/src/plugins/qnx/camera/bbcameraservice.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBCAMERASERVICE_H -#define BBCAMERASERVICE_H - -#include <QObject> - -#include <qmediaservice.h> - -QT_BEGIN_NAMESPACE - -class BbCameraAudioEncoderSettingsControl; -class BbCameraControl; -class BbCameraExposureControl; -class BbCameraFocusControl; -class BbCameraImageCaptureControl; -class BbCameraImageProcessingControl; -class BbCameraMediaRecorderControl; -class BbCameraSession; -class BbCameraVideoEncoderSettingsControl; -class BbCameraViewfinderSettingsControl; -class BbImageEncoderControl; -class BbVideoDeviceSelectorControl; -class BbVideoRendererControl; - -class BbCameraService : public QMediaService -{ - Q_OBJECT - -public: - explicit BbCameraService(QObject *parent = 0); - ~BbCameraService(); - - virtual QMediaControl* requestControl(const char *name); - virtual void releaseControl(QMediaControl *control); - -private: - BbCameraSession* m_cameraSession; - - BbCameraAudioEncoderSettingsControl* m_cameraAudioEncoderSettingsControl; - BbCameraControl* m_cameraControl; - BbCameraExposureControl* m_cameraExposureControl; - BbCameraFocusControl* m_cameraFocusControl; - BbCameraImageCaptureControl* m_cameraImageCaptureControl; - BbCameraImageProcessingControl* m_cameraImageProcessingControl; - BbCameraMediaRecorderControl* m_cameraMediaRecorderControl; - BbCameraVideoEncoderSettingsControl* m_cameraVideoEncoderSettingsControl; - BbCameraViewfinderSettingsControl* m_cameraViewfinderSettingsControl; - BbImageEncoderControl* m_imageEncoderControl; - BbVideoDeviceSelectorControl* m_videoDeviceSelectorControl; - BbVideoRendererControl* m_videoRendererControl; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbcamerasession.cpp b/src/plugins/qnx/camera/bbcamerasession.cpp deleted file mode 100644 index 7b3974084..000000000 --- a/src/plugins/qnx/camera/bbcamerasession.cpp +++ /dev/null @@ -1,1154 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbcamerasession.h" - -#include "bbcameraorientationhandler.h" -#include "bbcameraviewfindersettingscontrol.h" -#include "windowgrabber.h" - -#include <QAbstractVideoSurface> -#include <QBuffer> -#include <QDebug> -#include <QImage> -#include <QUrl> -#include <QVideoSurfaceFormat> -#include <qmath.h> - -#include <algorithm> - -QT_BEGIN_NAMESPACE - -static QString errorToString(camera_error_t error) -{ - switch (error) { - case CAMERA_EOK: - return QLatin1String("No error"); - case CAMERA_EAGAIN: - return QLatin1String("Camera unavailable"); - case CAMERA_EINVAL: - return QLatin1String("Invalid argument"); - case CAMERA_ENODEV: - return QLatin1String("Camera not found"); - case CAMERA_EMFILE: - return QLatin1String("File table overflow"); - case CAMERA_EBADF: - return QLatin1String("Invalid handle passed"); - case CAMERA_EACCESS: - return QLatin1String("No permission"); - case CAMERA_EBADR: - return QLatin1String("Invalid file descriptor"); - case CAMERA_ENOENT: - return QLatin1String("File or directory does not exists"); - case CAMERA_ENOMEM: - return QLatin1String("Memory allocation failed"); - case CAMERA_EOPNOTSUPP: - return QLatin1String("Operation not supported"); - case CAMERA_ETIMEDOUT: - return QLatin1String("Communication timeout"); - case CAMERA_EALREADY: - return QLatin1String("Operation already in progress"); - case CAMERA_EUNINIT: - return QLatin1String("Camera library not initialized"); - case CAMERA_EREGFAULT: - return QLatin1String("Callback registration failed"); - case CAMERA_EMICINUSE: - return QLatin1String("Microphone in use already"); - case CAMERA_ENODATA: - return QLatin1String("Data does not exist"); - case CAMERA_EBUSY: - return QLatin1String("Camera busy"); - case CAMERA_EDESKTOPCAMERAINUSE: - return QLatin1String("Desktop camera in use already"); - case CAMERA_ENOSPC: - return QLatin1String("Disk is full"); - case CAMERA_EPOWERDOWN: - return QLatin1String("Camera in power down state"); - case CAMERA_3ALOCKED: - return QLatin1String("3A have been locked"); -// case CAMERA_EVIEWFINDERFROZEN: // not yet available in 10.2 NDK -// return QLatin1String("Freeze flag set"); - default: - return QLatin1String("Unknown error"); - } -} - -QDebug operator<<(QDebug debug, camera_error_t error) -{ - debug.nospace() << errorToString(error); - return debug.space(); -} - -BbCameraSession::BbCameraSession(QObject *parent) - : QObject(parent) - , m_nativeCameraOrientation(0) - , m_orientationHandler(new BbCameraOrientationHandler(this)) - , m_status(QCamera::UnloadedStatus) - , m_state(QCamera::UnloadedState) - , m_captureMode(QCamera::CaptureStillImage) - , m_device("bb:RearCamera") - , m_previewIsVideo(true) - , m_surface(0) - , m_captureImageDriveMode(QCameraImageCapture::SingleImageCapture) - , m_lastImageCaptureId(0) - , m_captureDestination(QCameraImageCapture::CaptureToFile) - , m_videoState(QMediaRecorder::StoppedState) - , m_videoStatus(QMediaRecorder::LoadedStatus) - , m_handle(CAMERA_HANDLE_INVALID) - , m_windowGrabber(new WindowGrabber(this)) -{ - connect(this, SIGNAL(statusChanged(QCamera::Status)), SLOT(updateReadyForCapture())); - connect(this, SIGNAL(captureModeChanged(QCamera::CaptureModes)), SLOT(updateReadyForCapture())); - connect(m_orientationHandler, SIGNAL(orientationChanged(int)), SLOT(deviceOrientationChanged(int))); - - connect(m_windowGrabber, SIGNAL(frameGrabbed(QImage, int)), SLOT(viewfinderFrameGrabbed(QImage))); -} - -BbCameraSession::~BbCameraSession() -{ - stopViewFinder(); - closeCamera(); -} - -camera_handle_t BbCameraSession::handle() const -{ - return m_handle; -} - -QCamera::State BbCameraSession::state() const -{ - return m_state; -} - -void BbCameraSession::setState(QCamera::State state) -{ - if (m_state == state) - return; - - const QCamera::State previousState = m_state; - - if (previousState == QCamera::UnloadedState) { - if (state == QCamera::LoadedState) { - if (openCamera()) { - m_state = state; - } - } else if (state == QCamera::ActiveState) { - if (openCamera()) { - QMetaObject::invokeMethod(this, "applyConfiguration", Qt::QueuedConnection); - m_state = state; - } - } - } else if (previousState == QCamera::LoadedState) { - if (state == QCamera::UnloadedState) { - closeCamera(); - m_state = state; - } else if (state == QCamera::ActiveState) { - QMetaObject::invokeMethod(this, "applyConfiguration", Qt::QueuedConnection); - m_state = state; - } - } else if (previousState == QCamera::ActiveState) { - if (state == QCamera::LoadedState) { - stopViewFinder(); - m_state = state; - } else if (state == QCamera::UnloadedState) { - stopViewFinder(); - closeCamera(); - m_state = state; - } - } - - if (m_state != previousState) - emit stateChanged(m_state); -} - -QCamera::Status BbCameraSession::status() const -{ - return m_status; -} - -QCamera::CaptureModes BbCameraSession::captureMode() const -{ - return m_captureMode; -} - -void BbCameraSession::setCaptureMode(QCamera::CaptureModes captureMode) -{ - if (m_captureMode == captureMode) - return; - - m_captureMode = captureMode; - emit captureModeChanged(m_captureMode); -} - -bool BbCameraSession::isCaptureModeSupported(QCamera::CaptureModes mode) const -{ - if (m_handle == CAMERA_HANDLE_INVALID) { - // the camera has not been loaded yet via QCamera::load(), so - // we open it temporarily to peek for the supported capture modes - - camera_unit_t unit = CAMERA_UNIT_REAR; - if (m_device == cameraIdentifierFront()) - unit = CAMERA_UNIT_FRONT; - else if (m_device == cameraIdentifierRear()) - unit = CAMERA_UNIT_REAR; - else if (m_device == cameraIdentifierDesktop()) - unit = CAMERA_UNIT_DESKTOP; - - camera_handle_t handle; - const camera_error_t result = camera_open(unit, CAMERA_MODE_RW, &handle); - if (result != CAMERA_EOK) - return true; - - const bool supported = isCaptureModeSupported(handle, mode); - - camera_close(handle); - - return supported; - } else { - return isCaptureModeSupported(m_handle, mode); - } -} - -QByteArray BbCameraSession::cameraIdentifierFront() -{ - return "bb:FrontCamera"; -} - -QByteArray BbCameraSession::cameraIdentifierRear() -{ - return "bb:RearCamera"; -} - -QByteArray BbCameraSession::cameraIdentifierDesktop() -{ - return "bb:DesktopCamera"; -} - -void BbCameraSession::setDevice(const QByteArray &device) -{ - m_device = device; -} - -QByteArray BbCameraSession::device() const -{ - return m_device; -} - -QAbstractVideoSurface* BbCameraSession::surface() const -{ - return m_surface; -} - -void BbCameraSession::setSurface(QAbstractVideoSurface *surface) -{ - QMutexLocker locker(&m_surfaceMutex); - - if (m_surface == surface) - return; - - m_surface = surface; -} - -bool BbCameraSession::isReadyForCapture() const -{ - if (m_captureMode & QCamera::CaptureStillImage) - return (m_status == QCamera::ActiveStatus); - - if (m_captureMode & QCamera::CaptureVideo) - return (m_status == QCamera::ActiveStatus); - - return false; -} - -QCameraImageCapture::DriveMode BbCameraSession::driveMode() const -{ - return m_captureImageDriveMode; -} - -void BbCameraSession::setDriveMode(QCameraImageCapture::DriveMode mode) -{ - m_captureImageDriveMode = mode; -} - -/** - * A helper structure that keeps context data for image capture callbacks. - */ -struct ImageCaptureData -{ - int requestId; - QString fileName; - BbCameraSession *session; -}; - -static void imageCaptureShutterCallback(camera_handle_t handle, void *context) -{ - Q_UNUSED(handle); - - const ImageCaptureData *data = static_cast<ImageCaptureData*>(context); - - // We are inside a worker thread here, so emit imageExposed inside the main thread - QMetaObject::invokeMethod(data->session, "imageExposed", Qt::QueuedConnection, - Q_ARG(int, data->requestId)); -} - -static void imageCaptureImageCallback(camera_handle_t handle, camera_buffer_t *buffer, void *context) -{ - Q_UNUSED(handle); - - QScopedPointer<ImageCaptureData> data(static_cast<ImageCaptureData*>(context)); - - if (buffer->frametype != CAMERA_FRAMETYPE_JPEG) { - // We are inside a worker thread here, so emit error signal inside the main thread - QMetaObject::invokeMethod(data->session, "imageCaptureError", Qt::QueuedConnection, - Q_ARG(int, data->requestId), - Q_ARG(QCameraImageCapture::Error, QCameraImageCapture::FormatError), - Q_ARG(QString, BbCameraSession::tr("Camera provides image in unsupported format"))); - return; - } - - const QByteArray rawData((const char*)buffer->framebuf, buffer->framedesc.jpeg.bufsize); - - QImage image; - const bool ok = image.loadFromData(rawData, "JPG"); - if (!ok) { - const QString errorMessage = BbCameraSession::tr("Could not load JPEG data from frame"); - // We are inside a worker thread here, so emit error signal inside the main thread - QMetaObject::invokeMethod(data->session, "imageCaptureError", Qt::QueuedConnection, - Q_ARG(int, data->requestId), - Q_ARG(QCameraImageCapture::Error, QCameraImageCapture::FormatError), - Q_ARG(QString, errorMessage)); - return; - } - - - // We are inside a worker thread here, so invoke imageCaptured inside the main thread - QMetaObject::invokeMethod(data->session, "imageCaptured", Qt::QueuedConnection, - Q_ARG(int, data->requestId), - Q_ARG(QImage, image), - Q_ARG(QString, data->fileName)); -} - -int BbCameraSession::capture(const QString &fileName) -{ - m_lastImageCaptureId++; - - if (!isReadyForCapture()) { - emit imageCaptureError(m_lastImageCaptureId, QCameraImageCapture::NotReadyError, tr("Camera not ready")); - return m_lastImageCaptureId; - } - - if (m_captureImageDriveMode == QCameraImageCapture::SingleImageCapture) { - // prepare context object for callback - ImageCaptureData *context = new ImageCaptureData; - context->requestId = m_lastImageCaptureId; - context->fileName = fileName; - context->session = this; - - const camera_error_t result = camera_take_photo(m_handle, - imageCaptureShutterCallback, - 0, - 0, - imageCaptureImageCallback, - context, false); - - if (result != CAMERA_EOK) - qWarning() << "Unable to take photo:" << result; - } else { - // TODO: implement burst mode when available in Qt API - } - - return m_lastImageCaptureId; -} - -void BbCameraSession::cancelCapture() -{ - // BB10 API doesn't provide functionality for that -} - -bool BbCameraSession::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const -{ - // capture to buffer, file and both are supported. - return destination & (QCameraImageCapture::CaptureToFile | QCameraImageCapture::CaptureToBuffer); -} - -QCameraImageCapture::CaptureDestinations BbCameraSession::captureDestination() const -{ - return m_captureDestination; -} - -void BbCameraSession::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) -{ - if (m_captureDestination != destination) { - m_captureDestination = destination; - emit captureDestinationChanged(m_captureDestination); - } -} - -QList<QSize> BbCameraSession::supportedResolutions(const QImageEncoderSettings&, bool *continuous) const -{ - if (continuous) - *continuous = false; - - if (m_status == QCamera::UnloadedStatus) - return QList<QSize>(); - - if (m_captureMode & QCamera::CaptureStillImage) { - return supportedResolutions(QCamera::CaptureStillImage); - } else if (m_captureMode & QCamera::CaptureVideo) { - return supportedResolutions(QCamera::CaptureVideo); - } - - return QList<QSize>(); -} - -QImageEncoderSettings BbCameraSession::imageSettings() const -{ - return m_imageEncoderSettings; -} - -void BbCameraSession::setImageSettings(const QImageEncoderSettings &settings) -{ - m_imageEncoderSettings = settings; - if (m_imageEncoderSettings.codec().isEmpty()) - m_imageEncoderSettings.setCodec(QLatin1String("jpeg")); -} - -QUrl BbCameraSession::outputLocation() const -{ - return QUrl::fromLocalFile(m_videoOutputLocation); -} - -bool BbCameraSession::setOutputLocation(const QUrl &location) -{ - m_videoOutputLocation = location.toLocalFile(); - - return true; -} - -QMediaRecorder::State BbCameraSession::videoState() const -{ - return m_videoState; -} - -void BbCameraSession::setVideoState(QMediaRecorder::State state) -{ - if (m_videoState == state) - return; - - const QMediaRecorder::State previousState = m_videoState; - - if (previousState == QMediaRecorder::StoppedState) { - if (state == QMediaRecorder::RecordingState) { - if (startVideoRecording()) { - m_videoState = state; - } - } else if (state == QMediaRecorder::PausedState) { - // do nothing - } - } else if (previousState == QMediaRecorder::RecordingState) { - if (state == QMediaRecorder::StoppedState) { - stopVideoRecording(); - m_videoState = state; - } else if (state == QMediaRecorder::PausedState) { - //TODO: (pause) not supported by BB10 API yet - } - } else if (previousState == QMediaRecorder::PausedState) { - if (state == QMediaRecorder::StoppedState) { - stopVideoRecording(); - m_videoState = state; - } else if (state == QMediaRecorder::RecordingState) { - //TODO: (resume) not supported by BB10 API yet - } - } - - emit videoStateChanged(m_videoState); -} - -QMediaRecorder::Status BbCameraSession::videoStatus() const -{ - return m_videoStatus; -} - -qint64 BbCameraSession::duration() const -{ - return (m_videoRecordingDuration.isValid() ? m_videoRecordingDuration.elapsed() : 0); -} - -void BbCameraSession::applyVideoSettings() -{ - if (m_handle == CAMERA_HANDLE_INVALID) - return; - - // apply viewfinder configuration - const QList<QSize> videoOutputResolutions = supportedResolutions(QCamera::CaptureVideo); - - if (!m_videoEncoderSettings.resolution().isValid() || !videoOutputResolutions.contains(m_videoEncoderSettings.resolution())) - m_videoEncoderSettings.setResolution(videoOutputResolutions.first()); - - QSize viewfinderResolution; - - if (m_previewIsVideo) { - // The viewfinder is responsible for encoding the video frames, so the resolutions must match. - viewfinderResolution = m_videoEncoderSettings.resolution(); - } else { - // The frames are encoded separately from the viewfinder, so only the aspect ratio must match. - const QSize videoResolution = m_videoEncoderSettings.resolution(); - const qreal aspectRatio = static_cast<qreal>(videoResolution.width())/static_cast<qreal>(videoResolution.height()); - - QList<QSize> sizes = supportedViewfinderResolutions(QCamera::CaptureVideo); - std::reverse(sizes.begin(), sizes.end()); // use smallest possible resolution - for (const QSize &size : qAsConst(sizes)) { - // search for viewfinder resolution with the same aspect ratio - if (qFuzzyCompare(aspectRatio, (static_cast<qreal>(size.width())/static_cast<qreal>(size.height())))) { - viewfinderResolution = size; - break; - } - } - } - - Q_ASSERT(viewfinderResolution.isValid()); - - const QByteArray windowId = QString().sprintf("qcamera_vf_%p", this).toLatin1(); - m_windowGrabber->setWindowId(windowId); - - const QByteArray windowGroupId = m_windowGrabber->windowGroupId(); - - const int rotationAngle = (360 - m_nativeCameraOrientation); - - camera_error_t result = CAMERA_EOK; - result = camera_set_videovf_property(m_handle, - CAMERA_IMGPROP_WIN_GROUPID, windowGroupId.data(), - CAMERA_IMGPROP_WIN_ID, windowId.data(), - CAMERA_IMGPROP_WIDTH, viewfinderResolution.width(), - CAMERA_IMGPROP_HEIGHT, viewfinderResolution.height(), - CAMERA_IMGPROP_ROTATION, rotationAngle); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to apply video viewfinder settings:" << result; - return; - } - - const QSize resolution = m_videoEncoderSettings.resolution(); - - QString videoCodec = m_videoEncoderSettings.codec(); - if (videoCodec.isEmpty()) - videoCodec = QLatin1String("h264"); - - camera_videocodec_t cameraVideoCodec = CAMERA_VIDEOCODEC_H264; - if (videoCodec == QLatin1String("none")) - cameraVideoCodec = CAMERA_VIDEOCODEC_NONE; - else if (videoCodec == QLatin1String("avc1")) - cameraVideoCodec = CAMERA_VIDEOCODEC_AVC1; - else if (videoCodec == QLatin1String("h264")) - cameraVideoCodec = CAMERA_VIDEOCODEC_H264; - - qreal frameRate = m_videoEncoderSettings.frameRate(); - if (frameRate == 0) { - const QList<qreal> frameRates = supportedFrameRates(QVideoEncoderSettings(), 0); - if (!frameRates.isEmpty()) - frameRate = frameRates.last(); - } - - QString audioCodec = m_audioEncoderSettings.codec(); - if (audioCodec.isEmpty()) - audioCodec = QLatin1String("aac"); - - camera_audiocodec_t cameraAudioCodec = CAMERA_AUDIOCODEC_AAC; - if (audioCodec == QLatin1String("none")) - cameraAudioCodec = CAMERA_AUDIOCODEC_NONE; - else if (audioCodec == QLatin1String("aac")) - cameraAudioCodec = CAMERA_AUDIOCODEC_AAC; - else if (audioCodec == QLatin1String("raw")) - cameraAudioCodec = CAMERA_AUDIOCODEC_RAW; - - result = camera_set_video_property(m_handle, - CAMERA_IMGPROP_WIDTH, resolution.width(), - CAMERA_IMGPROP_HEIGHT, resolution.height(), - CAMERA_IMGPROP_ROTATION, rotationAngle, - CAMERA_IMGPROP_VIDEOCODEC, cameraVideoCodec, - CAMERA_IMGPROP_AUDIOCODEC, cameraAudioCodec); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to apply video settings:" << result; - emit videoError(QMediaRecorder::ResourceError, tr("Unable to apply video settings")); - } -} - -QList<QSize> BbCameraSession::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const -{ - Q_UNUSED(settings); - - if (continuous) - *continuous = false; - - return supportedResolutions(QCamera::CaptureVideo); -} - -QList<qreal> BbCameraSession::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const -{ - Q_UNUSED(settings); - - if (m_handle == CAMERA_HANDLE_INVALID) - return QList<qreal>(); - - int supported = 0; - double rates[20]; - bool maxmin = false; - - /** - * Since in current version of the BB10 platform the video viewfinder encodes the video frames, we use - * the values as returned by camera_get_video_vf_framerates(). - */ - const camera_error_t result = camera_get_video_vf_framerates(m_handle, 20, &supported, rates, &maxmin); - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve supported viewfinder framerates:" << result; - return QList<qreal>(); - } - - QList<qreal> frameRates; - for (int i = 0; i < supported; ++i) - frameRates << rates[i]; - - if (continuous) - *continuous = maxmin; - - return frameRates; -} - -QVideoEncoderSettings BbCameraSession::videoSettings() const -{ - return m_videoEncoderSettings; -} - -void BbCameraSession::setVideoSettings(const QVideoEncoderSettings &settings) -{ - m_videoEncoderSettings = settings; -} - -QAudioEncoderSettings BbCameraSession::audioSettings() const -{ - return m_audioEncoderSettings; -} - -void BbCameraSession::setAudioSettings(const QAudioEncoderSettings &settings) -{ - m_audioEncoderSettings = settings; -} - -void BbCameraSession::updateReadyForCapture() -{ - emit readyForCaptureChanged(isReadyForCapture()); -} - -void BbCameraSession::imageCaptured(int requestId, const QImage &rawImage, const QString &fileName) -{ - QTransform transform; - - // subtract out the native rotation - transform.rotate(m_nativeCameraOrientation); - - // subtract out the current device orientation - if (m_device == cameraIdentifierRear()) - transform.rotate(360 - m_orientationHandler->orientation()); - else - transform.rotate(m_orientationHandler->orientation()); - - const QImage image = rawImage.transformed(transform); - - // Generate snap preview as downscaled image - { - QSize previewSize = image.size(); - int downScaleSteps = 0; - while (previewSize.width() > 800 && downScaleSteps < 8) { - previewSize.rwidth() /= 2; - previewSize.rheight() /= 2; - downScaleSteps++; - } - - const QImage snapPreview = image.scaled(previewSize); - - emit imageCaptured(requestId, snapPreview); - } - - if (m_captureDestination & QCameraImageCapture::CaptureToBuffer) { - QVideoFrame frame(image); - - emit imageAvailable(requestId, frame); - } - - if (m_captureDestination & QCameraImageCapture::CaptureToFile) { - const QString actualFileName = m_mediaStorageLocation.generateFileName(fileName, - QCamera::CaptureStillImage, - QLatin1String("IMG_"), - QLatin1String("jpg")); - - QFile file(actualFileName); - if (file.open(QFile::WriteOnly)) { - if (image.save(&file, "JPG")) { - emit imageSaved(requestId, actualFileName); - } else { - emit imageCaptureError(requestId, QCameraImageCapture::OutOfSpaceError, file.errorString()); - } - } else { - const QString errorMessage = tr("Could not open destination file:\n%1").arg(actualFileName); - emit imageCaptureError(requestId, QCameraImageCapture::ResourceError, errorMessage); - } - } -} - -void BbCameraSession::handleVideoRecordingPaused() -{ - //TODO: implement once BB10 API supports pausing a video -} - -void BbCameraSession::handleVideoRecordingResumed() -{ - if (m_videoStatus == QMediaRecorder::StartingStatus) { - m_videoStatus = QMediaRecorder::RecordingStatus; - emit videoStatusChanged(m_videoStatus); - - m_videoRecordingDuration.restart(); - } -} - -void BbCameraSession::deviceOrientationChanged(int angle) -{ - if (m_handle != CAMERA_HANDLE_INVALID) - camera_set_device_orientation(m_handle, angle); -} - -void BbCameraSession::handleCameraPowerUp() -{ - stopViewFinder(); - startViewFinder(); -} - -void BbCameraSession::viewfinderFrameGrabbed(const QImage &image) -{ - QTransform transform; - - // subtract out the native rotation - transform.rotate(m_nativeCameraOrientation); - - // subtract out the current device orientation - if (m_device == cameraIdentifierRear()) - transform.rotate(360 - m_orientationHandler->viewfinderOrientation()); - else - transform.rotate(m_orientationHandler->viewfinderOrientation()); - - QImage frame = image.copy().transformed(transform); - - QMutexLocker locker(&m_surfaceMutex); - if (m_surface) { - if (frame.size() != m_surface->surfaceFormat().frameSize()) { - m_surface->stop(); - m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_ARGB32)); - } - - QVideoFrame videoFrame(frame); - - m_surface->present(videoFrame); - } -} - -bool BbCameraSession::openCamera() -{ - if (m_handle != CAMERA_HANDLE_INVALID) // camera is already open - return true; - - m_status = QCamera::LoadingStatus; - emit statusChanged(m_status); - - camera_unit_t unit = CAMERA_UNIT_REAR; - if (m_device == cameraIdentifierFront()) - unit = CAMERA_UNIT_FRONT; - else if (m_device == cameraIdentifierRear()) - unit = CAMERA_UNIT_REAR; - else if (m_device == cameraIdentifierDesktop()) - unit = CAMERA_UNIT_DESKTOP; - - camera_error_t result = camera_open(unit, CAMERA_MODE_RW, &m_handle); - if (result != CAMERA_EOK) { - m_handle = CAMERA_HANDLE_INVALID; - m_status = QCamera::UnloadedStatus; - emit statusChanged(m_status); - - qWarning() << "Unable to open camera:" << result; - emit error(QCamera::CameraError, tr("Unable to open camera")); - return false; - } - - result = camera_get_native_orientation(m_handle, &m_nativeCameraOrientation); - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve native camera orientation:" << result; - emit error(QCamera::CameraError, tr("Unable to retrieve native camera orientation")); - return false; - } - - m_previewIsVideo = camera_has_feature(m_handle, CAMERA_FEATURE_PREVIEWISVIDEO); - - m_status = QCamera::LoadedStatus; - emit statusChanged(m_status); - - emit cameraOpened(); - - return true; -} - -void BbCameraSession::closeCamera() -{ - if (m_handle == CAMERA_HANDLE_INVALID) // camera is closed already - return; - - m_status = QCamera::UnloadingStatus; - emit statusChanged(m_status); - - const camera_error_t result = camera_close(m_handle); - if (result != CAMERA_EOK) { - m_status = QCamera::LoadedStatus; - emit statusChanged(m_status); - - qWarning() << "Unable to close camera:" << result; - emit error(QCamera::CameraError, tr("Unable to close camera")); - return; - } - - m_handle = CAMERA_HANDLE_INVALID; - - m_status = QCamera::UnloadedStatus; - emit statusChanged(m_status); -} - -static void viewFinderStatusCallback(camera_handle_t handle, camera_devstatus_t status, uint16_t value, void *context) -{ - Q_UNUSED(handle); - - if (status == CAMERA_STATUS_FOCUS_CHANGE) { - BbCameraSession *session = static_cast<BbCameraSession*>(context); - QMetaObject::invokeMethod(session, "focusStatusChanged", Qt::QueuedConnection, Q_ARG(int, value)); - return; - } else if (status == CAMERA_STATUS_POWERUP) { - BbCameraSession *session = static_cast<BbCameraSession*>(context); - QMetaObject::invokeMethod(session, "handleCameraPowerUp", Qt::QueuedConnection); - } -} - -bool BbCameraSession::startViewFinder() -{ - m_status = QCamera::StartingStatus; - emit statusChanged(m_status); - - QSize viewfinderResolution; - camera_error_t result = CAMERA_EOK; - if (m_captureMode & QCamera::CaptureStillImage) { - result = camera_start_photo_viewfinder(m_handle, 0, viewFinderStatusCallback, this); - viewfinderResolution = currentViewfinderResolution(QCamera::CaptureStillImage); - } else if (m_captureMode & QCamera::CaptureVideo) { - result = camera_start_video_viewfinder(m_handle, 0, viewFinderStatusCallback, this); - viewfinderResolution = currentViewfinderResolution(QCamera::CaptureVideo); - } - - if (result != CAMERA_EOK) { - qWarning() << "Unable to start viewfinder:" << result; - return false; - } - - const int angle = m_orientationHandler->viewfinderOrientation(); - - const QSize rotatedSize = ((angle == 0 || angle == 180) ? viewfinderResolution - : viewfinderResolution.transposed()); - - m_surfaceMutex.lock(); - if (m_surface) { - const bool ok = m_surface->start(QVideoSurfaceFormat(rotatedSize, QVideoFrame::Format_ARGB32)); - if (!ok) - qWarning() << "Unable to start camera viewfinder surface"; - } - m_surfaceMutex.unlock(); - - m_status = QCamera::ActiveStatus; - emit statusChanged(m_status); - - return true; -} - -void BbCameraSession::stopViewFinder() -{ - m_windowGrabber->stop(); - - m_status = QCamera::StoppingStatus; - emit statusChanged(m_status); - - m_surfaceMutex.lock(); - if (m_surface) { - m_surface->stop(); - } - m_surfaceMutex.unlock(); - - camera_error_t result = CAMERA_EOK; - if (m_captureMode & QCamera::CaptureStillImage) - result = camera_stop_photo_viewfinder(m_handle); - else if (m_captureMode & QCamera::CaptureVideo) - result = camera_stop_video_viewfinder(m_handle); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to stop viewfinder:" << result; - return; - } - - m_status = QCamera::LoadedStatus; - emit statusChanged(m_status); -} - -void BbCameraSession::applyConfiguration() -{ - if (m_captureMode & QCamera::CaptureStillImage) { - const QList<QSize> photoOutputResolutions = supportedResolutions(QCamera::CaptureStillImage); - - if (!m_imageEncoderSettings.resolution().isValid() || !photoOutputResolutions.contains(m_imageEncoderSettings.resolution())) - m_imageEncoderSettings.setResolution(photoOutputResolutions.first()); - - const QSize photoResolution = m_imageEncoderSettings.resolution(); - const qreal aspectRatio = static_cast<qreal>(photoResolution.width())/static_cast<qreal>(photoResolution.height()); - - // apply viewfinder configuration - QSize viewfinderResolution; - QList<QSize> sizes = supportedViewfinderResolutions(QCamera::CaptureStillImage); - std::reverse(sizes.begin(), sizes.end()); // use smallest possible resolution - for (const QSize &size : qAsConst(sizes)) { - // search for viewfinder resolution with the same aspect ratio - if (qFuzzyCompare(aspectRatio, (static_cast<qreal>(size.width())/static_cast<qreal>(size.height())))) { - viewfinderResolution = size; - break; - } - } - - Q_ASSERT(viewfinderResolution.isValid()); - - const QByteArray windowId = QString().sprintf("qcamera_vf_%p", this).toLatin1(); - m_windowGrabber->setWindowId(windowId); - - const QByteArray windowGroupId = m_windowGrabber->windowGroupId(); - - camera_error_t result = camera_set_photovf_property(m_handle, - CAMERA_IMGPROP_WIN_GROUPID, windowGroupId.data(), - CAMERA_IMGPROP_WIN_ID, windowId.data(), - CAMERA_IMGPROP_WIDTH, viewfinderResolution.width(), - CAMERA_IMGPROP_HEIGHT, viewfinderResolution.height(), - CAMERA_IMGPROP_FORMAT, CAMERA_FRAMETYPE_NV12, - CAMERA_IMGPROP_ROTATION, 360 - m_nativeCameraOrientation); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to apply photo viewfinder settings:" << result; - return; - } - - - int jpegQuality = 100; - switch (m_imageEncoderSettings.quality()) { - case QMultimedia::VeryLowQuality: - jpegQuality = 20; - break; - case QMultimedia::LowQuality: - jpegQuality = 40; - break; - case QMultimedia::NormalQuality: - jpegQuality = 60; - break; - case QMultimedia::HighQuality: - jpegQuality = 80; - break; - case QMultimedia::VeryHighQuality: - jpegQuality = 100; - break; - } - - // apply photo configuration - result = camera_set_photo_property(m_handle, - CAMERA_IMGPROP_WIDTH, photoResolution.width(), - CAMERA_IMGPROP_HEIGHT, photoResolution.height(), - CAMERA_IMGPROP_JPEGQFACTOR, jpegQuality, - CAMERA_IMGPROP_ROTATION, 360 - m_nativeCameraOrientation); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to apply photo settings:" << result; - return; - } - - } else if (m_captureMode & QCamera::CaptureVideo) { - applyVideoSettings(); - } - - startViewFinder(); -} - -static void videoRecordingStatusCallback(camera_handle_t handle, camera_devstatus_t status, uint16_t value, void *context) -{ - Q_UNUSED(handle); - Q_UNUSED(value); - - if (status == CAMERA_STATUS_VIDEO_PAUSE) { - BbCameraSession *session = static_cast<BbCameraSession*>(context); - QMetaObject::invokeMethod(session, "handleVideoRecordingPaused", Qt::QueuedConnection); - } else if (status == CAMERA_STATUS_VIDEO_RESUME) { - BbCameraSession *session = static_cast<BbCameraSession*>(context); - QMetaObject::invokeMethod(session, "handleVideoRecordingResumed", Qt::QueuedConnection); - } -} - -bool BbCameraSession::startVideoRecording() -{ - m_videoRecordingDuration.invalidate(); - - m_videoStatus = QMediaRecorder::StartingStatus; - emit videoStatusChanged(m_videoStatus); - - if (m_videoOutputLocation.isEmpty()) - m_videoOutputLocation = m_mediaStorageLocation.generateFileName(QLatin1String("VID_"), m_mediaStorageLocation.defaultDir(QCamera::CaptureVideo), QLatin1String("mp4")); - - emit actualLocationChanged(m_videoOutputLocation); - - const camera_error_t result = camera_start_video(m_handle, QFile::encodeName(m_videoOutputLocation), 0, videoRecordingStatusCallback, this); - if (result != CAMERA_EOK) { - m_videoStatus = QMediaRecorder::LoadedStatus; - emit videoStatusChanged(m_videoStatus); - - emit videoError(QMediaRecorder::ResourceError, tr("Unable to start video recording")); - return false; - } - - return true; -} - -void BbCameraSession::stopVideoRecording() -{ - m_videoStatus = QMediaRecorder::FinalizingStatus; - emit videoStatusChanged(m_videoStatus); - - const camera_error_t result = camera_stop_video(m_handle); - if (result != CAMERA_EOK) { - emit videoError(QMediaRecorder::ResourceError, tr("Unable to stop video recording")); - } - - m_videoStatus = QMediaRecorder::LoadedStatus; - emit videoStatusChanged(m_videoStatus); - - m_videoRecordingDuration.invalidate(); -} - -bool BbCameraSession::isCaptureModeSupported(camera_handle_t handle, QCamera::CaptureModes mode) const -{ - if (mode & QCamera::CaptureStillImage) - return camera_has_feature(handle, CAMERA_FEATURE_PHOTO); - - if (mode & QCamera::CaptureVideo) - return camera_has_feature(handle, CAMERA_FEATURE_VIDEO); - - return false; -} - -QList<QSize> BbCameraSession::supportedResolutions(QCamera::CaptureMode mode) const -{ - Q_ASSERT(m_handle != CAMERA_HANDLE_INVALID); - - QList<QSize> list; - - camera_error_t result = CAMERA_EOK; - camera_res_t resolutions[20]; - unsigned int supported = 0; - - if (mode == QCamera::CaptureStillImage) - result = camera_get_photo_output_resolutions(m_handle, CAMERA_FRAMETYPE_JPEG, 20, &supported, resolutions); - else if (mode == QCamera::CaptureVideo) - result = camera_get_video_output_resolutions(m_handle, 20, &supported, resolutions); - - if (result != CAMERA_EOK) - return list; - - for (unsigned int i = 0; i < supported; ++i) - list << QSize(resolutions[i].width, resolutions[i].height); - - return list; -} - -QList<QSize> BbCameraSession::supportedViewfinderResolutions(QCamera::CaptureMode mode) const -{ - Q_ASSERT(m_handle != CAMERA_HANDLE_INVALID); - - QList<QSize> list; - - camera_error_t result = CAMERA_EOK; - camera_res_t resolutions[20]; - unsigned int supported = 0; - - if (mode == QCamera::CaptureStillImage) - result = camera_get_photo_vf_resolutions(m_handle, 20, &supported, resolutions); - else if (mode == QCamera::CaptureVideo) - result = camera_get_video_vf_resolutions(m_handle, 20, &supported, resolutions); - - if (result != CAMERA_EOK) - return list; - - for (unsigned int i = 0; i < supported; ++i) - list << QSize(resolutions[i].width, resolutions[i].height); - - return list; -} - -QSize BbCameraSession::currentViewfinderResolution(QCamera::CaptureMode mode) const -{ - Q_ASSERT(m_handle != CAMERA_HANDLE_INVALID); - - camera_error_t result = CAMERA_EOK; - int width = 0; - int height = 0; - - if (mode == QCamera::CaptureStillImage) - result = camera_get_photovf_property(m_handle, CAMERA_IMGPROP_WIDTH, &width, - CAMERA_IMGPROP_HEIGHT, &height); - else if (mode == QCamera::CaptureVideo) - result = camera_get_videovf_property(m_handle, CAMERA_IMGPROP_WIDTH, &width, - CAMERA_IMGPROP_HEIGHT, &height); - - if (result != CAMERA_EOK) - return QSize(); - - return QSize(width, height); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbcamerasession.h b/src/plugins/qnx/camera/bbcamerasession.h deleted file mode 100644 index 70523f1e3..000000000 --- a/src/plugins/qnx/camera/bbcamerasession.h +++ /dev/null @@ -1,215 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBCAMERASESSION_H -#define BBCAMERASESSION_H - -#include "bbmediastoragelocation.h" - -#include <QCamera> -#include <QCameraImageCapture> -#include <QCameraViewfinderSettingsControl> -#include <QElapsedTimer> -#include <QMediaRecorder> -#include <QMutex> -#include <QObject> -#include <QPointer> - -#include <camera/camera_api.h> - -QT_BEGIN_NAMESPACE - -class BbCameraOrientationHandler; -class WindowGrabber; - -class BbCameraSession : public QObject -{ - Q_OBJECT -public: - explicit BbCameraSession(QObject *parent = 0); - ~BbCameraSession(); - - camera_handle_t handle() const; - - // camera control - QCamera::State state() const; - void setState(QCamera::State state); - QCamera::Status status() const; - QCamera::CaptureModes captureMode() const; - void setCaptureMode(QCamera::CaptureModes); - bool isCaptureModeSupported(QCamera::CaptureModes mode) const; - - // video device selector control - static QByteArray cameraIdentifierFront(); - static QByteArray cameraIdentifierRear(); - static QByteArray cameraIdentifierDesktop(); - - void setDevice(const QByteArray &device); - QByteArray device() const; - - // video renderer control - QAbstractVideoSurface *surface() const; - void setSurface(QAbstractVideoSurface *surface); - - // image capture control - bool isReadyForCapture() const; - QCameraImageCapture::DriveMode driveMode() const; - void setDriveMode(QCameraImageCapture::DriveMode mode); - int capture(const QString &fileName); - void cancelCapture(); - - // capture destination control - bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const; - QCameraImageCapture::CaptureDestinations captureDestination() const; - void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination); - - // image encoder control - QList<QSize> supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const; - QImageEncoderSettings imageSettings() const; - void setImageSettings(const QImageEncoderSettings &settings); - - // media recorder control - QUrl outputLocation() const; - bool setOutputLocation(const QUrl &location); - QMediaRecorder::State videoState() const; - void setVideoState(QMediaRecorder::State state); - QMediaRecorder::Status videoStatus() const; - qint64 duration() const; - void applyVideoSettings(); - - // video encoder settings control - QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const; - QList<qreal> supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const; - QVideoEncoderSettings videoSettings() const; - void setVideoSettings(const QVideoEncoderSettings &settings); - - // audio encoder settings control - QAudioEncoderSettings audioSettings() const; - void setAudioSettings(const QAudioEncoderSettings &settings); - -Q_SIGNALS: - // camera control - void statusChanged(QCamera::Status); - void stateChanged(QCamera::State); - void error(int error, const QString &errorString); - void captureModeChanged(QCamera::CaptureModes); - - // image capture control - void readyForCaptureChanged(bool); - void imageExposed(int id); - void imageCaptured(int id, const QImage &preview); - void imageMetadataAvailable(int id, const QString &key, const QVariant &value); - void imageAvailable(int id, const QVideoFrame &buffer); - void imageSaved(int id, const QString &fileName); - void imageCaptureError(int id, int error, const QString &errorString); - - // capture destination control - void captureDestinationChanged(QCameraImageCapture::CaptureDestinations destination); - - // media recorder control - void videoStateChanged(QMediaRecorder::State state); - void videoStatusChanged(QMediaRecorder::Status status); - void durationChanged(qint64 duration); - void actualLocationChanged(const QUrl &location); - void videoError(int error, const QString &errorString); - - void cameraOpened(); - void focusStatusChanged(int status); - -private slots: - void updateReadyForCapture(); - void imageCaptured(int, const QImage&, const QString&); - void handleVideoRecordingPaused(); - void handleVideoRecordingResumed(); - void deviceOrientationChanged(int); - void handleCameraPowerUp(); - void viewfinderFrameGrabbed(const QImage &image); - void applyConfiguration(); - -private: - bool openCamera(); - void closeCamera(); - bool startViewFinder(); - void stopViewFinder(); - bool startVideoRecording(); - void stopVideoRecording(); - - bool isCaptureModeSupported(camera_handle_t handle, QCamera::CaptureModes mode) const; - QList<QSize> supportedResolutions(QCamera::CaptureMode mode) const; - QList<QSize> supportedViewfinderResolutions(QCamera::CaptureMode mode) const; - QSize currentViewfinderResolution(QCamera::CaptureMode mode) const; - - quint32 m_nativeCameraOrientation; - BbCameraOrientationHandler* m_orientationHandler; - - QCamera::Status m_status; - QCamera::State m_state; - QCamera::CaptureModes m_captureMode; - - QByteArray m_device; - bool m_previewIsVideo; - - QPointer<QAbstractVideoSurface> m_surface; - QMutex m_surfaceMutex; - - QCameraImageCapture::DriveMode m_captureImageDriveMode; - int m_lastImageCaptureId; - QCameraImageCapture::CaptureDestinations m_captureDestination; - - QImageEncoderSettings m_imageEncoderSettings; - - QString m_videoOutputLocation; - QMediaRecorder::State m_videoState; - QMediaRecorder::Status m_videoStatus; - QElapsedTimer m_videoRecordingDuration; - - QVideoEncoderSettings m_videoEncoderSettings; - QAudioEncoderSettings m_audioEncoderSettings; - - BbMediaStorageLocation m_mediaStorageLocation; - - camera_handle_t m_handle; - - WindowGrabber* m_windowGrabber; -}; - -QDebug operator<<(QDebug debug, camera_error_t error); - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.cpp b/src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.cpp deleted file mode 100644 index 5e3a902c2..000000000 --- a/src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbcameravideoencodersettingscontrol.h" - -#include "bbcamerasession.h" - -QT_BEGIN_NAMESPACE - -BbCameraVideoEncoderSettingsControl::BbCameraVideoEncoderSettingsControl(BbCameraSession *session, QObject *parent) - : QVideoEncoderSettingsControl(parent) - , m_session(session) -{ -} - -QList<QSize> BbCameraVideoEncoderSettingsControl::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const -{ - return m_session->supportedResolutions(settings, continuous); -} - -QList<qreal> BbCameraVideoEncoderSettingsControl::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const -{ - return m_session->supportedFrameRates(settings, continuous); -} - -QStringList BbCameraVideoEncoderSettingsControl::supportedVideoCodecs() const -{ - return QStringList() << QLatin1String("none") << QLatin1String("avc1") << QLatin1String("h264"); -} - -QString BbCameraVideoEncoderSettingsControl::videoCodecDescription(const QString &codecName) const -{ - if (codecName == QLatin1String("none")) - return tr("No compression"); - else if (codecName == QLatin1String("avc1")) - return tr("AVC1 compression"); - else if (codecName == QLatin1String("h264")) - return tr("H264 compression"); - - return QString(); -} - -QVideoEncoderSettings BbCameraVideoEncoderSettingsControl::videoSettings() const -{ - return m_session->videoSettings(); -} - -void BbCameraVideoEncoderSettingsControl::setVideoSettings(const QVideoEncoderSettings &settings) -{ - m_session->setVideoSettings(settings); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.h b/src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.h deleted file mode 100644 index f67196be1..000000000 --- a/src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBCAMERAVIDEOENCODERSETTINGSCONTROL_H -#define BBCAMERAVIDEOENCODERSETTINGSCONTROL_H - -#include <qvideoencodersettingscontrol.h> - -QT_BEGIN_NAMESPACE - -class BbCameraSession; - -class BbCameraVideoEncoderSettingsControl : public QVideoEncoderSettingsControl -{ - Q_OBJECT -public: - explicit BbCameraVideoEncoderSettingsControl(BbCameraSession *session, QObject *parent = 0); - - QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous = 0) const override; - QList<qreal> supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous = 0) const override; - QStringList supportedVideoCodecs() const override; - QString videoCodecDescription(const QString &codecName) const override; - QVideoEncoderSettings videoSettings() const override; - void setVideoSettings(const QVideoEncoderSettings &settings) override; - -private: - BbCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.cpp b/src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.cpp deleted file mode 100644 index d800ffe13..000000000 --- a/src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbcameraviewfindersettingscontrol.h" - -#include "bbcamerasession.h" - -#include <QDebug> - -QT_BEGIN_NAMESPACE - -BbCameraViewfinderSettingsControl::BbCameraViewfinderSettingsControl(BbCameraSession *session, QObject *parent) - : QCameraViewfinderSettingsControl(parent) - , m_session(session) -{ -} - -bool BbCameraViewfinderSettingsControl::isViewfinderParameterSupported(ViewfinderParameter parameter) const -{ - switch (parameter) { - case QCameraViewfinderSettingsControl::Resolution: - return true; - case QCameraViewfinderSettingsControl::PixelAspectRatio: - return false; - case QCameraViewfinderSettingsControl::MinimumFrameRate: - return true; - case QCameraViewfinderSettingsControl::MaximumFrameRate: - return true; - case QCameraViewfinderSettingsControl::PixelFormat: - return true; - default: - return false; - } -} - -QVariant BbCameraViewfinderSettingsControl::viewfinderParameter(ViewfinderParameter parameter) const -{ - if (parameter == QCameraViewfinderSettingsControl::Resolution) { - camera_error_t result = CAMERA_EOK; - unsigned int width = 0; - unsigned int height = 0; - - if (m_session->captureMode() & QCamera::CaptureStillImage) { - result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_WIDTH, &width, - CAMERA_IMGPROP_HEIGHT, &height); - } else if (m_session->captureMode() & QCamera::CaptureVideo) { - result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_WIDTH, &width, - CAMERA_IMGPROP_HEIGHT, &height); - } - - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve resolution of viewfinder:" << result; - return QVariant(); - } - - return QSize(width, height); - - } else if (parameter == QCameraViewfinderSettingsControl::MinimumFrameRate) { - camera_error_t result = CAMERA_EOK; - double minimumFrameRate = 0; - - if (m_session->captureMode() & QCamera::CaptureStillImage) - result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_MINFRAMERATE, &minimumFrameRate); - else if (m_session->captureMode() & QCamera::CaptureVideo) - result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_MINFRAMERATE, &minimumFrameRate); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve minimum framerate of viewfinder:" << result; - return QVariant(); - } - - return QVariant(static_cast<qreal>(minimumFrameRate)); - - } else if (parameter == QCameraViewfinderSettingsControl::MaximumFrameRate) { - camera_error_t result = CAMERA_EOK; - double maximumFrameRate = 0; - - if (m_session->captureMode() & QCamera::CaptureStillImage) - result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_FRAMERATE, &maximumFrameRate); - else if (m_session->captureMode() & QCamera::CaptureVideo) - result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_FRAMERATE, &maximumFrameRate); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve maximum framerate of viewfinder:" << result; - return QVariant(); - } - - return QVariant(static_cast<qreal>(maximumFrameRate)); - } else if (parameter == QCameraViewfinderSettingsControl::PixelFormat) { - camera_error_t result = CAMERA_EOK; - camera_frametype_t format = CAMERA_FRAMETYPE_UNSPECIFIED; - - if (m_session->captureMode() & QCamera::CaptureStillImage) - result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_FORMAT, &format); - else if (m_session->captureMode() & QCamera::CaptureVideo) - result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_FORMAT, &format); - - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve pixel format of viewfinder:" << result; - return QVariant(); - } - - switch (format) { - case CAMERA_FRAMETYPE_UNSPECIFIED: - return QVideoFrame::Format_Invalid; - case CAMERA_FRAMETYPE_NV12: - return QVideoFrame::Format_NV12; - case CAMERA_FRAMETYPE_RGB8888: - return QVideoFrame::Format_ARGB32; - case CAMERA_FRAMETYPE_RGB888: - return QVideoFrame::Format_RGB24; - case CAMERA_FRAMETYPE_JPEG: - return QVideoFrame::Format_Jpeg; - case CAMERA_FRAMETYPE_GRAY8: - return QVideoFrame::Format_Y8; - case CAMERA_FRAMETYPE_METADATA: - return QVideoFrame::Format_Invalid; - case CAMERA_FRAMETYPE_BAYER: - return QVideoFrame::Format_Invalid; - case CAMERA_FRAMETYPE_CBYCRY: - return QVideoFrame::Format_Invalid; - case CAMERA_FRAMETYPE_COMPRESSEDVIDEO: - return QVideoFrame::Format_Invalid; - case CAMERA_FRAMETYPE_COMPRESSEDAUDIO: - return QVideoFrame::Format_Invalid; - default: - return QVideoFrame::Format_Invalid; - } - } - - return QVariant(); -} - -void BbCameraViewfinderSettingsControl::setViewfinderParameter(ViewfinderParameter parameter, const QVariant &value) -{ - if (parameter == QCameraViewfinderSettingsControl::Resolution) { - camera_error_t result = CAMERA_EOK; - const QSize size = value.toSize(); - - if (m_session->captureMode() & QCamera::CaptureStillImage) { - result = camera_set_photovf_property(m_session->handle(), CAMERA_IMGPROP_WIDTH, size.width(), - CAMERA_IMGPROP_HEIGHT, size.height()); - } else if (m_session->captureMode() & QCamera::CaptureVideo) { - result = camera_set_videovf_property(m_session->handle(), CAMERA_IMGPROP_WIDTH, size.width(), - CAMERA_IMGPROP_HEIGHT, size.height()); - } - - if (result != CAMERA_EOK) - qWarning() << "Unable to set resolution of viewfinder:" << result; - - } else if (parameter == QCameraViewfinderSettingsControl::MinimumFrameRate) { - camera_error_t result = CAMERA_EOK; - const double minimumFrameRate = value.toReal(); - - if (m_session->captureMode() & QCamera::CaptureStillImage) - result = camera_set_photovf_property(m_session->handle(), CAMERA_IMGPROP_MINFRAMERATE, minimumFrameRate); - else if (m_session->captureMode() & QCamera::CaptureVideo) - result = camera_set_videovf_property(m_session->handle(), CAMERA_IMGPROP_MINFRAMERATE, minimumFrameRate); - - if (result != CAMERA_EOK) - qWarning() << "Unable to set minimum framerate of viewfinder:" << result; - - } else if (parameter == QCameraViewfinderSettingsControl::MaximumFrameRate) { - camera_error_t result = CAMERA_EOK; - const double maximumFrameRate = value.toReal(); - - if (m_session->captureMode() & QCamera::CaptureStillImage) - result = camera_set_photovf_property(m_session->handle(), CAMERA_IMGPROP_FRAMERATE, maximumFrameRate); - else if (m_session->captureMode() & QCamera::CaptureVideo) - result = camera_set_videovf_property(m_session->handle(), CAMERA_IMGPROP_FRAMERATE, maximumFrameRate); - - if (result != CAMERA_EOK) - qWarning() << "Unable to set maximum framerate of viewfinder:" << result; - - } else if (parameter == QCameraViewfinderSettingsControl::PixelFormat) { - camera_error_t result = CAMERA_EOK; - camera_frametype_t format = CAMERA_FRAMETYPE_UNSPECIFIED; - - switch (value.value<QVideoFrame::PixelFormat>()) { - case QVideoFrame::Format_NV12: - format = CAMERA_FRAMETYPE_NV12; - break; - case QVideoFrame::Format_ARGB32: - format = CAMERA_FRAMETYPE_RGB8888; - break; - case QVideoFrame::Format_RGB24: - format = CAMERA_FRAMETYPE_RGB888; - break; - case QVideoFrame::Format_Jpeg: - format = CAMERA_FRAMETYPE_JPEG; - break; - case QVideoFrame::Format_Y8: - format = CAMERA_FRAMETYPE_GRAY8; - break; - default: - format = CAMERA_FRAMETYPE_UNSPECIFIED; - break; - } - - if (m_session->captureMode() & QCamera::CaptureStillImage) - result = camera_set_photovf_property(m_session->handle(), CAMERA_IMGPROP_FORMAT, format); - else if (m_session->captureMode() & QCamera::CaptureVideo) - result = camera_set_videovf_property(m_session->handle(), CAMERA_IMGPROP_FORMAT, format); - - if (result != CAMERA_EOK) - qWarning() << "Unable to set pixel format of viewfinder:" << result; - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.h b/src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.h deleted file mode 100644 index 7a8e57a13..000000000 --- a/src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBCAMERAVIEWVINDERSETTINGSCONTROL_H -#define BBCAMERAVIEWVINDERSETTINGSCONTROL_H - -#include <qcameraviewfindersettingscontrol.h> - -QT_BEGIN_NAMESPACE - -class BbCameraSession; - -class BbCameraViewfinderSettingsControl : public QCameraViewfinderSettingsControl -{ - Q_OBJECT -public: - explicit BbCameraViewfinderSettingsControl(BbCameraSession *session, QObject *parent = 0); - - bool isViewfinderParameterSupported(ViewfinderParameter parameter) const override; - QVariant viewfinderParameter(ViewfinderParameter parameter) const override; - void setViewfinderParameter(ViewfinderParameter parameter, const QVariant &value) override; - -private: - BbCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbimageencodercontrol.cpp b/src/plugins/qnx/camera/bbimageencodercontrol.cpp deleted file mode 100644 index cd564a1d4..000000000 --- a/src/plugins/qnx/camera/bbimageencodercontrol.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbimageencodercontrol.h" - -#include "bbcamerasession.h" - -QT_BEGIN_NAMESPACE - -BbImageEncoderControl::BbImageEncoderControl(BbCameraSession *session, QObject *parent) - : QImageEncoderControl(parent) - , m_session(session) -{ -} - -QStringList BbImageEncoderControl::supportedImageCodecs() const -{ - return QStringList() << QLatin1String("jpeg"); -} - -QString BbImageEncoderControl::imageCodecDescription(const QString &codecName) const -{ - if (codecName == QLatin1String("jpeg")) - return tr("JPEG image"); - - return QString(); -} - -QList<QSize> BbImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const -{ - return m_session->supportedResolutions(settings, continuous); -} - -QImageEncoderSettings BbImageEncoderControl::imageSettings() const -{ - return m_session->imageSettings(); -} - -void BbImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings) -{ - m_session->setImageSettings(settings); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbimageencodercontrol.h b/src/plugins/qnx/camera/bbimageencodercontrol.h deleted file mode 100644 index bb246def6..000000000 --- a/src/plugins/qnx/camera/bbimageencodercontrol.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBIMAGEENCODERCONTROL_H -#define BBIMAGEENCODERCONTROL_H - -#include <qimageencodercontrol.h> - -QT_BEGIN_NAMESPACE - -class BbCameraSession; - -class BbImageEncoderControl : public QImageEncoderControl -{ - Q_OBJECT -public: - explicit BbImageEncoderControl(BbCameraSession *session, QObject *parent = 0); - - QStringList supportedImageCodecs() const override; - QString imageCodecDescription(const QString &codecName) const override; - QList<QSize> supportedResolutions(const QImageEncoderSettings &settings, bool *continuous = 0) const override; - QImageEncoderSettings imageSettings() const override; - void setImageSettings(const QImageEncoderSettings &settings) override; - -private: - BbCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbmediastoragelocation.cpp b/src/plugins/qnx/camera/bbmediastoragelocation.cpp deleted file mode 100644 index c3aaed55d..000000000 --- a/src/plugins/qnx/camera/bbmediastoragelocation.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbmediastoragelocation.h" - -#include <QStandardPaths> - -QT_BEGIN_NAMESPACE - -BbMediaStorageLocation::BbMediaStorageLocation() -{ -} - -QDir BbMediaStorageLocation::defaultDir(QCamera::CaptureMode mode) const -{ - QStringList dirCandidates; - - dirCandidates << QLatin1String("shared/camera"); - - if (mode == QCamera::CaptureVideo) { - dirCandidates << QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); - } else { - dirCandidates << QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); - } - - dirCandidates << QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); - dirCandidates << QDir::homePath(); - dirCandidates << QDir::currentPath(); - dirCandidates << QDir::tempPath(); - - for (const QString &path : qAsConst(dirCandidates)) { - if (QFileInfo(path).isWritable()) - return QDir(path); - } - - return QDir(); -} - -QString BbMediaStorageLocation::generateFileName(const QString &requestedName, QCamera::CaptureMode mode, const QString &prefix, const QString &extension) const -{ - if (requestedName.isEmpty()) - return generateFileName(prefix, defaultDir(mode), extension); - - if (QFileInfo(requestedName).isDir()) - return generateFileName(prefix, QDir(requestedName), extension); - - return requestedName; -} - -QString BbMediaStorageLocation::generateFileName(const QString &prefix, const QDir &dir, const QString &extension) const -{ - const QString lastMediaKey = dir.absolutePath() + QLatin1Char(' ') + prefix + QLatin1Char(' ') + extension; - qint64 lastMediaIndex = m_lastUsedIndex.value(lastMediaKey, 0); - - if (lastMediaIndex == 0) { - // first run, find the maximum media number during the fist capture - const auto list = dir.entryList(QStringList() << QString("%1*.%2").arg(prefix).arg(extension)); - for (const QString &fileName : list) { - const qint64 mediaIndex = QStringView{fileName}.mid(prefix.length(), fileName.size() - prefix.length() - extension.length() - 1).toInt(); - lastMediaIndex = qMax(lastMediaIndex, mediaIndex); - } - } - - // don't just rely on cached lastMediaIndex value, - // someone else may create a file after camera started - while (true) { - const QString name = QString("%1%2.%3").arg(prefix) - .arg(lastMediaIndex + 1, 8, 10, QLatin1Char('0')) - .arg(extension); - - const QString path = dir.absoluteFilePath(name); - if (!QFileInfo(path).exists()) { - m_lastUsedIndex[lastMediaKey] = lastMediaIndex + 1; - return path; - } - - lastMediaIndex++; - } - - return QString(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbmediastoragelocation.h b/src/plugins/qnx/camera/bbmediastoragelocation.h deleted file mode 100644 index 8a953c27d..000000000 --- a/src/plugins/qnx/camera/bbmediastoragelocation.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBMEDIASTORAGELOCATION_H -#define BBMEDIASTORAGELOCATION_H - -#include <QCamera> -#include <QDir> -#include <QHash> - -QT_BEGIN_NAMESPACE - -class BbMediaStorageLocation -{ -public: - BbMediaStorageLocation(); - - QDir defaultDir(QCamera::CaptureMode mode) const; - - QString generateFileName(const QString &requestedName, QCamera::CaptureMode mode, const QString &prefix, const QString &extension) const; - QString generateFileName(const QString &prefix, const QDir &dir, const QString &extension) const; - -private: - mutable QHash<QString, qint64> m_lastUsedIndex; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbvideodeviceselectorcontrol.cpp b/src/plugins/qnx/camera/bbvideodeviceselectorcontrol.cpp deleted file mode 100644 index 791c4af54..000000000 --- a/src/plugins/qnx/camera/bbvideodeviceselectorcontrol.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "bbvideodeviceselectorcontrol.h" - -#include "bbcamerasession.h" - -#include <QDebug> - -QT_BEGIN_NAMESPACE - -BbVideoDeviceSelectorControl::BbVideoDeviceSelectorControl(BbCameraSession *session, QObject *parent) - : QVideoDeviceSelectorControl(parent) - , m_session(session) - , m_default(0) - , m_selected(0) -{ - enumerateDevices(&m_devices, &m_descriptions); - - // pre-select the rear camera - const int index = m_devices.indexOf(BbCameraSession::cameraIdentifierRear()); - if (index != -1) - m_default = m_selected = index; -} - -int BbVideoDeviceSelectorControl::deviceCount() const -{ - return m_devices.count(); -} - -QString BbVideoDeviceSelectorControl::deviceName(int index) const -{ - if (index < 0 || index >= m_devices.count()) - return QString(); - - return QString::fromUtf8(m_devices.at(index)); -} - -QString BbVideoDeviceSelectorControl::deviceDescription(int index) const -{ - if (index < 0 || index >= m_descriptions.count()) - return QString(); - - return m_descriptions.at(index); -} - -QCamera::Position BbVideoDeviceSelectorControl::cameraPosition(int index) const -{ - if (deviceName(index) == QString::fromUtf8(BbCameraSession::cameraIdentifierFront())) - return QCamera::FrontFace; - else if (deviceName(index) == QString::fromUtf8(BbCameraSession::cameraIdentifierRear())) - return QCamera::BackFace; - else - return QCamera::UnspecifiedPosition; -} - -int BbVideoDeviceSelectorControl::cameraOrientation(int index) const -{ - return 0; -} - -int BbVideoDeviceSelectorControl::defaultDevice() const -{ - return m_default; -} - -int BbVideoDeviceSelectorControl::selectedDevice() const -{ - return m_selected; -} - -void BbVideoDeviceSelectorControl::enumerateDevices(QList<QByteArray> *devices, QStringList *descriptions) -{ - devices->clear(); - descriptions->clear(); - - camera_unit_t cameras[10]; - - unsigned int knownCameras = 0; - const camera_error_t result = camera_get_supported_cameras(10, &knownCameras, cameras); - if (result != CAMERA_EOK) { - qWarning() << "Unable to retrieve supported camera types:" << result; - return; - } - - for (unsigned int i = 0; i < knownCameras; ++i) { - switch (cameras[i]) { - case CAMERA_UNIT_FRONT: - devices->append(BbCameraSession::cameraIdentifierFront()); - descriptions->append(tr("Front Camera")); - break; - case CAMERA_UNIT_REAR: - devices->append(BbCameraSession::cameraIdentifierRear()); - descriptions->append(tr("Rear Camera")); - break; - case CAMERA_UNIT_DESKTOP: - devices->append(BbCameraSession::cameraIdentifierDesktop()); - descriptions->append(tr("Desktop Camera")); - break; - default: - break; - } - } -} - -void BbVideoDeviceSelectorControl::setSelectedDevice(int index) -{ - if (index < 0 || index >= m_devices.count()) - return; - - if (!m_session) - return; - - const QByteArray device = m_devices.at(index); - if (device == m_session->device()) - return; - - m_session->setDevice(device); - m_selected = index; - - emit selectedDeviceChanged(QString::fromUtf8(device)); - emit selectedDeviceChanged(index); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbvideodeviceselectorcontrol.h b/src/plugins/qnx/camera/bbvideodeviceselectorcontrol.h deleted file mode 100644 index fdaa7fc0d..000000000 --- a/src/plugins/qnx/camera/bbvideodeviceselectorcontrol.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBVIDEODEVICESELECTORCONTROL_H -#define BBVIDEODEVICESELECTORCONTROL_H - -#include <qvideodeviceselectorcontrol.h> -#include <QStringList> - -QT_BEGIN_NAMESPACE - -class BbCameraSession; - -class BbVideoDeviceSelectorControl : public QVideoDeviceSelectorControl -{ - Q_OBJECT -public: - explicit BbVideoDeviceSelectorControl(BbCameraSession *session, QObject *parent = 0); - - int deviceCount() const override; - QString deviceName(int index) const override; - QString deviceDescription(int index) const override; - QCamera::Position cameraPosition(int index) const; - int cameraOrientation(int index) const; - - int defaultDevice() const override; - int selectedDevice() const override; - - static void enumerateDevices(QList<QByteArray> *devices, QStringList *descriptions); - -public Q_SLOTS: - void setSelectedDevice(int index) override; - -private: - BbCameraSession* m_session; - - QList<QByteArray> m_devices; - QStringList m_descriptions; - - int m_default; - int m_selected; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/bbvideorenderercontrol.cpp b/src/plugins/qnx/camera/bbvideorenderercontrol.cpp deleted file mode 100644 index fd271c9de..000000000 --- a/src/plugins/qnx/camera/bbvideorenderercontrol.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "bbvideorenderercontrol.h" - -#include "bbcamerasession.h" - -QT_BEGIN_NAMESPACE - -BbVideoRendererControl::BbVideoRendererControl(BbCameraSession *session, QObject *parent) - : QVideoRendererControl(parent) - , m_session(session) -{ -} - -QAbstractVideoSurface* BbVideoRendererControl::surface() const -{ - return m_session->surface(); -} - -void BbVideoRendererControl::setSurface(QAbstractVideoSurface *surface) -{ - m_session->setSurface(surface); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/camera/bbvideorenderercontrol.h b/src/plugins/qnx/camera/bbvideorenderercontrol.h deleted file mode 100644 index 441ff369d..000000000 --- a/src/plugins/qnx/camera/bbvideorenderercontrol.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef BBVIDEORENDERERCONTROL_H -#define BBVIDEORENDERERCONTROL_H - -#include <qvideorenderercontrol.h> - -QT_BEGIN_NAMESPACE - -class BbCameraSession; - -class BbVideoRendererControl : public QVideoRendererControl -{ - Q_OBJECT -public: - explicit BbVideoRendererControl(BbCameraSession *session, QObject *parent = 0); - - QAbstractVideoSurface *surface() const override; - void setSurface(QAbstractVideoSurface *surface) override; - -private: - BbCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/camera/camera.pri b/src/plugins/qnx/camera/camera.pri deleted file mode 100644 index a3fde711a..000000000 --- a/src/plugins/qnx/camera/camera.pri +++ /dev/null @@ -1,40 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/bbcameraaudioencodersettingscontrol.h \ - $$PWD/bbcameracontrol.h \ - $$PWD/bbcameraexposurecontrol.h \ - $$PWD/bbcamerafocuscontrol.h \ - $$PWD/bbcameraimagecapturecontrol.h \ - $$PWD/bbcameraimageprocessingcontrol.h \ - $$PWD/bbcameramediarecordercontrol.h \ - $$PWD/bbcameraorientationhandler.h \ - $$PWD/bbcameraservice.h \ - $$PWD/bbcamerasession.h \ - $$PWD/bbcameravideoencodersettingscontrol.h \ - $$PWD/bbcameraviewfindersettingscontrol.h \ - $$PWD/bbimageencodercontrol.h \ - $$PWD/bbmediastoragelocation.h \ - $$PWD/bbvideodeviceselectorcontrol.h \ - $$PWD/bbvideorenderercontrol.h - -SOURCES += \ - $$PWD/bbcameraaudioencodersettingscontrol.cpp \ - $$PWD/bbcameracontrol.cpp \ - $$PWD/bbcameraexposurecontrol.cpp \ - $$PWD/bbcamerafocuscontrol.cpp \ - $$PWD/bbcameraimagecapturecontrol.cpp \ - $$PWD/bbcameraimageprocessingcontrol.cpp \ - $$PWD/bbcameramediarecordercontrol.cpp \ - $$PWD/bbcameraorientationhandler.cpp \ - $$PWD/bbcameraservice.cpp \ - $$PWD/bbcamerasession.cpp \ - $$PWD/bbcameravideoencodersettingscontrol.cpp \ - $$PWD/bbcameraviewfindersettingscontrol.cpp \ - $$PWD/bbimageencodercontrol.cpp \ - $$PWD/bbmediastoragelocation.cpp \ - $$PWD/bbvideodeviceselectorcontrol.cpp \ - $$PWD/bbvideorenderercontrol.cpp - -LIBS += -lcamapi -laudio_manager - diff --git a/src/plugins/qnx/common/common.pri b/src/plugins/qnx/common/common.pri deleted file mode 100644 index 1a6693474..000000000 --- a/src/plugins/qnx/common/common.pri +++ /dev/null @@ -1,7 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/windowgrabber.h - -SOURCES += \ - $$PWD/windowgrabber.cpp diff --git a/src/plugins/qnx/common/windowgrabber.cpp b/src/plugins/qnx/common/windowgrabber.cpp deleted file mode 100644 index 65037fcce..000000000 --- a/src/plugins/qnx/common/windowgrabber.cpp +++ /dev/null @@ -1,419 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "windowgrabber.h" - -#include <QAbstractEventDispatcher> -#include <QDebug> -#include <QGuiApplication> -#include <QImage> -#include <QThread> -#include <qpa/qplatformnativeinterface.h> - -#include <QOpenGLContext> -#include <QOpenGLFunctions> - -#include <errno.h> - -QT_BEGIN_NAMESPACE - -static PFNEGLCREATEIMAGEKHRPROC s_eglCreateImageKHR; -static PFNEGLDESTROYIMAGEKHRPROC s_eglDestroyImageKHR; - -WindowGrabber::WindowGrabber(QObject *parent) - : QObject(parent), - m_windowParent(nullptr), - m_screenContext(0), - m_active(false), - m_currentFrame(0), - m_eglImageSupported(false), - m_eglImageCheck(false) -{ - // grab the window frame with 60 frames per second - m_timer.setInterval(1000/60); - - connect(&m_timer, SIGNAL(timeout()), SLOT(triggerUpdate())); - - QCoreApplication::eventDispatcher()->installNativeEventFilter(this); - - for ( int i = 0; i < 2; ++i ) - m_images[i] = 0; - - // Use of EGL images can be disabled by setting QQNX_MM_DISABLE_EGLIMAGE_SUPPORT to something - // non-zero. This is probably useful only to test that this path still works since it results - // in a high CPU load. - if (!s_eglCreateImageKHR && qgetenv("QQNX_MM_DISABLE_EGLIMAGE_SUPPORT").toInt() == 0) { - s_eglCreateImageKHR = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR")); - s_eglDestroyImageKHR = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR")); - } - - QPlatformNativeInterface *const nativeInterface = QGuiApplication::platformNativeInterface(); - if (nativeInterface) { - m_screenContext = static_cast<screen_context_t>( - nativeInterface->nativeResourceForIntegration("screenContext")); - } - - // Create a parent window for the window whose content will be grabbed. Since the - // window is only a buffer conduit, the characteristics of the parent window are - // irrelevant. The contents of the window can be grabbed so long as the window - // joins the parent window's group and the parent window is in this process. - // Using the window that displays this content isn't possible because there's no - // way to reliably retrieve it from this code or any calling code. - screen_create_window(&m_windowParent, m_screenContext); - screen_create_window_group(m_windowParent, nullptr); -} - -WindowGrabber::~WindowGrabber() -{ - screen_destroy_window(m_windowParent); - QCoreApplication::eventDispatcher()->removeNativeEventFilter(this); - cleanup(); -} - -void WindowGrabber::setFrameRate(int frameRate) -{ - m_timer.setInterval(1000/frameRate); -} - - -void WindowGrabber::setWindowId(const QByteArray &windowId) -{ - m_windowId = windowId; -} - -void WindowGrabber::start() -{ - if (m_active) - return; - - if (!m_screenContext) - screen_get_window_property_pv(m_window, SCREEN_PROPERTY_CONTEXT, reinterpret_cast<void**>(&m_screenContext)); - - m_timer.start(); - - m_active = true; -} - -void WindowGrabber::stop() -{ - if (!m_active) - return; - - cleanup(); - - m_timer.stop(); - - m_active = false; -} - -void WindowGrabber::pause() -{ - m_timer.stop(); -} - -void WindowGrabber::resume() -{ - if (!m_active) - return; - - m_timer.start(); -} - -bool WindowGrabber::handleScreenEvent(screen_event_t screen_event) -{ - - int eventType; - if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) { - qWarning() << "WindowGrabber: Failed to query screen event type"; - return false; - } - - if (eventType != SCREEN_EVENT_CREATE) - return false; - - screen_window_t window = 0; - if (screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0) { - qWarning() << "WindowGrabber: Failed to query window property"; - return false; - } - - const int maxIdStrLength = 128; - char idString[maxIdStrLength]; - if (screen_get_window_property_cv(window, SCREEN_PROPERTY_ID_STRING, maxIdStrLength, idString) != 0) { - qWarning() << "WindowGrabber: Failed to query window ID string"; - return false; - } - - // Grab windows that have a non-empty ID string and a matching window id to grab - if (idString[0] != '\0' && m_windowId == idString) { - m_window = window; - start(); - } - - return false; -} - -bool WindowGrabber::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *) -{ - if (eventType == "screen_event_t") { - const screen_event_t event = static_cast<screen_event_t>(message); - return handleScreenEvent(event); - } - - return false; -} - -QByteArray WindowGrabber::windowGroupId() const -{ - char groupName[256]; - memset(groupName, 0, sizeof(groupName)); - screen_get_window_property_cv(m_windowParent, - SCREEN_PROPERTY_GROUP, - sizeof(groupName) - 1, - groupName); - return QByteArray(groupName); -} - -bool WindowGrabber::eglImageSupported() -{ - return m_eglImageSupported; -} - -void WindowGrabber::checkForEglImageExtension() -{ - QOpenGLContext *m_context = QOpenGLContext::currentContext(); - if (!m_context) //Should not happen, because we are called from the render thread - return; - - QByteArray eglExtensions = QByteArray(eglQueryString(eglGetDisplay(EGL_DEFAULT_DISPLAY), - EGL_EXTENSIONS)); - m_eglImageSupported = m_context->hasExtension(QByteArrayLiteral("GL_OES_EGL_image")) - && eglExtensions.contains(QByteArrayLiteral("EGL_KHR_image")) - && s_eglCreateImageKHR && s_eglDestroyImageKHR; - - if (strstr(reinterpret_cast<const char*>(glGetString(GL_VENDOR)), "VMware")) - m_eglImageSupported = false; - - m_eglImageCheck = true; -} - -void WindowGrabber::triggerUpdate() -{ - if (!m_eglImageCheck) // We did not check for egl images yet - return; - - int size[2] = { 0, 0 }; - - int result = screen_get_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, size); - if (result != 0) { - cleanup(); - qWarning() << "WindowGrabber: cannot get window size:" << strerror(errno); - return; - } - - if (m_size.width() != size[0] || m_size.height() != size[1]) - m_size = QSize(size[0], size[1]); - - emit updateScene(m_size); -} - -bool WindowGrabber::selectBuffer() -{ - // If we're using egl images we need to double buffer since the gpu may still be using the last - // video frame. If we're not, it doesn't matter since the data is immediately copied. - if (eglImageSupported()) - m_currentFrame = (m_currentFrame + 1) % 2; - - if (!m_images[m_currentFrame]) { - m_images[m_currentFrame] = new WindowGrabberImage(); - if (!m_images[m_currentFrame]->initialize(m_screenContext)) { - delete m_images[m_currentFrame]; - m_images[m_currentFrame] = 0; - return false; - } - } - return true; -} - -int WindowGrabber::getNextTextureId() -{ - if (!selectBuffer()) - return 0; - return m_images[m_currentFrame]->getTexture(m_window, m_size); -} - -QImage WindowGrabber::getNextImage() -{ - if (!selectBuffer()) - return QImage(); - - return m_images[m_currentFrame]->getImage(m_window, m_size); -} - -void WindowGrabber::cleanup() -{ - for ( int i = 0; i < 2; ++i ) { - if (m_images[i]) { - m_images[i]->destroy(); - m_images[i] = 0; - } - } -} - - -WindowGrabberImage::WindowGrabberImage() - : m_pixmap(0), m_pixmapBuffer(0), m_eglImage(0), m_glTexture(0), m_bufferAddress(0), m_bufferStride(0) -{ -} - -WindowGrabberImage::~WindowGrabberImage() -{ - if (m_glTexture) - glDeleteTextures(1, &m_glTexture); - if (m_eglImage) - s_eglDestroyImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), m_eglImage); - if (m_pixmap) - screen_destroy_pixmap(m_pixmap); -} - -bool -WindowGrabberImage::initialize(screen_context_t screenContext) -{ - if (screen_create_pixmap(&m_pixmap, screenContext) != 0) { - qWarning() << "WindowGrabber: cannot create pixmap:" << strerror(errno); - return false; - } - const int usage = SCREEN_USAGE_WRITE | SCREEN_USAGE_READ | SCREEN_USAGE_NATIVE; - screen_set_pixmap_property_iv(m_pixmap, SCREEN_PROPERTY_USAGE, &usage); - - const int format = SCREEN_FORMAT_RGBX8888; - screen_set_pixmap_property_iv(m_pixmap, SCREEN_PROPERTY_FORMAT, &format); - - return true; -} - -void -WindowGrabberImage::destroy() -{ - // We want to delete in the thread we were created in since we need the thread that - // has called eglMakeCurrent on the right EGL context. This doesn't actually guarantee - // this but that would be hard to achieve and in practice it works. - if (QThread::currentThread() == thread()) - delete this; - else - deleteLater(); -} - -bool -WindowGrabberImage::resize(const QSize &newSize) -{ - if (m_pixmapBuffer) { - screen_destroy_pixmap_buffer(m_pixmap); - m_pixmapBuffer = 0; - m_bufferAddress = 0; - m_bufferStride = 0; - } - - int size[2] = { newSize.width(), newSize.height() }; - - screen_set_pixmap_property_iv(m_pixmap, SCREEN_PROPERTY_BUFFER_SIZE, size); - - if (screen_create_pixmap_buffer(m_pixmap) == 0) { - screen_get_pixmap_property_pv(m_pixmap, SCREEN_PROPERTY_RENDER_BUFFERS, - reinterpret_cast<void**>(&m_pixmapBuffer)); - screen_get_buffer_property_pv(m_pixmapBuffer, SCREEN_PROPERTY_POINTER, - reinterpret_cast<void**>(&m_bufferAddress)); - screen_get_buffer_property_iv(m_pixmapBuffer, SCREEN_PROPERTY_STRIDE, &m_bufferStride); - m_size = newSize; - - return true; - } else { - m_size = QSize(); - return false; - } -} - -bool -WindowGrabberImage::grab(screen_window_t window) -{ - const int rect[] = { 0, 0, m_size.width(), m_size.height() }; - return screen_read_window(window, m_pixmapBuffer, 1, rect, 0) == 0; -} - -QImage -WindowGrabberImage::getImage(screen_window_t window, const QSize &size) -{ - if (size != m_size) { - if (!resize(size)) - return QImage(); - } - if (!m_bufferAddress || !grab(window)) - return QImage(); - - return QImage(m_bufferAddress, m_size.width(), m_size.height(), m_bufferStride, QImage::Format_ARGB32); -} - -GLuint -WindowGrabberImage::getTexture(screen_window_t window, const QSize &size) -{ - if (size != m_size) { - if (!m_glTexture) - glGenTextures(1, &m_glTexture); - glBindTexture(GL_TEXTURE_2D, m_glTexture); - if (m_eglImage) { - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, 0); - s_eglDestroyImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), m_eglImage); - m_eglImage = 0; - } - if (!resize(size)) - return 0; - m_eglImage = s_eglCreateImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT, - EGL_NATIVE_PIXMAP_KHR, m_pixmap, 0); - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage); - } - - if (!m_pixmap || !grab(window)) - return 0; - - return m_glTexture; -} - - - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/common/windowgrabber.h b/src/plugins/qnx/common/windowgrabber.h deleted file mode 100644 index c4c1f6a53..000000000 --- a/src/plugins/qnx/common/windowgrabber.h +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef WINDOWGRABBER_H -#define WINDOWGRABBER_H - -#define EGL_EGLEXT_PROTOTYPES -#define GL_GLEXT_PROTOTYPES -#include <EGL/egl.h> -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> -#include <EGL/eglext.h> -#include <QAbstractNativeEventFilter> -#include <QObject> -#include <QSize> -#include <QTimer> - -#include <screen/screen.h> - -QT_BEGIN_NAMESPACE - -class WindowGrabberImage : public QObject -{ - Q_OBJECT - -public: - WindowGrabberImage(); - ~WindowGrabberImage(); - - bool initialize(screen_context_t screenContext); - - void destroy(); - - QImage getImage(screen_window_t window, const QSize &size); - GLuint getTexture(screen_window_t window, const QSize &size); - -private: - bool grab(screen_window_t window); - bool resize(const QSize &size); - - QSize m_size; - screen_pixmap_t m_pixmap; - screen_buffer_t m_pixmapBuffer; - EGLImageKHR m_eglImage; - GLuint m_glTexture; - unsigned char *m_bufferAddress; - int m_bufferStride; -}; - -class WindowGrabber : public QObject, public QAbstractNativeEventFilter -{ - Q_OBJECT - -public: - explicit WindowGrabber(QObject *parent = 0); - ~WindowGrabber(); - - void setFrameRate(int frameRate); - - void setWindowId(const QByteArray &windowId); - - void start(); - void stop(); - - void pause(); - void resume(); - - bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override; - - bool handleScreenEvent(screen_event_t event); - - QByteArray windowGroupId() const; - - bool eglImageSupported(); - void checkForEglImageExtension(); - - int getNextTextureId(); - QImage getNextImage(); - -signals: - void updateScene(const QSize &size); - -private slots: - void triggerUpdate(); - -private: - bool selectBuffer(); - void cleanup(); - - QTimer m_timer; - - QByteArray m_windowId; - - screen_window_t m_windowParent; - screen_window_t m_window; - screen_context_t m_screenContext; - - WindowGrabberImage *m_images[2]; - QSize m_size; - - bool m_active; - int m_currentFrame; - bool m_eglImageSupported; - bool m_eglImageCheck; // We must not send a grabed frame before this is true -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/mediaplayer/mediaplayer.pri b/src/plugins/qnx/mediaplayer/mediaplayer.pri deleted file mode 100644 index 4c4363a91..000000000 --- a/src/plugins/qnx/mediaplayer/mediaplayer.pri +++ /dev/null @@ -1,24 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/mmrenderermediaplayercontrol.h \ - $$PWD/mmrenderermediaplayerservice.h \ - $$PWD/mmrenderermetadata.h \ - $$PWD/mmrenderermetadatareadercontrol.h \ - $$PWD/mmrendererplayervideorenderercontrol.h \ - $$PWD/mmrendererutil.h \ - $$PWD/mmrenderervideowindowcontrol.h \ - $$PWD/mmreventmediaplayercontrol.h \ - $$PWD/mmreventthread.h -SOURCES += \ - $$PWD/mmrenderermediaplayercontrol.cpp \ - $$PWD/mmrenderermediaplayerservice.cpp \ - $$PWD/mmrenderermetadata.cpp \ - $$PWD/mmrenderermetadatareadercontrol.cpp \ - $$PWD/mmrendererplayervideorenderercontrol.cpp \ - $$PWD/mmrendererutil.cpp \ - $$PWD/mmrenderervideowindowcontrol.cpp \ - $$PWD/mmreventmediaplayercontrol.cpp \ - $$PWD/mmreventthread.cpp - -QMAKE_USE += mmrenderer diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp deleted file mode 100644 index d8b69a2e4..000000000 --- a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp +++ /dev/null @@ -1,664 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "mmrendereraudiorolecontrol.h" -#include "mmrenderercustomaudiorolecontrol.h" -#include "mmrenderermediaplayercontrol.h" -#include "mmrenderermetadatareadercontrol.h" -#include "mmrendererplayervideorenderercontrol.h" -#include "mmrendererutil.h" -#include "mmrenderervideowindowcontrol.h" -#include <QtCore/qabstracteventdispatcher.h> -#include <QtCore/qcoreapplication.h> -#include <QtCore/qdir.h> -#include <QtCore/qfileinfo.h> -#include <QtCore/quuid.h> -#include <mm/renderer.h> - -#include <errno.h> -#include <sys/strm.h> -#include <sys/stat.h> - -QT_BEGIN_NAMESPACE - -static int idCounter = 0; - -MmRendererMediaPlayerControl::MmRendererMediaPlayerControl(QObject *parent) - : QMediaPlayerControl(parent), - m_context(0), - m_id(-1), - m_connection(0), - m_audioId(-1), - m_state(QMediaPlayer::StoppedState), - m_volume(100), - m_muted(false), - m_rate(1), - m_position(0), - m_mediaStatus(QMediaPlayer::NoMedia), - m_playAfterMediaLoaded(false), - m_inputAttached(false), - m_bufferLevel(0) -{ - m_loadingTimer.setSingleShot(true); - m_loadingTimer.setInterval(0); - connect(&m_loadingTimer, SIGNAL(timeout()), this, SLOT(continueLoadMedia())); - QCoreApplication::eventDispatcher()->installNativeEventFilter(this); -} - -void MmRendererMediaPlayerControl::destroy() -{ - stop(); - detach(); - closeConnection(); - QCoreApplication::eventDispatcher()->removeNativeEventFilter(this); -} - -void MmRendererMediaPlayerControl::openConnection() -{ - m_connection = mmr_connect(NULL); - if (!m_connection) { - emitPError("Unable to connect to the multimedia renderer"); - return; - } - - m_id = idCounter++; - m_contextName = QString("MmRendererMediaPlayerControl_%1_%2").arg(m_id) - .arg(QCoreApplication::applicationPid()); - m_context = mmr_context_create(m_connection, m_contextName.toLatin1(), - 0, S_IRWXU|S_IRWXG|S_IRWXO); - if (!m_context) { - emitPError("Unable to create context"); - closeConnection(); - return; - } - - startMonitoring(); -} - -void MmRendererMediaPlayerControl::handleMmStopped() -{ - // Only react to stop events that happen when the end of the stream is reached and - // playback is stopped because of this. - // Ignore other stop event sources, such as calling mmr_stop() ourselves. - if (m_state != QMediaPlayer::StoppedState) { - setMediaStatus(QMediaPlayer::EndOfMedia); - stopInternal(IgnoreMmRenderer); - } -} - -void MmRendererMediaPlayerControl::handleMmSuspend(const QString &reason) -{ - if (m_state == QMediaPlayer::StoppedState) - return; - - Q_UNUSED(reason); - setMediaStatus(QMediaPlayer::StalledMedia); -} - -void MmRendererMediaPlayerControl::handleMmSuspendRemoval(const QString &bufferStatus) -{ - if (m_state == QMediaPlayer::StoppedState) - return; - - if (bufferStatus == QLatin1String("buffering")) - setMediaStatus(QMediaPlayer::BufferingMedia); - else - setMediaStatus(QMediaPlayer::BufferedMedia); -} - -void MmRendererMediaPlayerControl::handleMmPause() -{ - if (m_state == QMediaPlayer::PlayingState) { - setState(QMediaPlayer::PausedState); - } -} - -void MmRendererMediaPlayerControl::handleMmPlay() -{ - if (m_state == QMediaPlayer::PausedState) { - setState(QMediaPlayer::PlayingState); - } -} - -void MmRendererMediaPlayerControl::closeConnection() -{ - stopMonitoring(); - - if (m_context) { - mmr_context_destroy(m_context); - m_context = 0; - m_contextName.clear(); - } - - if (m_connection) { - mmr_disconnect(m_connection); - m_connection = 0; - } -} - -QByteArray MmRendererMediaPlayerControl::resourcePathForUrl(const QUrl &url) -{ - // If this is a local file, mmrenderer expects the file:// prefix and an absolute path. - // We treat URLs without scheme as local files, most likely someone just forgot to set the - // file:// prefix when constructing the URL. - if (url.isLocalFile() || url.scheme().isEmpty()) { - QString relativeFilePath; - if (!url.scheme().isEmpty()) - relativeFilePath = url.toLocalFile(); - else - relativeFilePath = url.path(); - const QFileInfo fileInfo(relativeFilePath); - return QFile::encodeName(QStringLiteral("file://") + fileInfo.absoluteFilePath()); - - // HTTP or similar URL - } else { - return url.toEncoded(); - } -} - -void MmRendererMediaPlayerControl::attach() -{ - // Should only be called in detached state - Q_ASSERT(m_audioId == -1 && !m_inputAttached); - - if (m_media.isNull() || !m_context) { - setMediaStatus(QMediaPlayer::NoMedia); - return; - } - - resetMonitoring(); - - if (m_videoRendererControl) - m_videoRendererControl->attachDisplay(m_context); - - if (m_videoWindowControl) - m_videoWindowControl->attachDisplay(m_context); - - const QByteArray defaultAudioDevice = qgetenv("QQNX_RENDERER_DEFAULT_AUDIO_SINK"); - m_audioId = mmr_output_attach(m_context, defaultAudioDevice.isEmpty() ? "audio:default" : defaultAudioDevice.constData(), "audio"); - if (m_audioId == -1) { - emitMmError("mmr_output_attach() for audio failed"); - return; - } - - if (m_audioId != -1) { - QString audioType = m_role == QAudio::CustomRole - ? m_customRole - : qnxAudioType(m_role); - QByteArray latin1AudioType = audioType.toLatin1(); - if (!audioType.isEmpty() && latin1AudioType == audioType) { - strm_dict_t *dict = strm_dict_new(); - dict = strm_dict_set(dict, "audio_type", latin1AudioType.constData()); - if (mmr_output_parameters(m_context, m_audioId, dict) != 0) - emitMmError("mmr_output_parameters: Setting audio_type failed"); - } - } - - const QByteArray resourcePath = resourcePathForUrl(m_media.request().url()); - if (resourcePath.isEmpty()) { - detach(); - return; - } - - if (mmr_input_attach(m_context, resourcePath.constData(), "track") != 0) { - emitMmError(QStringLiteral("mmr_input_attach() failed for ") + QString(resourcePath)); - setMediaStatus(QMediaPlayer::InvalidMedia); - detach(); - return; - } - - m_inputAttached = true; - setMediaStatus(QMediaPlayer::LoadedMedia); - - // mm-renderer has buffer properties "status" and "level" - // QMediaPlayer's buffer status maps to mm-renderer's buffer level - m_bufferLevel = 0; - emit bufferStatusChanged(m_bufferLevel); -} - -void MmRendererMediaPlayerControl::detach() -{ - if (m_context) { - if (m_inputAttached) { - mmr_input_detach(m_context); - m_inputAttached = false; - } - if (m_videoRendererControl) - m_videoRendererControl->detachDisplay(); - if (m_videoWindowControl) - m_videoWindowControl->detachDisplay(); - if (m_audioId != -1 && m_context) { - mmr_output_detach(m_context, m_audioId); - m_audioId = -1; - } - } - - m_loadingTimer.stop(); -} - -QMediaPlayer::State MmRendererMediaPlayerControl::state() const -{ - return m_state; -} - -QMediaPlayer::MediaStatus MmRendererMediaPlayerControl::mediaStatus() const -{ - return m_mediaStatus; -} - -qint64 MmRendererMediaPlayerControl::duration() const -{ - return m_metaData.duration(); -} - -qint64 MmRendererMediaPlayerControl::position() const -{ - return m_position; -} - -void MmRendererMediaPlayerControl::setPosition(qint64 position) -{ - if (m_position != position) { - m_position = position; - - // Don't update in stopped state, it would not have any effect. Instead, the position is - // updated in play(). - if (m_state != QMediaPlayer::StoppedState) - setPositionInternal(m_position); - - emit positionChanged(m_position); - } -} - -int MmRendererMediaPlayerControl::volume() const -{ - return m_volume; -} - -void MmRendererMediaPlayerControl::setVolumeInternal(int newVolume) -{ - if (!m_context) - return; - - newVolume = qBound(0, newVolume, 100); - if (m_audioId != -1) { - strm_dict_t * dict = strm_dict_new(); - dict = strm_dict_set(dict, "volume", QString::number(newVolume).toLatin1()); - if (mmr_output_parameters(m_context, m_audioId, dict) != 0) - emitMmError("mmr_output_parameters: Setting volume failed"); - } -} - -void MmRendererMediaPlayerControl::setPlaybackRateInternal(qreal rate) -{ - if (!m_context) - return; - - const int mmRate = rate * 1000; - if (mmr_speed_set(m_context, mmRate) != 0) - emitMmError("mmr_speed_set failed"); -} - -void MmRendererMediaPlayerControl::setPositionInternal(qint64 position) -{ - if (!m_context) - return; - - if (m_metaData.isSeekable()) { - if (mmr_seek(m_context, QString::number(position).toLatin1()) != 0) - emitMmError("Seeking failed"); - } -} - -void MmRendererMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status) -{ - if (m_mediaStatus != status) { - m_mediaStatus = status; - emit mediaStatusChanged(m_mediaStatus); - } -} - -void MmRendererMediaPlayerControl::setState(QMediaPlayer::State state) -{ - if (m_state != state) { - if (m_videoRendererControl) { - if (state == QMediaPlayer::PausedState || state == QMediaPlayer::StoppedState) { - m_videoRendererControl->pause(); - } else if ((state == QMediaPlayer::PlayingState) - && (m_state == QMediaPlayer::PausedState - || m_state == QMediaPlayer::StoppedState)) { - m_videoRendererControl->resume(); - } - } - - m_state = state; - emit stateChanged(m_state); - } -} - -void MmRendererMediaPlayerControl::stopInternal(StopCommand stopCommand) -{ - resetMonitoring(); - setPosition(0); - - if (m_state != QMediaPlayer::StoppedState) { - - if (stopCommand == StopMmRenderer) { - mmr_stop(m_context); - } - - setState(QMediaPlayer::StoppedState); - } -} - -void MmRendererMediaPlayerControl::setVolume(int volume) -{ - const int newVolume = qBound(0, volume, 100); - if (m_volume != newVolume) { - m_volume = newVolume; - if (!m_muted) - setVolumeInternal(m_volume); - emit volumeChanged(m_volume); - } -} - -bool MmRendererMediaPlayerControl::isMuted() const -{ - return m_muted; -} - -void MmRendererMediaPlayerControl::setMuted(bool muted) -{ - if (m_muted != muted) { - m_muted = muted; - setVolumeInternal(muted ? 0 : m_volume); - emit mutedChanged(muted); - } -} - -int MmRendererMediaPlayerControl::bufferStatus() const -{ - // mm-renderer has buffer properties "status" and "level" - // QMediaPlayer's buffer status maps to mm-renderer's buffer level - return m_bufferLevel; -} - -bool MmRendererMediaPlayerControl::isAudioAvailable() const -{ - return m_metaData.hasAudio(); -} - -bool MmRendererMediaPlayerControl::isVideoAvailable() const -{ - return m_metaData.hasVideo(); -} - -bool MmRendererMediaPlayerControl::isSeekable() const -{ - return m_metaData.isSeekable(); -} - -QMediaTimeRange MmRendererMediaPlayerControl::availablePlaybackRanges() const -{ - // We can't get this information from the mmrenderer API yet, so pretend we can seek everywhere - return QMediaTimeRange(0, m_metaData.duration()); -} - -qreal MmRendererMediaPlayerControl::playbackRate() const -{ - return m_rate; -} - -void MmRendererMediaPlayerControl::setPlaybackRate(qreal rate) -{ - if (m_rate != rate) { - m_rate = rate; - setPlaybackRateInternal(m_rate); - emit playbackRateChanged(m_rate); - } -} - -QUrl MmRendererMediaPlayerControl::media() const -{ - return m_media; -} - -const QIODevice *MmRendererMediaPlayerControl::mediaStream() const -{ - // Always 0, we don't support QIODevice streams - return 0; -} - -void MmRendererMediaPlayerControl::setMedia(const QUrl &media, QIODevice *stream) -{ - Q_UNUSED(stream); // not supported - - stop(); - detach(); - - m_media = media; - emit mediaChanged(m_media); - - // Slight hack: With MediaPlayer QtQuick elements that have autoPlay set to true, playback - // would start before the QtQuick canvas is propagated to all elements, and therefore our - // video output would not work. Therefore, delay actually playing the media a bit so that the - // canvas is ready. - // The mmrenderer doesn't allow to attach video outputs after playing has started, otherwise - // this would be unnecessary. - if (!m_media.isNull()) { - setMediaStatus(QMediaPlayer::LoadingMedia); - m_loadingTimer.start(); // singleshot timer to continueLoadMedia() - } else { - continueLoadMedia(); // still needed, as it will update the media status and clear metadata - } -} - -void MmRendererMediaPlayerControl::continueLoadMedia() -{ - updateMetaData(nullptr); - attach(); - if (m_playAfterMediaLoaded) - play(); -} - -MmRendererVideoWindowControl *MmRendererMediaPlayerControl::videoWindowControl() const -{ - return m_videoWindowControl; -} - -void MmRendererMediaPlayerControl::play() -{ - if (m_playAfterMediaLoaded) - m_playAfterMediaLoaded = false; - - // No-op if we are already playing, except if we were called from continueLoadMedia(), in which - // case m_playAfterMediaLoaded is true (hence the 'else'). - else if (m_state == QMediaPlayer::PlayingState) - return; - - if (m_mediaStatus == QMediaPlayer::LoadingMedia) { - - // State changes are supposed to be synchronous - setState(QMediaPlayer::PlayingState); - - // Defer playing to later, when the timer triggers continueLoadMedia() - m_playAfterMediaLoaded = true; - return; - } - - // Un-pause the state when it is paused - if (m_state == QMediaPlayer::PausedState) { - setPlaybackRateInternal(m_rate); - setState(QMediaPlayer::PlayingState); - return; - } - - if (m_media.isNull() || !m_connection || !m_context || m_audioId == -1) { - setState(QMediaPlayer::StoppedState); - return; - } - - if (m_mediaStatus == QMediaPlayer::EndOfMedia) - m_position = 0; - - resetMonitoring(); - setPositionInternal(m_position); - setVolumeInternal(m_muted ? 0 : m_volume); - setPlaybackRateInternal(m_rate); - - if (mmr_play(m_context) != 0) { - setState(QMediaPlayer::StoppedState); - emitMmError("mmr_play() failed"); - return; - } - - setState( QMediaPlayer::PlayingState); -} - -void MmRendererMediaPlayerControl::pause() -{ - if (m_state == QMediaPlayer::PlayingState) { - setPlaybackRateInternal(0); - setState(QMediaPlayer::PausedState); - } -} - -void MmRendererMediaPlayerControl::stop() -{ - stopInternal(StopMmRenderer); -} - -void MmRendererMediaPlayerControl::setAudioRole(QAudio::Role role) -{ - m_role = role; - m_customRole.clear(); -} - -QList<QAudio::Role> MmRendererMediaPlayerControl::supportedAudioRoles() const -{ - return qnxSupportedAudioRoles(); -} - -void MmRendererMediaPlayerControl::setCustomAudioRole(const QString &role) -{ - m_role = QAudio::CustomRole; - m_customRole = role; -} - -QStringList MmRendererMediaPlayerControl::supportedCustomAudioRoles() const -{ - return QStringList(); -} - -MmRendererPlayerVideoRendererControl *MmRendererMediaPlayerControl::videoRendererControl() const -{ - return m_videoRendererControl; -} - -void MmRendererMediaPlayerControl::setVideoRendererControl(MmRendererPlayerVideoRendererControl *videoControl) -{ - m_videoRendererControl = videoControl; -} - -void MmRendererMediaPlayerControl::setVideoWindowControl(MmRendererVideoWindowControl *videoControl) -{ - m_videoWindowControl = videoControl; -} - -void MmRendererMediaPlayerControl::setMetaDataReaderControl(MmRendererMetaDataReaderControl *metaDataReaderControl) -{ - m_metaDataReaderControl = metaDataReaderControl; -} - -void MmRendererMediaPlayerControl::setMmPosition(qint64 newPosition) -{ - if (newPosition != 0 && newPosition != m_position) { - m_position = newPosition; - emit positionChanged(m_position); - } -} - -void MmRendererMediaPlayerControl::setMmBufferStatus(const QString &bufferStatus) -{ - if (bufferStatus == QLatin1String("buffering")) - setMediaStatus(QMediaPlayer::BufferingMedia); - else if (bufferStatus == QLatin1String("playing")) - setMediaStatus(QMediaPlayer::BufferedMedia); - // ignore "idle" buffer status -} - -void MmRendererMediaPlayerControl::setMmBufferLevel(int level, int capacity) -{ - m_bufferLevel = capacity == 0 ? 0 : level / static_cast<float>(capacity) * 100.0f; - m_bufferLevel = qBound(0, m_bufferLevel, 100); - emit bufferStatusChanged(m_bufferLevel); -} - -void MmRendererMediaPlayerControl::updateMetaData(const strm_dict *dict) -{ - m_metaData.update(dict); - - if (m_videoWindowControl) - m_videoWindowControl->setMetaData(m_metaData); - - if (m_metaDataReaderControl) - m_metaDataReaderControl->setMetaData(m_metaData); - - emit durationChanged(m_metaData.duration()); - emit audioAvailableChanged(m_metaData.hasAudio()); - emit videoAvailableChanged(m_metaData.hasVideo()); - emit availablePlaybackRangesChanged(availablePlaybackRanges()); - emit seekableChanged(m_metaData.isSeekable()); -} - -void MmRendererMediaPlayerControl::emitMmError(const QString &msg) -{ - int errorCode = MMR_ERROR_NONE; - const QString errorMessage = mmErrorMessage(msg, m_context, &errorCode); - qDebug() << errorMessage; - emit error(errorCode, errorMessage); -} - -void MmRendererMediaPlayerControl::emitPError(const QString &msg) -{ - const QString errorMessage = QString("%1: %2").arg(msg).arg(strerror(errno)); - qDebug() << errorMessage; - emit error(errno, errorMessage); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h deleted file mode 100644 index 97f4ed254..000000000 --- a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef MMRENDERERMEDIAPLAYERCONTROL_H -#define MMRENDERERMEDIAPLAYERCONTROL_H - -#include "mmrenderermetadata.h" -#include <qmediaplayercontrol.h> -#include <QtCore/qabstractnativeeventfilter.h> -#include <QtCore/qpointer.h> -#include <QtCore/qtimer.h> - -typedef struct mmr_connection mmr_connection_t; -typedef struct mmr_context mmr_context_t; -typedef struct mmrenderer_monitor mmrenderer_monitor_t; -typedef struct strm_dict strm_dict_t; - -QT_BEGIN_NAMESPACE - -class MmRendererAudioRoleControl; -class MmRendererCustomAudioRoleControl; -class MmRendererMetaDataReaderControl; -class MmRendererPlayerVideoRendererControl; -class MmRendererVideoWindowControl; - -class MmRendererMediaPlayerControl : public QMediaPlayerControl, public QAbstractNativeEventFilter -{ - Q_OBJECT -public: - explicit MmRendererMediaPlayerControl(QObject *parent = 0); - - QMediaPlayer::State state() const override; - - QMediaPlayer::MediaStatus mediaStatus() const override; - - qint64 duration() const override; - - qint64 position() const override; - void setPosition(qint64 position) override; - - int volume() const override; - void setVolume(int volume) override; - - bool isMuted() const override; - void setMuted(bool muted) override; - - int bufferStatus() const override; - - bool isAudioAvailable() const override; - bool isVideoAvailable() const override; - - bool isSeekable() const override; - - QMediaTimeRange availablePlaybackRanges() const override; - - qreal playbackRate() const override; - void setPlaybackRate(qreal rate) override; - - QUrl media() const override; - const QIODevice *mediaStream() const override; - void setMedia(const QUrl &media, QIODevice *stream) override; - - void play() override; - void pause() override; - void stop() override; - - void setAudioRole(QAudio::Role role) override; - QList<QAudio::Role> supportedAudioRoles() const override; - - void setCustomAudioRole(const QString &role) override; - QStringList supportedCustomAudioRoles() const override; - - MmRendererPlayerVideoRendererControl *videoRendererControl() const; - void setVideoRendererControl(MmRendererPlayerVideoRendererControl *videoControl); - - MmRendererVideoWindowControl *videoWindowControl() const; - void setVideoWindowControl(MmRendererVideoWindowControl *videoControl); - void setMetaDataReaderControl(MmRendererMetaDataReaderControl *metaDataReaderControl); - -protected: - virtual void startMonitoring() = 0; - virtual void stopMonitoring() = 0; - virtual void resetMonitoring() = 0; - - void openConnection(); - void emitMmError(const QString &msg); - void emitPError(const QString &msg); - void setMmPosition(qint64 newPosition); - void setMmBufferStatus(const QString &bufferStatus); - void setMmBufferLevel(int level, int capacity); - void handleMmStopped(); - void handleMmSuspend(const QString &reason); - void handleMmSuspendRemoval(const QString &bufferStatus); - void handleMmPause(); - void handleMmPlay(); - void updateMetaData(const strm_dict_t *dict); - - // must be called from subclass dtors (calls virtual function stopMonitoring()) - void destroy(); - - mmr_context_t *m_context; - int m_id; - QString m_contextName; - -private Q_SLOTS: - void continueLoadMedia(); - -private: - QByteArray resourcePathForUrl(const QUrl &url); - void closeConnection(); - void attach(); - void detach(); - - // All these set the specified value to the backend, but neither emit changed signals - // nor change the member value. - void setVolumeInternal(int newVolume); - void setPlaybackRateInternal(qreal rate); - void setPositionInternal(qint64 position); - - void setMediaStatus(QMediaPlayer::MediaStatus status); - void setState(QMediaPlayer::State state); - - enum StopCommand { StopMmRenderer, IgnoreMmRenderer }; - void stopInternal(StopCommand stopCommand); - - QUrl m_media; - mmr_connection_t *m_connection; - int m_audioId; - QMediaPlayer::State m_state; - int m_volume; - bool m_muted; - qreal m_rate; - QPointer<MmRendererPlayerVideoRendererControl> m_videoRendererControl; - QPointer<MmRendererVideoWindowControl> m_videoWindowControl; - QPointer<MmRendererMetaDataReaderControl> m_metaDataReaderControl; - MmRendererMetaData m_metaData; - qint64 m_position; - QMediaPlayer::MediaStatus m_mediaStatus; - bool m_playAfterMediaLoaded; - bool m_inputAttached; - int m_bufferLevel; - QTimer m_loadingTimer; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.cpp b/src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.cpp deleted file mode 100644 index 63b8fe916..000000000 --- a/src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "mmrenderermediaplayerservice.h" - -#include "mmrenderermediaplayercontrol.h" -#include "mmrenderermetadatareadercontrol.h" -#include "mmrendererplayervideorenderercontrol.h" -#include "mmrendererutil.h" -#include "mmrenderervideowindowcontrol.h" - -#include "mmreventmediaplayercontrol.h" - -QT_BEGIN_NAMESPACE - -MmRendererMediaPlayerService::MmRendererMediaPlayerService(QObject *parent) - : QMediaService(parent), - m_videoRendererControl(0), - m_videoWindowControl(0), - m_mediaPlayerControl(0), - m_metaDataReaderControl(0), - m_appHasDrmPermission(false), - m_appHasDrmPermissionChecked(false) -{ -} - -MmRendererMediaPlayerService::~MmRendererMediaPlayerService() -{ - // Someone should have called releaseControl(), but better be safe - delete m_videoRendererControl; - delete m_videoWindowControl; - delete m_mediaPlayerControl; - delete m_metaDataReaderControl; -} - -QObject *MmRendererMediaPlayerService::requestControl(const char *name) -{ - if (qstrcmp(name, QMediaPlayerControl_iid) == 0) { - if (!m_mediaPlayerControl) { - m_mediaPlayerControl = new MmrEventMediaPlayerControl; - updateControls(); - } - return m_mediaPlayerControl; - } else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) { - if (!m_metaDataReaderControl) { - m_metaDataReaderControl = new MmRendererMetaDataReaderControl(); - updateControls(); - } - return m_metaDataReaderControl; - } else if (qstrcmp(name, QVideoRendererControl_iid) == 0) { - if (!m_appHasDrmPermissionChecked) { - m_appHasDrmPermission = checkForDrmPermission(); - m_appHasDrmPermissionChecked = true; - } - - if (m_appHasDrmPermission) { - // When the application wants to play back DRM secured media, we can't use - // the QVideoRendererControl, because we won't have access to the pixel data - // in this case. - return 0; - } - - if (!m_videoRendererControl) { - m_videoRendererControl = new MmRendererPlayerVideoRendererControl(); - updateControls(); - } - return m_videoRendererControl; - } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) { - if (!m_videoWindowControl) { - m_videoWindowControl = new MmRendererVideoWindowControl(); - updateControls(); - } - return m_videoWindowControl; - } - return 0; -} - -void MmRendererMediaPlayerService::releaseControl(QObject *control) -{ - if (control == m_videoRendererControl) - m_videoRendererControl = 0; - if (control == m_videoWindowControl) - m_videoWindowControl = 0; - if (control == m_mediaPlayerControl) - m_mediaPlayerControl = 0; - if (control == m_metaDataReaderControl) - m_metaDataReaderControl = 0; - delete control; -} - -void MmRendererMediaPlayerService::updateControls() -{ - if (m_videoRendererControl && m_mediaPlayerControl) - m_mediaPlayerControl->setVideoRendererControl(m_videoRendererControl); - - if (m_videoWindowControl && m_mediaPlayerControl) - m_mediaPlayerControl->setVideoWindowControl(m_videoWindowControl); - - if (m_metaDataReaderControl && m_mediaPlayerControl) - m_mediaPlayerControl->setMetaDataReaderControl(m_metaDataReaderControl); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.h b/src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.h deleted file mode 100644 index fea4f0a0a..000000000 --- a/src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef MMRENDERERMEDIAPLAYERSERVICE_H -#define MMRENDERERMEDIAPLAYERSERVICE_H - -#include <qmediaservice.h> -#include <QtCore/qpointer.h> - -QT_BEGIN_NAMESPACE - -class MmRendererMediaPlayerControl; -class MmRendererMetaDataReaderControl; -class MmRendererPlayerVideoRendererControl; -class MmRendererVideoWindowControl; - -class MmRendererMediaPlayerService : public QMediaService -{ - Q_OBJECT -public: - explicit MmRendererMediaPlayerService(QObject *parent = 0); - ~MmRendererMediaPlayerService(); - - QObject *requestControl(const char *name) override; - void releaseControl(QObject *control) override; - -private: - void updateControls(); - - QPointer<MmRendererPlayerVideoRendererControl> m_videoRendererControl; - QPointer<MmRendererVideoWindowControl> m_videoWindowControl; - QPointer<MmRendererMediaPlayerControl> m_mediaPlayerControl; - QPointer<MmRendererMetaDataReaderControl> m_metaDataReaderControl; - - bool m_appHasDrmPermission : 1; - bool m_appHasDrmPermissionChecked : 1; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/mediaplayer/mmrenderermetadata.cpp b/src/plugins/qnx/mediaplayer/mmrenderermetadata.cpp deleted file mode 100644 index a8b92c267..000000000 --- a/src/plugins/qnx/mediaplayer/mmrenderermetadata.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "mmrenderermetadata.h" - -#include <QtCore/qdebug.h> -#include <QtCore/qfile.h> -#include <QtCore/qstringlist.h> - -#include <mm/renderer/events.h> -#include <sys/neutrino.h> -#include <sys/strm.h> - -static const char *strm_string_getx(const strm_string_t *sstr, const char *defaultValue) -{ - return sstr ? strm_string_get(sstr) : defaultValue; -} - -#if _NTO_VERSION < 700 -static strm_dict_t *mmr_metadata_split(strm_dict_t const *, const char *, unsigned) -{ - return nullptr; -} -#endif - -QT_BEGIN_NAMESPACE - -MmRendererMetaData::MmRendererMetaData() -{ - clear(); -} - -static const char * titleKey = "md_title_name"; -static const char * artistKey = "md_title_artist"; -static const char * commentKey = "md_title_comment"; -static const char * genreKey = "md_title_genre"; -static const char * yearKey = "md_title_year"; -static const char * durationKey = "md_title_duration"; -static const char * bitRateKey = "md_title_bitrate"; -static const char * sampleKey = "md_title_samplerate"; -static const char * albumKey = "md_title_album"; -static const char * trackKey = "md_title_track"; -static const char * widthKey = "md_video_width"; -static const char * heightKey = "md_video_height"; -static const char * mediaTypeKey = "md_title_mediatype"; -static const char * pixelWidthKey = "md_video_pixel_width"; -static const char * pixelHeightKey = "md_video_pixel_height"; -static const char * seekableKey = "md_title_seekable"; -static const char * trackSampleKey = "sample_rate"; -static const char * trackBitRateKey = "bitrate"; -static const char * trackWidthKey = "width"; -static const char * trackHeightKey = "height"; -static const char * trackPixelWidthKey = "pixel_width"; -static const char * trackPixelHeightKey = "pixel_height"; - -static const int mediaTypeAudioFlag = 4; -static const int mediaTypeVideoFlag = 2; - -bool MmRendererMetaData::update(const strm_dict_t *dict) -{ - if (!dict) { - clear(); - return true; - } - - const strm_string_t *value; - - value = strm_dict_find_rstr(dict, durationKey); - m_duration = QByteArray(strm_string_getx(value, "0")).toLongLong(); - - value = strm_dict_find_rstr(dict, mediaTypeKey); - m_mediaType = QByteArray(strm_string_getx(value, "-1")).toInt(); - - value = strm_dict_find_rstr(dict, titleKey); - m_title = QString::fromLatin1(QByteArray(strm_string_getx(value, nullptr))); - - value = strm_dict_find_rstr(dict, seekableKey); - m_seekable = (strcmp(strm_string_getx(value, "1"), "0") != 0); - - value = strm_dict_find_rstr(dict, artistKey); - m_artist = QString::fromLatin1(QByteArray(strm_string_getx(value, nullptr))); - - value = strm_dict_find_rstr(dict, commentKey); - m_comment = QString::fromLatin1(QByteArray(strm_string_getx(value, nullptr))); - - value = strm_dict_find_rstr(dict, genreKey); - m_genre = QString::fromLatin1(QByteArray(strm_string_getx(value, nullptr))); - - value = strm_dict_find_rstr(dict, yearKey); - m_year = QByteArray(strm_string_getx(value, "0")).toInt(); - - value = strm_dict_find_rstr(dict, albumKey); - m_album = QString::fromLatin1(QByteArray(strm_string_getx(value, nullptr))); - - value = strm_dict_find_rstr(dict, trackKey); - m_track = QByteArray(strm_string_getx(value, "0")).toInt(); - - strm_dict_t *at = mmr_metadata_split(dict, "audio", 0); - if (at) { - value = strm_dict_find_rstr(at, trackSampleKey); - m_sampleRate = QByteArray(strm_string_getx(value, "0")).toInt(); - - value = strm_dict_find_rstr(at, trackBitRateKey); - m_audioBitRate = QByteArray(strm_string_getx(value, "0")).toInt(); - - strm_dict_destroy(at); - } else { - value = strm_dict_find_rstr(dict, sampleKey); - m_sampleRate = QByteArray(strm_string_getx(value, "0")).toInt(); - - value = strm_dict_find_rstr(dict, bitRateKey); - m_audioBitRate = QByteArray(strm_string_getx(value, "0")).toInt(); - } - - strm_dict_t *vt = mmr_metadata_split(dict, "video", 0); - if (vt) { - value = strm_dict_find_rstr(vt, trackWidthKey); - m_width = QByteArray(strm_string_getx(value, "0")).toInt(); - - value = strm_dict_find_rstr(vt, trackHeightKey); - m_height = QByteArray(strm_string_getx(value, "0")).toInt(); - - value = strm_dict_find_rstr(vt, trackPixelWidthKey); - m_pixelWidth = QByteArray(strm_string_getx(value, "1")).toFloat(); - - value = strm_dict_find_rstr(vt, trackPixelHeightKey); - m_pixelHeight = QByteArray(strm_string_getx(value, "1")).toFloat(); - - strm_dict_destroy(vt); - } else { - value = strm_dict_find_rstr(dict, widthKey); - m_width = QByteArray(strm_string_getx(value, "0")).toInt(); - - value = strm_dict_find_rstr(dict, heightKey); - m_height = QByteArray(strm_string_getx(value, "0")).toInt(); - - value = strm_dict_find_rstr(dict, pixelWidthKey); - m_pixelWidth = QByteArray(strm_string_getx(value, "1")).toFloat(); - - value = strm_dict_find_rstr(dict, pixelHeightKey); - m_pixelHeight = QByteArray(strm_string_getx(value, "1")).toFloat(); - } - - return true; -} - -void MmRendererMetaData::clear() -{ - strm_dict_t *dict; - dict = strm_dict_new(); - update(dict); - strm_dict_destroy(dict); -} - -qlonglong MmRendererMetaData::duration() const -{ - return m_duration; -} - -// Handling of pixel aspect ratio -// -// If the pixel aspect ratio is different from 1:1, it means the video needs to be stretched in -// order to look natural. -// For example, if the pixel width is 2, and the pixel height is 1, it means a video of 300x200 -// pixels needs to be displayed as 600x200 to look correct. -// In order to support this the easiest way, we simply pretend that the actual size of the video -// is 600x200, which will cause the video to be displayed in an aspect ratio of 3:1 instead of 3:2, -// and therefore look correct. - -int MmRendererMetaData::height() const -{ - return m_height * m_pixelHeight; -} - -int MmRendererMetaData::width() const -{ - return m_width * m_pixelWidth; -} - -bool MmRendererMetaData::hasVideo() const -{ - // By default, assume no video if we can't extract the information - if (m_mediaType == -1) - return false; - - return (m_mediaType & mediaTypeVideoFlag); -} - -bool MmRendererMetaData::hasAudio() const -{ - // By default, assume audio only if we can't extract the information - if (m_mediaType == -1) - return true; - - return (m_mediaType & mediaTypeAudioFlag); -} - -QString MmRendererMetaData::title() const -{ - return m_title; -} - -bool MmRendererMetaData::isSeekable() const -{ - return m_seekable; -} - -QString MmRendererMetaData::artist() const -{ - return m_artist; -} - -QString MmRendererMetaData::comment() const -{ - return m_comment; -} - -QString MmRendererMetaData::genre() const -{ - return m_genre; -} - -int MmRendererMetaData::year() const -{ - return m_year; -} - -QString MmRendererMetaData::mediaType() const -{ - if (hasVideo()) - return QLatin1String("video"); - else if (hasAudio()) - return QLatin1String("audio"); - else - return QString(); -} - -int MmRendererMetaData::audioBitRate() const -{ - return m_audioBitRate; -} - -int MmRendererMetaData::sampleRate() const -{ - return m_sampleRate; -} - -QString MmRendererMetaData::album() const -{ - return m_album; -} - -int MmRendererMetaData::track() const -{ - return m_track; -} - -QSize MmRendererMetaData::resolution() const -{ - return QSize(width(), height()); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/mediaplayer/mmrenderermetadata.h b/src/plugins/qnx/mediaplayer/mmrenderermetadata.h deleted file mode 100644 index ad2193d29..000000000 --- a/src/plugins/qnx/mediaplayer/mmrenderermetadata.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef MMRENDERERMETADATA_H -#define MMRENDERERMETADATA_H - -#include <QtCore/qglobal.h> -#include <QtCore/QSize> -#include <QtCore/QString> - -typedef struct strm_dict strm_dict_t; - -QT_BEGIN_NAMESPACE - -class MmRendererMetaData -{ -public: - MmRendererMetaData(); - bool update(const strm_dict_t *dict); - void clear(); - - // Duration in milliseconds - qlonglong duration() const; - - int height() const; - int width() const; - bool hasVideo() const; - bool hasAudio() const; - bool isSeekable() const; - - QString title() const; - QString artist() const; - QString comment() const; - QString genre() const; - int year() const; - QString mediaType() const; - int audioBitRate() const; - int sampleRate() const; - QString album() const; - int track() const; - QSize resolution() const; - -private: - qlonglong m_duration; - int m_height; - int m_width; - int m_mediaType; - float m_pixelWidth; - float m_pixelHeight; - bool m_seekable; - QString m_title; - QString m_artist; - QString m_comment; - QString m_genre; - int m_year; - int m_audioBitRate; - int m_sampleRate; - QString m_album; - int m_track; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.cpp deleted file mode 100644 index 5367e0c54..000000000 --- a/src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "mmrenderermetadatareadercontrol.h" -#include <QtMultimedia/qmediametadata.h> - -QT_BEGIN_NAMESPACE - -MmRendererMetaDataReaderControl::MmRendererMetaDataReaderControl(QObject *parent) - : QMetaDataReaderControl(parent) -{ -} - -bool MmRendererMetaDataReaderControl::isMetaDataAvailable() const -{ - return !availableMetaData().isEmpty(); -} - -QVariant MmRendererMetaDataReaderControl::metaData(const QString &key) const -{ - if (key == QMediaMetaData::Title) - return m_metaData.title(); - else if (key == QMediaMetaData::AlbumArtist) - return m_metaData.artist(); - else if (key == QMediaMetaData::Comment) - return m_metaData.comment(); - else if (key == QMediaMetaData::Genre) - return m_metaData.genre(); - else if (key == QMediaMetaData::Year) - return m_metaData.year(); - else if (key == QMediaMetaData::MediaType) - return m_metaData.mediaType(); - else if (key == QMediaMetaData::Duration) - return m_metaData.duration(); - else if (key == QMediaMetaData::AudioBitRate) - return m_metaData.audioBitRate(); - else if (key == QMediaMetaData::SampleRate) - return m_metaData.sampleRate(); - else if (key == QMediaMetaData::AlbumTitle) - return m_metaData.album(); - else if (key == QMediaMetaData::TrackNumber) - return m_metaData.track(); - else if (key == QMediaMetaData::Resolution) - return m_metaData.resolution(); - - return QVariant(); -} - -QStringList MmRendererMetaDataReaderControl::availableMetaData() const -{ - QStringList metaData; - - if (!m_metaData.title().isEmpty()) - metaData << QMediaMetaData::Title; - if (!m_metaData.artist().isEmpty()) - metaData << QMediaMetaData::Author; - if (!m_metaData.comment().isEmpty()) - metaData << QMediaMetaData::Comment; - if (!m_metaData.genre().isEmpty()) - metaData << QMediaMetaData::Genre; - if (m_metaData.year() != 0) - metaData << QMediaMetaData::Year; - if (!m_metaData.mediaType().isEmpty()) - metaData << QMediaMetaData::MediaType; - if (m_metaData.duration() != 0) - metaData << QMediaMetaData::Duration; - if (m_metaData.audioBitRate() != 0) - metaData << QMediaMetaData::AudioBitRate; - if (m_metaData.sampleRate() != 0) - metaData << QMediaMetaData::SampleRate; - if (!m_metaData.album().isEmpty()) - metaData << QMediaMetaData::AlbumTitle; - if (m_metaData.track() != 0) - metaData << QMediaMetaData::TrackNumber; - if (m_metaData.resolution().isValid()) - metaData << QMediaMetaData::Resolution; - - return metaData; -} - -void MmRendererMetaDataReaderControl::setMetaData(const MmRendererMetaData &data) -{ - const MmRendererMetaData oldMetaData = m_metaData; - const bool oldMetaDataAvailable = isMetaDataAvailable(); - - m_metaData = data; - - bool changed = false; - if (m_metaData.title() != oldMetaData.title()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Title, m_metaData.title()); - } else if (m_metaData.artist() != oldMetaData.artist()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Author, m_metaData.artist()); - } else if (m_metaData.comment() != oldMetaData.comment()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Comment, m_metaData.comment()); - } else if (m_metaData.genre() != oldMetaData.genre()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Genre, m_metaData.genre()); - } else if (m_metaData.year() != oldMetaData.year()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Year, m_metaData.year()); - } else if (m_metaData.mediaType() != oldMetaData.mediaType()) { - changed = true; - emit metaDataChanged(QMediaMetaData::MediaType, m_metaData.mediaType()); - } else if (m_metaData.duration() != oldMetaData.duration()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Duration, m_metaData.duration()); - } else if (m_metaData.audioBitRate() != oldMetaData.audioBitRate()) { - changed = true; - emit metaDataChanged(QMediaMetaData::AudioBitRate, m_metaData.audioBitRate()); - } else if (m_metaData.sampleRate() != oldMetaData.sampleRate()) { - changed = true; - emit metaDataChanged(QMediaMetaData::SampleRate, m_metaData.sampleRate()); - } else if (m_metaData.album() != oldMetaData.album()) { - changed = true; - emit metaDataChanged(QMediaMetaData::AlbumTitle, m_metaData.album()); - } else if (m_metaData.track() != oldMetaData.track()) { - changed = true; - emit metaDataChanged(QMediaMetaData::TrackNumber, m_metaData.track()); - } else if (m_metaData.resolution() != oldMetaData.resolution()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Resolution, m_metaData.resolution()); - } - - if (changed) - emit metaDataChanged(); - - const bool metaDataAvailable = isMetaDataAvailable(); - if (metaDataAvailable != oldMetaDataAvailable) - emit metaDataAvailableChanged(metaDataAvailable); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.h b/src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.h deleted file mode 100644 index 878420460..000000000 --- a/src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef MMRENDERERMETADATAREADERCONTROL_H -#define MMRENDERERMETADATAREADERCONTROL_H - -#include "mmrenderermetadata.h" -#include <qmetadatareadercontrol.h> - -QT_BEGIN_NAMESPACE - -class MmRendererMetaDataReaderControl : public QMetaDataReaderControl -{ - Q_OBJECT -public: - explicit MmRendererMetaDataReaderControl(QObject *parent = 0); - - bool isMetaDataAvailable() const override; - - QVariant metaData(const QString &key) const override; - QStringList availableMetaData() const override; - - void setMetaData(const MmRendererMetaData &data); - -private: - MmRendererMetaData m_metaData; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp deleted file mode 100644 index 68cb47c3c..000000000 --- a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mmrendererplayervideorenderercontrol.h" - -#include "windowgrabber.h" - -#include <QCoreApplication> -#include <QDebug> -#include <QVideoSurfaceFormat> -#include <QOpenGLContext> - -#include <mm/renderer.h> - -QT_BEGIN_NAMESPACE - -static int winIdCounter = 0; - -MmRendererPlayerVideoRendererControl::MmRendererPlayerVideoRendererControl(QObject *parent) - : QVideoRendererControl(parent) - , m_windowGrabber(new WindowGrabber(this)) - , m_context(0) - , m_videoId(-1) -{ - connect(m_windowGrabber, SIGNAL(updateScene(const QSize &)), SLOT(updateScene(const QSize &))); -} - -MmRendererPlayerVideoRendererControl::~MmRendererPlayerVideoRendererControl() -{ - detachDisplay(); -} - -QAbstractVideoSurface *MmRendererPlayerVideoRendererControl::surface() const -{ - return m_surface; -} - -void MmRendererPlayerVideoRendererControl::setSurface(QAbstractVideoSurface *surface) -{ - m_surface = QPointer<QAbstractVideoSurface>(surface); - if (QOpenGLContext::currentContext()) - m_windowGrabber->checkForEglImageExtension(); - else if (m_surface) - m_surface->setProperty("_q_GLThreadCallback", QVariant::fromValue<QObject*>(this)); -} - -void MmRendererPlayerVideoRendererControl::attachDisplay(mmr_context_t *context) -{ - if (m_videoId != -1) { - qWarning() << "MmRendererPlayerVideoRendererControl: Video output already attached!"; - return; - } - - if (!context) { - qWarning() << "MmRendererPlayerVideoRendererControl: No media player context!"; - return; - } - - const QByteArray windowGroupId = m_windowGrabber->windowGroupId(); - if (windowGroupId.isEmpty()) { - qWarning() << "MmRendererPlayerVideoRendererControl: Unable to find window group"; - return; - } - - const QString windowName = QStringLiteral("MmRendererPlayerVideoRendererControl_%1_%2") - .arg(winIdCounter++) - .arg(QCoreApplication::applicationPid()); - - m_windowGrabber->setWindowId(windowName.toLatin1()); - - // Start with an invisible window, because we just want to grab the frames from it. - const QString videoDeviceUrl = QStringLiteral("screen:?winid=%1&wingrp=%2&initflags=invisible&nodstviewport=1") - .arg(windowName) - .arg(QString::fromLatin1(windowGroupId)); - - m_videoId = mmr_output_attach(context, videoDeviceUrl.toLatin1(), "video"); - if (m_videoId == -1) { - qWarning() << "mmr_output_attach() for video failed"; - return; - } - - m_context = context; -} - -void MmRendererPlayerVideoRendererControl::detachDisplay() -{ - m_windowGrabber->stop(); - - if (m_surface) - m_surface->stop(); - - if (m_context && m_videoId != -1) - mmr_output_detach(m_context, m_videoId); - - m_context = 0; - m_videoId = -1; -} - -void MmRendererPlayerVideoRendererControl::pause() -{ - m_windowGrabber->pause(); -} - -void MmRendererPlayerVideoRendererControl::resume() -{ - m_windowGrabber->resume(); -} - -class QnxTextureBuffer : public QAbstractVideoBuffer -{ -public: - QnxTextureBuffer(WindowGrabber *windowGrabber) : - QAbstractVideoBuffer(QAbstractVideoBuffer::GLTextureHandle) - { - m_windowGrabber = windowGrabber; - m_handle = 0; - } - MapMode mapMode() const { - return QAbstractVideoBuffer::ReadWrite; - } - void unmap() {} - MapData map(MapMode mode) override { return {}; } - QVariant handle() const { - if (!m_handle) { - const_cast<QnxTextureBuffer*>(this)->m_handle = m_windowGrabber->getNextTextureId(); - } - return m_handle; - } -private: - WindowGrabber *m_windowGrabber; - int m_handle; -}; - -void MmRendererPlayerVideoRendererControl::updateScene(const QSize &size) -{ - if (m_surface) { - if (!m_surface->isActive()) { - if (m_windowGrabber->eglImageSupported()) { - m_surface->start(QVideoSurfaceFormat(size, QVideoFrame::Format_BGR32, - QAbstractVideoBuffer::GLTextureHandle)); - } else { - m_surface->start(QVideoSurfaceFormat(size, QVideoFrame::Format_ARGB32)); - } - } else { - if (m_surface->surfaceFormat().frameSize() != size) { - m_surface->stop(); - if (m_windowGrabber->eglImageSupported()) { - m_surface->start(QVideoSurfaceFormat(size, QVideoFrame::Format_BGR32, - QAbstractVideoBuffer::GLTextureHandle)); - } else { - m_surface->start(QVideoSurfaceFormat(size, QVideoFrame::Format_ARGB32)); - } - } - } - - // Depending on the support of EGL images on the current platform we either pass a texture - // handle or a copy of the image data - if (m_windowGrabber->eglImageSupported()) { - QnxTextureBuffer *textBuffer = new QnxTextureBuffer(m_windowGrabber); - QVideoFrame actualFrame(textBuffer, size, QVideoFrame::Format_BGR32); - m_surface->present(actualFrame); - } else { - m_surface->present(m_windowGrabber->getNextImage().copy()); - } - } -} - -void MmRendererPlayerVideoRendererControl::customEvent(QEvent *e) -{ - // This is running in the render thread (OpenGL enabled) - if (e->type() == QEvent::User) - m_windowGrabber->checkForEglImageExtension(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.h b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.h deleted file mode 100644 index c547ef534..000000000 --- a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef MMRENDERERPLAYERVIDEORENDERERCONTROL_H -#define MMRENDERERPLAYERVIDEORENDERERCONTROL_H - -#include <QPointer> -#include <qabstractvideosurface.h> -#include <qvideorenderercontrol.h> - -typedef struct mmr_context mmr_context_t; - -QT_BEGIN_NAMESPACE - -class WindowGrabber; - -class MmRendererPlayerVideoRendererControl : public QVideoRendererControl -{ - Q_OBJECT -public: - explicit MmRendererPlayerVideoRendererControl(QObject *parent = 0); - ~MmRendererPlayerVideoRendererControl(); - - QAbstractVideoSurface *surface() const override; - void setSurface(QAbstractVideoSurface *surface) override; - - // Called by media control - void attachDisplay(mmr_context_t *context); - void detachDisplay(); - void pause(); - void resume(); - - void customEvent(QEvent *) override; - -private Q_SLOTS: - void updateScene(const QSize &size); - -private: - QPointer<QAbstractVideoSurface> m_surface; - - WindowGrabber* m_windowGrabber; - mmr_context_t *m_context; - - int m_videoId; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/mediaplayer/mmrendererutil.cpp b/src/plugins/qnx/mediaplayer/mmrendererutil.cpp deleted file mode 100644 index d8af4a746..000000000 --- a/src/plugins/qnx/mediaplayer/mmrendererutil.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "mmrendererutil.h" - -#include <QDebug> -#include <QDir> -#include <QFile> -#include <QJsonDocument> -#include <QJsonObject> -#include <QJsonValue> -#include <QMutex> -#include <QMutex> -#include <QString> -#include <QXmlStreamReader> - -#include <mm/renderer.h> - -QT_BEGIN_NAMESPACE - -struct MmError { - int errorCode; - const char *name; -}; - -#define MM_ERROR_ENTRY(error) { error, #error } -static const MmError mmErrors[] = { - MM_ERROR_ENTRY(MMR_ERROR_NONE), - MM_ERROR_ENTRY(MMR_ERROR_UNKNOWN ), - MM_ERROR_ENTRY(MMR_ERROR_INVALID_PARAMETER ), - MM_ERROR_ENTRY(MMR_ERROR_INVALID_STATE), - MM_ERROR_ENTRY(MMR_ERROR_UNSUPPORTED_VALUE), - MM_ERROR_ENTRY(MMR_ERROR_UNSUPPORTED_MEDIA_TYPE), - MM_ERROR_ENTRY(MMR_ERROR_MEDIA_PROTECTED), - MM_ERROR_ENTRY(MMR_ERROR_UNSUPPORTED_OPERATION), - MM_ERROR_ENTRY(MMR_ERROR_READ), - MM_ERROR_ENTRY(MMR_ERROR_WRITE), - MM_ERROR_ENTRY(MMR_ERROR_MEDIA_UNAVAILABLE), - MM_ERROR_ENTRY(MMR_ERROR_MEDIA_CORRUPTED), - MM_ERROR_ENTRY(MMR_ERROR_OUTPUT_UNAVAILABLE), - MM_ERROR_ENTRY(MMR_ERROR_NO_MEMORY), - MM_ERROR_ENTRY(MMR_ERROR_RESOURCE_UNAVAILABLE), - MM_ERROR_ENTRY(MMR_ERROR_MEDIA_DRM_NO_RIGHTS), - MM_ERROR_ENTRY(MMR_ERROR_DRM_CORRUPTED_DATA_STORE), - MM_ERROR_ENTRY(MMR_ERROR_DRM_OUTPUT_PROTECTION), - MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_HDMI), - MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_DISPLAYPORT), - MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_DVI), - MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_ANALOG_VIDEO), - MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_ANALOG_AUDIO), - MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_TOSLINK), - MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_SPDIF), - MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_BLUETOOTH), - MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_WIRELESSHD), -}; -static const unsigned int numMmErrors = sizeof(mmErrors) / sizeof(MmError); - -static QBasicMutex roleMapMutex; -static bool roleMapInitialized = false; -static QString roleMap[QAudio::CustomRole + 1]; - -template <typename T, size_t N> -constexpr size_t countof(T (&)[N]) -{ - return N; -} - -constexpr bool inBounds(QAudio::Role r) -{ - return r >= 0 && r < countof(roleMap); -} - -QString keyValueMapsLocation() -{ - QByteArray qtKeyValueMaps = qgetenv("QT_KEY_VALUE_MAPS"); - if (qtKeyValueMaps.isNull()) - return QStringLiteral("/etc/qt/keyvaluemaps"); - else - return qtKeyValueMaps; -} - -QJsonObject loadMapObject(const QString &keyValueMapPath) -{ - QFile mapFile(keyValueMapsLocation() + keyValueMapPath); - if (mapFile.open(QIODevice::ReadOnly)) { - QByteArray mapFileContents = mapFile.readAll(); - QJsonDocument mapDocument = QJsonDocument::fromJson(mapFileContents); - if (mapDocument.isObject()) { - QJsonObject mapObject = mapDocument.object(); - return mapObject; - } - } - return QJsonObject(); -} - -static void loadRoleMap() -{ - QMutexLocker locker(&roleMapMutex); - - if (!roleMapInitialized) { - QJsonObject mapObject = loadMapObject("/QAudio/Role.json"); - if (!mapObject.isEmpty()) { - // Wrapping the loads in a switch like this ensures that anyone adding - // a new enumerator will be notified that this code must be updated. A - // compile error will occur because the enumerator is missing from the - // switch. A compile error will also occur if the enumerator used to - // size the mapping table isn't updated when a new enumerator is added. - // One or more enumerators will be outside the bounds of the array when - // the wrong enumerator is used to size the array. - // - // The code loads a mapping for each enumerator because role is set - // to UnknownRole and all the cases drop through to the next case. -#pragma GCC diagnostic push -#pragma GCC diagnostic error "-Wswitch" -#define loadRoleMapping(r) \ - case QAudio::r: \ - static_assert(inBounds(QAudio::r), #r " out-of-bounds." \ - " Do you need to change the enumerator used to size the mapping table" \ - " because you added new QAudio::Role enumerators?"); \ - roleMap[QAudio::r] = mapObject.value(QLatin1String(#r)).toString(); - - QAudio::Role role = QAudio::UnknownRole; - switch (role) { - loadRoleMapping(UnknownRole); - loadRoleMapping(MusicRole); - loadRoleMapping(VideoRole); - loadRoleMapping(VoiceCommunicationRole); - loadRoleMapping(AlarmRole); - loadRoleMapping(NotificationRole); - loadRoleMapping(RingtoneRole); - loadRoleMapping(AccessibilityRole); - loadRoleMapping(SonificationRole); - loadRoleMapping(GameRole); - loadRoleMapping(CustomRole); - } -#undef loadRoleMapping -#pragma GCC diagnostic pop - - if (!roleMap[QAudio::CustomRole].isEmpty()) { - qWarning("CustomRole mapping ignored"); - roleMap[QAudio::CustomRole].clear(); - } - } - - roleMapInitialized = true; - } -} - -QString mmErrorMessage(const QString &msg, mmr_context_t *context, int *errorCode) -{ - const mmr_error_info_t * const mmError = mmr_error_info(context); - - if (errorCode) - *errorCode = mmError->error_code; - - if (mmError->error_code < numMmErrors) { - return QString("%1: %2 (code %3)").arg(msg).arg(mmErrors[mmError->error_code].name) - .arg(mmError->error_code); - } else { - return QString("%1: Unknown error code %2").arg(msg).arg(mmError->error_code); - } -} - -bool checkForDrmPermission() -{ - QDir sandboxDir = QDir::home(); // always returns 'data' directory - sandboxDir.cdUp(); // change to app sandbox directory - - QFile file(sandboxDir.filePath("app/native/bar-descriptor.xml")); - if (!file.open(QIODevice::ReadOnly)) { - qWarning() << "checkForDrmPermission: Unable to open bar-descriptor.xml"; - return false; - } - - QXmlStreamReader reader(&file); - while (!reader.atEnd()) { - reader.readNextStartElement(); - if (reader.name() == QLatin1String("action") - || reader.name() == QLatin1String("permission")) { - if (reader.readElementText().trimmed() == QLatin1String("access_protected_media")) - return true; - } - } - - return false; -} - -QString qnxAudioType(QAudio::Role role) -{ - loadRoleMap(); - - if (role >= 0 && role < countof(roleMap)) - return roleMap[role]; - else - return QString(); -} - -QList<QAudio::Role> qnxSupportedAudioRoles() -{ - loadRoleMap(); - - QList<QAudio::Role> result; - for (size_t i = 0; i < countof(roleMap); ++i) { - if (!roleMap[i].isEmpty() || (i == QAudio::UnknownRole)) - result.append(static_cast<QAudio::Role>(i)); - } - - return result; -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/mediaplayer/mmrendererutil.h b/src/plugins/qnx/mediaplayer/mmrendererutil.h deleted file mode 100644 index ac6f73a7d..000000000 --- a/src/plugins/qnx/mediaplayer/mmrendererutil.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef MMRENDERERUTIL_H -#define MMRENDERERUTIL_H - -#include <QtCore/qglobal.h> -#include <QtMultimedia/qaudio.h> - -typedef struct mmr_context mmr_context_t; - -QT_BEGIN_NAMESPACE - -class QString; - -QString mmErrorMessage(const QString &msg, mmr_context_t *context, int * errorCode = 0); - -bool checkForDrmPermission(); - -QString qnxAudioType(QAudio::Role role); -QList<QAudio::Role> qnxSupportedAudioRoles(); - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.cpp b/src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.cpp deleted file mode 100644 index fbd698eea..000000000 --- a/src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.cpp +++ /dev/null @@ -1,413 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "mmrenderervideowindowcontrol.h" -#include "mmrendererutil.h" -#include <QtCore/qdebug.h> -#include <QtGui/qguiapplication.h> -#include <QtGui/qpa/qplatformnativeinterface.h> -#include <QtGui/qscreen.h> -#include <QtGui/qwindow.h> -#include <mm/renderer.h> - -QT_BEGIN_NAMESPACE - -static int winIdCounter = 0; - -MmRendererVideoWindowControl::MmRendererVideoWindowControl(QObject *parent) - : QVideoWindowControl(parent), - m_videoId(-1), - m_winId(0), - m_context(0), - m_fullscreen(false), - m_aspectRatioMode(Qt::IgnoreAspectRatio), - m_window(0), - m_hue(0), - m_brightness(0), - m_contrast(0), - m_saturation(0) -{ -} - -MmRendererVideoWindowControl::~MmRendererVideoWindowControl() -{ -} - -WId MmRendererVideoWindowControl::winId() const -{ - return m_winId; -} - -void MmRendererVideoWindowControl::setWinId(WId id) -{ - m_winId = id; -} - -QRect MmRendererVideoWindowControl::displayRect() const -{ - return m_displayRect ; -} - -void MmRendererVideoWindowControl::setDisplayRect(const QRect &rect) -{ - if (m_displayRect != rect) { - m_displayRect = rect; - updateVideoPosition(); - } -} - -bool MmRendererVideoWindowControl::isFullScreen() const -{ - return m_fullscreen; -} - -void MmRendererVideoWindowControl::setFullScreen(bool fullScreen) -{ - if (m_fullscreen != fullScreen) { - m_fullscreen = fullScreen; - updateVideoPosition(); - emit fullScreenChanged(m_fullscreen); - } -} - -void MmRendererVideoWindowControl::repaint() -{ - // Nothing we can or should do here -} - -QSize MmRendererVideoWindowControl::nativeSize() const -{ - return QSize(m_metaData.width(), m_metaData.height()); -} - -Qt::AspectRatioMode MmRendererVideoWindowControl::aspectRatioMode() const -{ - return m_aspectRatioMode; -} - -void MmRendererVideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - m_aspectRatioMode = mode; -} - -int MmRendererVideoWindowControl::brightness() const -{ - return m_brightness; -} - -void MmRendererVideoWindowControl::setBrightness(int brightness) -{ - if (m_brightness != brightness) { - m_brightness = brightness; - updateBrightness(); - emit brightnessChanged(m_brightness); - } -} - -int MmRendererVideoWindowControl::contrast() const -{ - return m_contrast; -} - -void MmRendererVideoWindowControl::setContrast(int contrast) -{ - if (m_contrast != contrast) { - m_contrast = contrast; - updateContrast(); - emit contrastChanged(m_contrast); - } -} - -int MmRendererVideoWindowControl::hue() const -{ - return m_hue; -} - -void MmRendererVideoWindowControl::setHue(int hue) -{ - if (m_hue != hue) { - m_hue = hue; - updateHue(); - emit hueChanged(m_hue); - } -} - -int MmRendererVideoWindowControl::saturation() const -{ - return m_saturation; -} - -void MmRendererVideoWindowControl::setSaturation(int saturation) -{ - if (m_saturation != saturation) { - m_saturation = saturation; - updateSaturation(); - emit saturationChanged(m_saturation); - } -} - -void MmRendererVideoWindowControl::attachDisplay(mmr_context_t *context) -{ - if (m_videoId != -1) { - qDebug() << "MmRendererVideoWindowControl: Video output already attached!"; - return; - } - - if (!context) { - qDebug() << "MmRendererVideoWindowControl: No media player context!"; - return; - } - - QWindow *window = findWindow(m_winId); - if (!window) { - qDebug() << "MmRendererVideoWindowControl: No video window!"; - return; - } - - QPlatformNativeInterface * const nativeInterface = QGuiApplication::platformNativeInterface(); - if (!nativeInterface) { - qDebug() << "MmRendererVideoWindowControl: Unable to get platform native interface"; - return; - } - - const char * const groupNameData = static_cast<const char *>( - nativeInterface->nativeResourceForWindow("windowGroup", window)); - if (!groupNameData) { - qDebug() << "MmRendererVideoWindowControl: Unable to find window group for window" - << window; - return; - } - - const QString groupName = QString::fromLatin1(groupNameData); - m_windowName = QString("MmRendererVideoWindowControl_%1_%2").arg(winIdCounter++) - .arg(QCoreApplication::applicationPid()); - - nativeInterface->setWindowProperty(window->handle(), - QStringLiteral("mmRendererWindowName"), m_windowName); - - // Start with an invisible window. If it would be visible right away, it would be at the wrong - // position, and we can only change the position once we get the window handle. - const QString videoDeviceUrl = - QString("screen:?winid=%1&wingrp=%2&initflags=invisible&nodstviewport=1").arg(m_windowName).arg(groupName); - - m_videoId = mmr_output_attach(context, videoDeviceUrl.toLatin1(), "video"); - if (m_videoId == -1) { - qDebug() << mmErrorMessage("mmr_output_attach() for video failed", context); - return; - } - - m_context = context; - updateVideoPosition(); - updateHue(); - updateContrast(); - updateBrightness(); - updateSaturation(); -} - -void MmRendererVideoWindowControl::updateVideoPosition() -{ - QWindow * const window = findWindow(m_winId); - if (m_context && m_videoId != -1 && window) { - QPoint topLeft = m_displayRect.topLeft(); - - QScreen * const screen = window->screen(); - int width = m_fullscreen ? - screen->size().width() : - m_displayRect.width(); - int height = m_fullscreen ? - screen->size().height() : - m_displayRect.height(); - - if (m_metaData.hasVideo() && m_metaData.width() > 0 && m_metaData.height() > 0) { - // We need the source size to do aspect ratio scaling - const qreal sourceRatio = m_metaData.width() / static_cast<float>(m_metaData.height()); - const qreal targetRatio = width / static_cast<float>(height); - - if (m_aspectRatioMode == Qt::KeepAspectRatio) { - if (targetRatio < sourceRatio) { - // Need to make height smaller - const int newHeight = width / sourceRatio; - const int heightDiff = height - newHeight; - topLeft.ry() += heightDiff / 2; - height = newHeight; - } else { - // Need to make width smaller - const int newWidth = sourceRatio * height; - const int widthDiff = width - newWidth; - topLeft.rx() += widthDiff / 2; - width = newWidth; - } - - } else if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) { - if (targetRatio < sourceRatio) { - // Need to make width larger - const int newWidth = sourceRatio * height; - const int widthDiff = newWidth - width; - topLeft.rx() -= widthDiff / 2; - width = newWidth; - } else { - // Need to make height larger - const int newHeight = width / sourceRatio; - const int heightDiff = newHeight - height; - topLeft.ry() -= heightDiff / 2; - height = newHeight; - } - } - } - - if (m_window != 0) { - const int position[2] = { topLeft.x(), topLeft.y() }; - const int size[2] = { width, height }; - const int visible = m_displayRect.isValid(); - if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, position) != 0) - perror("Setting video position failed"); - if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, size) != 0) - perror("Setting video size failed"); - if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &visible) != 0) - perror("Setting video visibility failed"); - } - } -} - -void MmRendererVideoWindowControl::updateBrightness() -{ - if (m_window != 0) { - const int backendValue = m_brightness * 2.55f; - if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BRIGHTNESS, &backendValue) != 0) - perror("Setting brightness failed"); - } -} - -void MmRendererVideoWindowControl::updateContrast() -{ - if (m_window != 0) { - const int backendValue = m_contrast * 1.27f; - if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_CONTRAST, &backendValue) != 0) - perror("Setting contrast failed"); - } -} - -void MmRendererVideoWindowControl::updateHue() -{ - if (m_window != 0) { - const int backendValue = m_hue * 1.27f; - if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_HUE, &backendValue) != 0) - perror("Setting hue failed"); - } -} - -void MmRendererVideoWindowControl::updateSaturation() -{ - if (m_window != 0) { - const int backendValue = m_saturation * 1.27f; - if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SATURATION, &backendValue) != 0) - perror("Setting saturation failed"); - } -} - -void MmRendererVideoWindowControl::detachDisplay() -{ - if (m_context && m_videoId != -1) - mmr_output_detach(m_context, m_videoId); - - m_context = 0; - m_videoId = -1; - m_metaData.clear(); - m_windowName.clear(); - m_window = 0; - m_hue = 0; - m_brightness = 0; - m_contrast = 0; - m_saturation = 0; -} - -void MmRendererVideoWindowControl::setMetaData(const MmRendererMetaData &metaData) -{ - m_metaData = metaData; - emit nativeSizeChanged(); - - // To handle the updated source size data - updateVideoPosition(); -} - -void MmRendererVideoWindowControl::screenEventHandler(const screen_event_t &screen_event) -{ - int eventType; - if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) { - perror("MmRendererVideoWindowControl: Failed to query screen event type"); - return; - } - - if (eventType != SCREEN_EVENT_CREATE) - return; - - screen_window_t window = 0; - if (screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0) { - perror("MmRendererVideoWindowControl: Failed to query window property"); - return; - } - - const int maxIdStrLength = 128; - char idString[maxIdStrLength]; - if (screen_get_window_property_cv(window, SCREEN_PROPERTY_ID_STRING, maxIdStrLength, idString) != 0) { - perror("MmRendererVideoWindowControl: Failed to query window ID string"); - return; - } - - if (m_windowName == idString) { - m_window = window; - updateVideoPosition(); - - const int visibleFlag = 1; - if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &visibleFlag) != 0) { - perror("MmRendererVideoWindowControl: Failed to make window visible"); - return; - } - } -} - -QWindow *MmRendererVideoWindowControl::findWindow(WId id) const -{ - const auto allWindows = QGuiApplication::allWindows(); - for (QWindow *window : allWindows) - if (window->winId() == id) - return window; - return 0; -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.h b/src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.h deleted file mode 100644 index 8327e259d..000000000 --- a/src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef MMRENDERERVIDEOWINDOWCONTROL_H -#define MMRENDERERVIDEOWINDOWCONTROL_H - -#include "mmrenderermetadata.h" -#include <qvideowindowcontrol.h> -#include <screen/screen.h> - -typedef struct mmr_context mmr_context_t; - -QT_BEGIN_NAMESPACE - -class MmRendererVideoWindowControl : public QVideoWindowControl -{ - Q_OBJECT -public: - explicit MmRendererVideoWindowControl(QObject *parent = 0); - ~MmRendererVideoWindowControl(); - - WId winId() const override; - void setWinId(WId id) override; - - QRect displayRect() const override; - void setDisplayRect(const QRect &rect) override; - - bool isFullScreen() const override; - void setFullScreen(bool fullScreen) override; - - void repaint() override; - - QSize nativeSize() const override; - - Qt::AspectRatioMode aspectRatioMode() const override; - void setAspectRatioMode(Qt::AspectRatioMode mode) override; - - int brightness() const override; - void setBrightness(int brightness) override; - - int contrast() const override; - void setContrast(int contrast) override; - - int hue() const override; - void setHue(int hue) override; - - int saturation() const override; - void setSaturation(int saturation) override; - - // - // Called by media control - // - void detachDisplay(); - void attachDisplay(mmr_context_t *context); - void setMetaData(const MmRendererMetaData &metaData); - void screenEventHandler(const screen_event_t &event); - -private: - QWindow *findWindow(WId id) const; - void updateVideoPosition(); - void updateBrightness(); - void updateContrast(); - void updateHue(); - void updateSaturation(); - - int m_videoId; - WId m_winId; - QRect m_displayRect; - mmr_context_t *m_context; - bool m_fullscreen; - MmRendererMetaData m_metaData; - Qt::AspectRatioMode m_aspectRatioMode; - QString m_windowName; - screen_window_t m_window; - int m_hue; - int m_brightness; - int m_contrast; - int m_saturation; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.cpp b/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.cpp deleted file mode 100644 index b5c9804ab..000000000 --- a/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 QNX Software Systems. All rights reserved. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mmreventmediaplayercontrol.h" -#include "mmreventthread.h" -#include "mmrenderervideowindowcontrol.h" - -#include <mm/renderer.h> -#include <tuple> - -QT_BEGIN_NAMESPACE - -static std::tuple<int, int, bool> parseBufferLevel(const QByteArray &value) -{ - const int slashPos = value.indexOf('/'); - if (slashPos <= 0) - return std::make_tuple(0, 0, false); - - bool ok = false; - const int level = value.left(slashPos).toInt(&ok); - if (!ok || level < 0) - return std::make_tuple(0, 0, false); - - const int capacity = value.mid(slashPos + 1).toInt(&ok); - if (!ok || capacity < 0) - return std::make_tuple(0, 0, false); - - return std::make_tuple(level, capacity, true); -} - -MmrEventMediaPlayerControl::MmrEventMediaPlayerControl(QObject *parent) - : MmRendererMediaPlayerControl(parent) - , m_eventThread(nullptr) - , m_bufferStatus("") - , m_bufferLevel(0) - , m_bufferCapacity(0) - , m_position(0) - , m_suspended(false) - , m_suspendedReason("unknown") - , m_state(MMR_STATE_IDLE) - , m_speed(0) -{ - openConnection(); -} - -MmrEventMediaPlayerControl::~MmrEventMediaPlayerControl() -{ - destroy(); -} - -void MmrEventMediaPlayerControl::startMonitoring() -{ - m_eventThread = new MmrEventThread(m_context); - - connect(m_eventThread, &MmrEventThread::eventPending, - this, &MmrEventMediaPlayerControl::readEvents); - - m_eventThread->setObjectName(QStringLiteral("MmrEventThread-") + QString::number(m_id)); - m_eventThread->start(); -} - -void MmrEventMediaPlayerControl::stopMonitoring() -{ - delete m_eventThread; - m_eventThread = nullptr; -} - -void MmrEventMediaPlayerControl::resetMonitoring() -{ - m_bufferStatus = ""; - m_bufferLevel = 0; - m_bufferCapacity = 0; - m_position = 0; - m_suspended = false; - m_suspendedReason = "unknown"; - m_state = MMR_STATE_IDLE; - m_speed = 0; -} - -bool MmrEventMediaPlayerControl::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) -{ - Q_UNUSED(result); - if (eventType == "screen_event_t") { - screen_event_t event = static_cast<screen_event_t>(message); - if (MmRendererVideoWindowControl *control = videoWindowControl()) - control->screenEventHandler(event); - } - - return false; -} - -void MmrEventMediaPlayerControl::readEvents() -{ - const mmr_event_t *event; - - while ((event = mmr_event_get(m_context))) { - if (event->type == MMR_EVENT_NONE) - break; - - switch (event->type) { - case MMR_EVENT_STATUS: { - if (event->data) { - const strm_string_t *value; - value = strm_dict_find_rstr(event->data, "bufferstatus"); - if (value) { - m_bufferStatus = QByteArray(strm_string_get(value)); - if (!m_suspended) - setMmBufferStatus(m_bufferStatus); - } - - value = strm_dict_find_rstr(event->data, "bufferlevel"); - if (value) { - const char *cstrValue = strm_string_get(value); - int level; - int capacity; - bool ok; - std::tie(level, capacity, ok) = parseBufferLevel(QByteArray(cstrValue)); - if (!ok) { - qCritical("Could not parse buffer capacity from '%s'", cstrValue); - } else { - m_bufferLevel = level; - m_bufferCapacity = capacity; - setMmBufferLevel(level, capacity); - } - } - - value = strm_dict_find_rstr(event->data, "suspended"); - if (value) { - if (!m_suspended) { - m_suspended = true; - m_suspendedReason = strm_string_get(value); - handleMmSuspend(m_suspendedReason); - } - } else if (m_suspended) { - m_suspended = false; - handleMmSuspendRemoval(m_bufferStatus); - } - } - - if (event->pos_str) { - const QByteArray valueBa = QByteArray(event->pos_str); - bool ok; - m_position = valueBa.toLongLong(&ok); - if (!ok) { - qCritical("Could not parse position from '%s'", valueBa.constData()); - } else { - setMmPosition(m_position); - } - } - break; - } - case MMR_EVENT_STATE: { - if (event->state == MMR_STATE_PLAYING && m_speed != event->speed) { - m_speed = event->speed; - if (m_speed == 0) - handleMmPause(); - else - handleMmPlay(); - } - break; - } - case MMR_EVENT_METADATA: { - updateMetaData(event->data); - break; - } - case MMR_EVENT_ERROR: - case MMR_EVENT_NONE: - case MMR_EVENT_OVERFLOW: - case MMR_EVENT_WARNING: - case MMR_EVENT_PLAYLIST: - case MMR_EVENT_INPUT: - case MMR_EVENT_OUTPUT: - case MMR_EVENT_CTXTPAR: - case MMR_EVENT_TRKPAR: - case MMR_EVENT_OTHER: { - break; - } - } - - // Currently, any exit from the playing state is considered a stop (end-of-media). - // If you ever need to separate end-of-media from things like "stopped unexpectedly" - // or "stopped because of an error", you'll find that end-of-media is signaled by an - // MMR_EVENT_ERROR of MMR_ERROR_NONE with state changed to MMR_STATE_STOPPED. - if (event->state != m_state && m_state == MMR_STATE_PLAYING) - handleMmStopped(); - m_state = event->state; - } - - if (m_eventThread) - m_eventThread->signalRead(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.h b/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.h deleted file mode 100644 index e6c138f89..000000000 --- a/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 QNX Software Systems. All rights reserved. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef MMREVENTMEDIAPLAYERCONTROL_H -#define MMREVENTMEDIAPLAYERCONTROL_H - -#include "mmrenderermediaplayercontrol.h" - -#include <mm/renderer/events.h> - -QT_BEGIN_NAMESPACE - -class MmrEventThread; - -class MmrEventMediaPlayerControl final : public MmRendererMediaPlayerControl -{ - Q_OBJECT -public: - explicit MmrEventMediaPlayerControl(QObject *parent = 0); - ~MmrEventMediaPlayerControl() override; - - void startMonitoring() override; - void stopMonitoring() override; - void resetMonitoring() override; - - bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override; - -private Q_SLOTS: - void readEvents(); - -private: - MmrEventThread *m_eventThread; - - // status properties. - QByteArray m_bufferStatus; - int m_bufferLevel; - int m_bufferCapacity; - qint64 m_position; - bool m_suspended; - QByteArray m_suspendedReason; - - // state properties. - mmr_state_t m_state; - int m_speed; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/mediaplayer/mmreventthread.cpp b/src/plugins/qnx/mediaplayer/mmreventthread.cpp deleted file mode 100644 index 25f26e216..000000000 --- a/src/plugins/qnx/mediaplayer/mmreventthread.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 QNX Software Systems. All rights reserved. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mmreventthread.h" - -#include <QtCore/QDebug> - -#include <errno.h> -#include <mm/renderer/events.h> -#include <sys/neutrino.h> - -static const int c_mmrCode = _PULSE_CODE_MINAVAIL + 0; -static const int c_readCode = _PULSE_CODE_MINAVAIL + 1; -static const int c_quitCode = _PULSE_CODE_MINAVAIL + 2; - -MmrEventThread::MmrEventThread(mmr_context_t *context) - : QThread(), - m_mmrContext(context) -{ - if (Q_UNLIKELY((m_channelId = ChannelCreate(_NTO_CHF_DISCONNECT - | _NTO_CHF_UNBLOCK - | _NTO_CHF_PRIVATE)) == -1)) { - qFatal("MmrEventThread: Can't continue without a channel"); - } - - if (Q_UNLIKELY((m_connectionId = ConnectAttach(0, 0, m_channelId, - _NTO_SIDE_CHANNEL, 0)) == -1)) { - ChannelDestroy(m_channelId); - qFatal("MmrEventThread: Can't continue without a channel connection"); - } - - SIGEV_PULSE_INIT(&m_mmrEvent, m_connectionId, SIGEV_PULSE_PRIO_INHERIT, c_mmrCode, 0); -} - -MmrEventThread::~MmrEventThread() -{ - // block until thread terminates - shutdown(); - - ConnectDetach(m_connectionId); - ChannelDestroy(m_channelId); -} - -void MmrEventThread::run() -{ - int armResult = mmr_event_arm(m_mmrContext, &m_mmrEvent); - if (armResult > 0) - emit eventPending(); - - while (1) { - struct _pulse msg; - memset(&msg, 0, sizeof(msg)); - int receiveId = MsgReceive(m_channelId, &msg, sizeof(msg), nullptr); - if (receiveId == 0) { - if (msg.code == c_mmrCode) { - emit eventPending(); - } else if (msg.code == c_readCode) { - armResult = mmr_event_arm(m_mmrContext, &m_mmrEvent); - if (armResult > 0) - emit eventPending(); - } else if (msg.code == c_quitCode) { - break; - } else { - qWarning() << Q_FUNC_INFO << "Unexpected pulse" << msg.code; - } - } else if (receiveId > 0) { - qWarning() << Q_FUNC_INFO << "Unexpected message" << msg.code; - } else { - qWarning() << Q_FUNC_INFO << "MsgReceive error" << strerror(errno); - } - } -} - -void MmrEventThread::signalRead() -{ - MsgSendPulse(m_connectionId, SIGEV_PULSE_PRIO_INHERIT, c_readCode, 0); -} - -void MmrEventThread::shutdown() -{ - MsgSendPulse(m_connectionId, SIGEV_PULSE_PRIO_INHERIT, c_quitCode, 0); - - // block until thread terminates - wait(); -} diff --git a/src/plugins/qnx/mediaplayer/mmreventthread.h b/src/plugins/qnx/mediaplayer/mmreventthread.h deleted file mode 100644 index f7bc5cf5e..000000000 --- a/src/plugins/qnx/mediaplayer/mmreventthread.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 QNX Software Systems. All rights reserved. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MMREVENTTHREAD_H -#define MMREVENTTHREAD_H - -#include <QtCore/QThread> - -#include <sys/neutrino.h> -#include <sys/siginfo.h> - -QT_BEGIN_NAMESPACE - -typedef struct mmr_context mmr_context_t; - -class MmrEventThread : public QThread -{ - Q_OBJECT - -public: - MmrEventThread(mmr_context_t *context); - ~MmrEventThread() override; - - void signalRead(); - -protected: - void run() override; - -Q_SIGNALS: - void eventPending(); - -private: - void shutdown(); - - int m_channelId; - int m_connectionId; - struct sigevent m_mmrEvent; - mmr_context_t *m_mmrContext; -}; - -QT_END_NAMESPACE - -#endif // MMREVENTTHREAD_H diff --git a/src/plugins/qnx/neutrino_mediaservice.json b/src/plugins/qnx/neutrino_mediaservice.json deleted file mode 100644 index 919368d73..000000000 --- a/src/plugins/qnx/neutrino_mediaservice.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["neutrinomultimedia"], - "Services": ["org.qt-project.qt.mediaplayer"] -} diff --git a/src/plugins/qnx/neutrinoserviceplugin.cpp b/src/plugins/qnx/neutrinoserviceplugin.cpp deleted file mode 100644 index 25a26d28f..000000000 --- a/src/plugins/qnx/neutrinoserviceplugin.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "neutrinoserviceplugin.h" - -#include "mmrenderermediaplayerservice.h" - -QT_BEGIN_NAMESPACE - -NeutrinoServicePlugin::NeutrinoServicePlugin() -{ -} - -QMediaService *NeutrinoServicePlugin::create(const QString &key) -{ - if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) - return new MmRendererMediaPlayerService(); - - return 0; -} - -void NeutrinoServicePlugin::release(QMediaService *service) -{ - delete service; -} - -QT_END_NAMESPACE diff --git a/src/plugins/qnx/neutrinoserviceplugin.h b/src/plugins/qnx/neutrinoserviceplugin.h deleted file mode 100644 index 6fd9752ee..000000000 --- a/src/plugins/qnx/neutrinoserviceplugin.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef NEUTRINOSERVICEPLUGIN_H -#define NEUTRINOSERVICEPLUGIN_H - -#include <qmediaserviceproviderplugin.h> - -QT_BEGIN_NAMESPACE - -class NeutrinoServicePlugin - : public QMediaServiceProviderPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "neutrino_mediaservice.json") -public: - NeutrinoServicePlugin(); - - QMediaService *create(const QString &key) override; - void release(QMediaService *service) override; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qnx/qnx.pro b/src/plugins/qnx/qnx.pro deleted file mode 100644 index 960c614e0..000000000 --- a/src/plugins/qnx/qnx.pro +++ /dev/null @@ -1,15 +0,0 @@ -TARGET = qtmedia_qnx -QT += multimedia-private gui-private core-private - -LIBS += -lscreen - -include(common/common.pri) -include(mediaplayer/mediaplayer.pri) - -HEADERS += neutrinoserviceplugin.h -SOURCES += neutrinoserviceplugin.cpp -OTHER_FILES += neutrino_mediaservice.json -PLUGIN_CLASS_NAME = NeutrinoServicePlugin - -PLUGIN_TYPE = mediaservice -load(qt_plugin) diff --git a/src/plugins/wmf/CMakeLists.txt b/src/plugins/wmf/CMakeLists.txt deleted file mode 100644 index 60875df9a..000000000 --- a/src/plugins/wmf/CMakeLists.txt +++ /dev/null @@ -1,74 +0,0 @@ -# Generated from wmf.pro. - -##################################################################### -## WMFServicePlugin Plugin: -##################################################################### - -qt_internal_add_plugin(WMFServicePlugin - OUTPUT_NAME wmfengine - TYPE mediaservice - SOURCES - ../common/evr/evrcustompresenter.cpp ../common/evr/evrcustompresenter.h - ../common/evr/evrd3dpresentengine.cpp ../common/evr/evrd3dpresentengine.h - ../common/evr/evrdefs.cpp ../common/evr/evrdefs.h - ../common/evr/evrhelpers.cpp ../common/evr/evrhelpers.h - ../common/evr/evrvideowindowcontrol.cpp ../common/evr/evrvideowindowcontrol.h - decoder/mfaudiodecodercontrol.cpp decoder/mfaudiodecodercontrol.h - decoder/mfdecoderservice.cpp decoder/mfdecoderservice.h - decoder/mfdecodersourcereader.cpp decoder/mfdecodersourcereader.h - mfstream.cpp mfstream.h - player/mfactivate.cpp player/mfactivate.h - player/mfaudioendpointcontrol.cpp player/mfaudioendpointcontrol.h - player/mfaudioprobecontrol.cpp player/mfaudioprobecontrol.h - player/mfevrvideowindowcontrol.cpp player/mfevrvideowindowcontrol.h - player/mfmetadatacontrol.cpp player/mfmetadatacontrol.h - player/mfplayercontrol.cpp player/mfplayercontrol.h - player/mfplayerservice.cpp player/mfplayerservice.h - player/mfplayersession.cpp player/mfplayersession.h - player/mftvideo.cpp player/mftvideo.h - player/mfvideoprobecontrol.cpp player/mfvideoprobecontrol.h - player/mfvideorenderercontrol.cpp player/mfvideorenderercontrol.h - player/samplegrabber.cpp player/samplegrabber.h - sourceresolver.cpp sourceresolver.h - wmfserviceplugin.cpp wmfserviceplugin.h - INCLUDE_DIRECTORIES - . - ../common/evr - decoder - player - PUBLIC_LIBRARIES - Qt::Core - Qt::Gui - Qt::GuiPrivate - Qt::MultimediaPrivate - Qt::Network - d3d9 - dxva2 - evr - gdi32 - mf - mfplat - mfreadwrite - mfuuid - user32 - winmm - wmcodecdspuuid - wmf -) - -#### Keys ignored in scope 1:.:.:wmf.pro:<TRUE>: -# OTHER_FILES = "wmf.json" - -## Scopes: -##################################################################### - -qt_internal_extend_target(WMFServicePlugin CONDITION WIN32 AND NOT TARGET Qt::OpenGL - LIBRARIES - gdi32 - user32 -) - -qt_internal_extend_target(WMFServicePlugin CONDITION TARGET Qt::Widgets - PUBLIC_LIBRARIES - Qt::Widgets -) diff --git a/src/plugins/wmf/decoder/decoder.pri b/src/plugins/wmf/decoder/decoder.pri deleted file mode 100644 index 7637ac848..000000000 --- a/src/plugins/wmf/decoder/decoder.pri +++ /dev/null @@ -1,14 +0,0 @@ -INCLUDEPATH += $$PWD - -LIBS += -lmfreadwrite -lwmcodecdspuuid -QMAKE_USE += wmf - -HEADERS += \ - $$PWD/mfdecoderservice.h \ - $$PWD/mfdecodersourcereader.h \ - $$PWD/mfaudiodecodercontrol.h - -SOURCES += \ - $$PWD/mfdecoderservice.cpp \ - $$PWD/mfdecodersourcereader.cpp \ - $$PWD/mfaudiodecodercontrol.cpp diff --git a/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp b/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp deleted file mode 100644 index fcc1743bc..000000000 --- a/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp +++ /dev/null @@ -1,486 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Wmcodecdsp.h" -#include "mfaudiodecodercontrol.h" - -MFAudioDecoderControl::MFAudioDecoderControl(QObject *parent) - : QAudioDecoderControl(parent) - , m_decoderSourceReader(new MFDecoderSourceReader) - , m_sourceResolver(new SourceResolver) - , m_resampler(0) - , m_state(QAudioDecoder::StoppedState) - , m_device(0) - , m_mfInputStreamID(0) - , m_mfOutputStreamID(0) - , m_bufferReady(false) - , m_duration(0) - , m_position(0) - , m_loadingSource(false) - , m_mfOutputType(0) - , m_convertSample(0) - , m_sourceReady(false) - , m_resamplerDirty(false) -{ - CoCreateInstance(CLSID_CResamplerMediaObject, NULL, CLSCTX_INPROC_SERVER, IID_IMFTransform, (LPVOID*)(&m_resampler)); - if (!m_resampler) { - qCritical("MFAudioDecoderControl: Failed to create resampler(CLSID_CResamplerMediaObject)!"); - return; - } - m_resampler->AddInputStreams(1, &m_mfInputStreamID); - - connect(m_sourceResolver, SIGNAL(mediaSourceReady()), this, SLOT(handleMediaSourceReady())); - connect(m_sourceResolver, SIGNAL(error(long)), this, SLOT(handleMediaSourceError(long))); - connect(m_decoderSourceReader, SIGNAL(finished()), this, SLOT(handleSourceFinished())); - - QAudioFormat defaultFormat; - defaultFormat.setCodec("audio/x-raw"); - setAudioFormat(defaultFormat); -} - -MFAudioDecoderControl::~MFAudioDecoderControl() -{ - if (m_mfOutputType) - m_mfOutputType->Release(); - m_decoderSourceReader->shutdown(); - m_decoderSourceReader->Release(); - m_sourceResolver->Release(); - if (m_resampler) - m_resampler->Release(); -} - -QAudioDecoder::State MFAudioDecoderControl::state() const -{ - return m_state; -} - -QString MFAudioDecoderControl::sourceFilename() const -{ - return m_sourceFilename; -} - -void MFAudioDecoderControl::onSourceCleared() -{ - bool positionDirty = false; - bool durationDirty = false; - if (m_position != 0) { - m_position = 0; - positionDirty = true; - } - if (m_duration != 0) { - m_duration = 0; - durationDirty = true; - } - if (positionDirty) - emit positionChanged(m_position); - if (durationDirty) - emit durationChanged(m_duration); -} - -void MFAudioDecoderControl::setSourceFilename(const QString &fileName) -{ - if (!m_device && m_sourceFilename == fileName) - return; - m_sourceReady = false; - m_sourceResolver->cancel(); - m_decoderSourceReader->setSource(0, m_audioFormat); - m_device = 0; - m_sourceFilename = fileName; - if (!m_sourceFilename.isEmpty()) { - m_sourceResolver->shutdown(); - QUrl url; - if (m_sourceFilename.startsWith(':')) - url = QUrl(QStringLiteral("qrc%1").arg(m_sourceFilename)); - else - url = QUrl::fromLocalFile(m_sourceFilename); - m_sourceResolver->load(url, 0); - m_loadingSource = true; - } else { - onSourceCleared(); - } - emit sourceChanged(); -} - -QIODevice* MFAudioDecoderControl::sourceDevice() const -{ - return m_device; -} - -void MFAudioDecoderControl::setSourceDevice(QIODevice *device) -{ - if (m_device == device && m_sourceFilename.isEmpty()) - return; - m_sourceReady = false; - m_sourceResolver->cancel(); - m_decoderSourceReader->setSource(0, m_audioFormat); - m_sourceFilename.clear(); - m_device = device; - if (m_device) { - m_sourceResolver->shutdown(); - m_sourceResolver->load(QUrl(), m_device); - m_loadingSource = true; - } else { - onSourceCleared(); - } - emit sourceChanged(); -} - -void MFAudioDecoderControl::updateResamplerOutputType() -{ - m_resamplerDirty = false; - if (m_audioFormat == m_sourceOutputFormat) - return; - HRESULT hr = m_resampler->SetOutputType(m_mfOutputStreamID, m_mfOutputType, 0); - if (SUCCEEDED(hr)) { - MFT_OUTPUT_STREAM_INFO streamInfo; - m_resampler->GetOutputStreamInfo(m_mfOutputStreamID, &streamInfo); - if ((streamInfo.dwFlags & (MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES)) == 0) { - //if resampler does not allocate output sample memory, we do it here - if (m_convertSample) { - m_convertSample->Release(); - m_convertSample = 0; - } - if (SUCCEEDED(MFCreateSample(&m_convertSample))) { - IMFMediaBuffer *mbuf = 0;; - if (SUCCEEDED(MFCreateMemoryBuffer(streamInfo.cbSize, &mbuf))) { - m_convertSample->AddBuffer(mbuf); - mbuf->Release(); - } - } - } - } else { - qWarning() << "MFAudioDecoderControl: failed to SetOutputType of resampler" << hr; - } -} - -void MFAudioDecoderControl::handleMediaSourceReady() -{ - m_loadingSource = false; - m_sourceReady = true; - IMFMediaType *mediaType = m_decoderSourceReader->setSource(m_sourceResolver->mediaSource(), m_audioFormat); - m_sourceOutputFormat = QAudioFormat(); - - if (mediaType) { - m_sourceOutputFormat = m_audioFormat; - QAudioFormat af = m_audioFormat; - - UINT32 val = 0; - if (SUCCEEDED(mediaType->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &val))) { - m_sourceOutputFormat.setChannelCount(int(val)); - } - if (SUCCEEDED(mediaType->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, &val))) { - m_sourceOutputFormat.setSampleRate(int(val)); - } - if (SUCCEEDED(mediaType->GetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, &val))) { - m_sourceOutputFormat.setSampleSize(int(val)); - } - - GUID subType; - if (SUCCEEDED(mediaType->GetGUID(MF_MT_SUBTYPE, &subType))) { - if (subType == MFAudioFormat_Float) { - m_sourceOutputFormat.setSampleType(QAudioFormat::Float); - } else if (m_sourceOutputFormat.sampleSize() == 8) { - m_sourceOutputFormat.setSampleType(QAudioFormat::UnSignedInt); - } else { - m_sourceOutputFormat.setSampleType(QAudioFormat::SignedInt); - } - } - if (m_sourceOutputFormat.sampleType() != QAudioFormat::Float) { - m_sourceOutputFormat.setByteOrder(QAudioFormat::LittleEndian); - } - - if (m_audioFormat.sampleType() != QAudioFormat::Float - && m_audioFormat.sampleType() != QAudioFormat::SignedInt) { - af.setSampleType(m_sourceOutputFormat.sampleType()); - } - if (af.sampleType() == QAudioFormat::SignedInt) { - af.setByteOrder(QAudioFormat::LittleEndian); - } - if (m_audioFormat.channelCount() <= 0) { - af.setChannelCount(m_sourceOutputFormat.channelCount()); - } - if (m_audioFormat.sampleRate() <= 0) { - af.setSampleRate(m_sourceOutputFormat.sampleRate()); - } - if (m_audioFormat.sampleSize() <= 0) { - af.setSampleSize(m_sourceOutputFormat.sampleSize()); - } - setAudioFormat(af); - } - - if (m_sourceResolver->mediaSource()) { - if (mediaType && m_resampler) { - HRESULT hr = S_OK; - hr = m_resampler->SetInputType(m_mfInputStreamID, mediaType, 0); - if (SUCCEEDED(hr)) { - updateResamplerOutputType(); - } else { - qWarning() << "MFAudioDecoderControl: failed to SetInputType of resampler" << hr; - } - } - IMFPresentationDescriptor *pd; - if (SUCCEEDED(m_sourceResolver->mediaSource()->CreatePresentationDescriptor(&pd))) { - UINT64 duration = 0; - pd->GetUINT64(MF_PD_DURATION, &duration); - pd->Release(); - duration /= 10000; - if (m_duration != qint64(duration)) { - m_duration = qint64(duration); - emit durationChanged(m_duration); - } - } - if (m_state == QAudioDecoder::DecodingState) { - activatePipeline(); - } - } else if (m_state != QAudioDecoder::StoppedState) { - m_state = QAudioDecoder::StoppedState; - emit stateChanged(m_state); - } -} - -void MFAudioDecoderControl::handleMediaSourceError(long hr) -{ - Q_UNUSED(hr); - m_loadingSource = false; - m_decoderSourceReader->setSource(0, m_audioFormat); - if (m_state != QAudioDecoder::StoppedState) { - m_state = QAudioDecoder::StoppedState; - emit stateChanged(m_state); - } -} - -void MFAudioDecoderControl::activatePipeline() -{ - Q_ASSERT(!m_bufferReady); - m_state = QAudioDecoder::DecodingState; - connect(m_decoderSourceReader, SIGNAL(sampleAdded()), this, SLOT(handleSampleAdded())); - if (m_resamplerDirty) { - updateResamplerOutputType(); - } - m_decoderSourceReader->reset(); - m_decoderSourceReader->readNextSample(); - if (m_position != 0) { - m_position = 0; - emit positionChanged(0); - } -} - -void MFAudioDecoderControl::start() -{ - if (m_state != QAudioDecoder::StoppedState) - return; - - if (m_loadingSource) { - //deferred starting - m_state = QAudioDecoder::DecodingState; - emit stateChanged(m_state); - return; - } - - if (!m_decoderSourceReader->mediaSource()) - return; - activatePipeline(); - emit stateChanged(m_state); -} - -void MFAudioDecoderControl::stop() -{ - if (m_state == QAudioDecoder::StoppedState) - return; - m_state = QAudioDecoder::StoppedState; - disconnect(m_decoderSourceReader, SIGNAL(sampleAdded()), this, SLOT(handleSampleAdded())); - if (m_bufferReady) { - m_bufferReady = false; - emit bufferAvailableChanged(m_bufferReady); - } - emit stateChanged(m_state); -} - -void MFAudioDecoderControl::handleSampleAdded() -{ - QList<IMFSample*> samples = m_decoderSourceReader->takeSamples(); - Q_ASSERT(samples.count() > 0); - Q_ASSERT(!m_bufferReady); - Q_ASSERT(m_resampler); - LONGLONG sampleStartTime = 0; - IMFSample *firstSample = samples.first(); - firstSample->GetSampleTime(&sampleStartTime); - QByteArray abuf; - if (m_sourceOutputFormat == m_audioFormat) { - //no need for resampling - for (IMFSample *s : qAsConst(samples)) { - IMFMediaBuffer *buffer; - s->ConvertToContiguousBuffer(&buffer); - DWORD bufLen = 0; - BYTE *buf = 0; - if (SUCCEEDED(buffer->Lock(&buf, NULL, &bufLen))) { - abuf.push_back(QByteArray(reinterpret_cast<char*>(buf), bufLen)); - buffer->Unlock(); - } - buffer->Release(); - LONGLONG sampleTime = 0, sampleDuration = 0; - s->GetSampleTime(&sampleTime); - s->GetSampleDuration(&sampleDuration); - m_position = qint64(sampleTime + sampleDuration) / 10000; - s->Release(); - } - } else { - for (IMFSample *s : qAsConst(samples)) { - HRESULT hr = m_resampler->ProcessInput(m_mfInputStreamID, s, 0); - if (SUCCEEDED(hr)) { - MFT_OUTPUT_DATA_BUFFER outputDataBuffer; - outputDataBuffer.dwStreamID = m_mfOutputStreamID; - while (true) { - outputDataBuffer.pEvents = 0; - outputDataBuffer.dwStatus = 0; - outputDataBuffer.pSample = m_convertSample; - DWORD status = 0; - if (SUCCEEDED(m_resampler->ProcessOutput(0, 1, &outputDataBuffer, &status))) { - IMFMediaBuffer *buffer; - outputDataBuffer.pSample->ConvertToContiguousBuffer(&buffer); - DWORD bufLen = 0; - BYTE *buf = 0; - if (SUCCEEDED(buffer->Lock(&buf, NULL, &bufLen))) { - abuf.push_back(QByteArray(reinterpret_cast<char*>(buf), bufLen)); - buffer->Unlock(); - } - buffer->Release(); - } else { - break; - } - } - } - LONGLONG sampleTime = 0, sampleDuration = 0; - s->GetSampleTime(&sampleTime); - s->GetSampleDuration(&sampleDuration); - m_position = qint64(sampleTime + sampleDuration) / 10000; - s->Release(); - } - } - // WMF uses 100-nanosecond units, QAudioDecoder uses milliseconds, QAudioBuffer uses microseconds... - m_cachedAudioBuffer = QAudioBuffer(abuf, m_audioFormat, qint64(sampleStartTime / 10)); - m_bufferReady = true; - emit positionChanged(m_position); - emit bufferAvailableChanged(m_bufferReady); - emit bufferReady(); -} - -void MFAudioDecoderControl::handleSourceFinished() -{ - stop(); - emit finished(); -} - -QAudioFormat MFAudioDecoderControl::audioFormat() const -{ - return m_audioFormat; -} - -void MFAudioDecoderControl::setAudioFormat(const QAudioFormat &format) -{ - if (m_audioFormat == format || !m_resampler) - return; - if (format.codec() != QLatin1String("audio/x-wav") && format.codec() != QLatin1String("audio/x-raw")) { - qWarning("MFAudioDecoderControl does not accept non-pcm audio format!"); - return; - } - m_audioFormat = format; - - if (m_audioFormat.isValid()) { - IMFMediaType *mediaType = 0; - MFCreateMediaType(&mediaType); - mediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio); - if (format.sampleType() == QAudioFormat::Float) { - mediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_Float); - } else { - mediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM); - } - - mediaType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, UINT32(m_audioFormat.channelCount())); - mediaType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, UINT32(m_audioFormat.sampleRate())); - UINT32 alignmentBlock = UINT32(m_audioFormat.channelCount() * m_audioFormat.sampleSize() / 8); - mediaType->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, alignmentBlock); - UINT32 avgBytesPerSec = UINT32(m_audioFormat.sampleRate() * m_audioFormat.sampleSize() / 8 * m_audioFormat.channelCount()); - mediaType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, avgBytesPerSec); - mediaType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, UINT32(m_audioFormat.sampleSize())); - mediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); - - if (m_mfOutputType) - m_mfOutputType->Release(); - m_mfOutputType = mediaType; - } else { - if (m_mfOutputType) - m_mfOutputType->Release(); - m_mfOutputType = NULL; - } - - if (m_sourceReady && m_state == QAudioDecoder::StoppedState) { - updateResamplerOutputType(); - } else { - m_resamplerDirty = true; - } - - emit formatChanged(m_audioFormat); -} - -QAudioBuffer MFAudioDecoderControl::read() -{ - if (!m_bufferReady) - return QAudioBuffer(); - QAudioBuffer buffer = m_cachedAudioBuffer; - m_bufferReady = false; - emit bufferAvailableChanged(m_bufferReady); - m_decoderSourceReader->readNextSample(); - return buffer; -} - -bool MFAudioDecoderControl::bufferAvailable() const -{ - return m_bufferReady; -} - -qint64 MFAudioDecoderControl::position() const -{ - return m_position; -} - -qint64 MFAudioDecoderControl::duration() const -{ - return m_duration; -} diff --git a/src/plugins/wmf/decoder/mfaudiodecodercontrol.h b/src/plugins/wmf/decoder/mfaudiodecodercontrol.h deleted file mode 100644 index cfb8e9091..000000000 --- a/src/plugins/wmf/decoder/mfaudiodecodercontrol.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFAUDIODECODERCONTROL_H -#define MFAUDIODECODERCONTROL_H - -#include "qaudiodecodercontrol.h" -#include "mfdecodersourcereader.h" -#include "sourceresolver.h" - -QT_USE_NAMESPACE - -class MFAudioDecoderControl : public QAudioDecoderControl -{ - Q_OBJECT -public: - MFAudioDecoderControl(QObject *parent = 0); - ~MFAudioDecoderControl(); - - QAudioDecoder::State state() const; - - QString sourceFilename() const; - void setSourceFilename(const QString &fileName); - - QIODevice* sourceDevice() const; - void setSourceDevice(QIODevice *device); - - void start(); - void stop(); - - QAudioFormat audioFormat() const; - void setAudioFormat(const QAudioFormat &format); - - QAudioBuffer read(); - bool bufferAvailable() const; - - qint64 position() const; - qint64 duration() const; - -private Q_SLOTS: - void handleMediaSourceReady(); - void handleMediaSourceError(long hr); - void handleSampleAdded(); - void handleSourceFinished(); - -private: - void updateResamplerOutputType(); - void activatePipeline(); - void onSourceCleared(); - - MFDecoderSourceReader *m_decoderSourceReader; - SourceResolver *m_sourceResolver; - IMFTransform *m_resampler; - QAudioDecoder::State m_state; - QString m_sourceFilename; - QIODevice *m_device; - QAudioFormat m_audioFormat; - DWORD m_mfInputStreamID; - DWORD m_mfOutputStreamID; - bool m_bufferReady; - QAudioBuffer m_cachedAudioBuffer; - qint64 m_duration; - qint64 m_position; - bool m_loadingSource; - IMFMediaType *m_mfOutputType; - IMFSample *m_convertSample; - QAudioFormat m_sourceOutputFormat; - bool m_sourceReady; - bool m_resamplerDirty; -}; - -#endif//MFAUDIODECODERCONTROL_H diff --git a/src/plugins/wmf/decoder/mfdecoderservice.cpp b/src/plugins/wmf/decoder/mfdecoderservice.cpp deleted file mode 100644 index eb2069a23..000000000 --- a/src/plugins/wmf/decoder/mfdecoderservice.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfdecoderservice.h" -#include "mfaudiodecodercontrol.h" - -MFAudioDecoderService::MFAudioDecoderService(QObject *parent) - : QMediaService(parent) -{ -} - -MFAudioDecoderService::~MFAudioDecoderService() -{ -} - -QObject *MFAudioDecoderService::requestControl(const char *name) -{ - if (qstrcmp(name, QAudioDecoderControl_iid) == 0) { - return new MFAudioDecoderControl(this); - } - return 0; -} - -void MFAudioDecoderService::releaseControl(QObject *control) -{ - if (control && control->inherits("MFAudioDecoderControl")) { - delete control; - } -} diff --git a/src/plugins/wmf/decoder/mfdecoderservice.h b/src/plugins/wmf/decoder/mfdecoderservice.h deleted file mode 100644 index 3749bc8df..000000000 --- a/src/plugins/wmf/decoder/mfdecoderservice.h +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFDECODERSERVICE_H -#define MFDECODERSERVICE_H - -#include "qmediaservice.h" - -class MFAudioDecoderService : public QMediaService -{ - Q_OBJECT -public: - MFAudioDecoderService(QObject *parent = 0); - ~MFAudioDecoderService(); - - QObject *requestControl(const char *name); - void releaseControl(QObject *control); -}; - -#endif//MFDECODERSERVICE_H diff --git a/src/plugins/wmf/decoder/mfdecodersourcereader.cpp b/src/plugins/wmf/decoder/mfdecodersourcereader.cpp deleted file mode 100644 index e907cfaf0..000000000 --- a/src/plugins/wmf/decoder/mfdecodersourcereader.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfdecodersourcereader.h" - -MFDecoderSourceReader::MFDecoderSourceReader(QObject *parent) - : m_cRef(1) - , m_sourceReader(0) - , m_source(0) -{ - Q_UNUSED(parent); -} - -void MFDecoderSourceReader::shutdown() -{ - if (m_source) { - m_source->Release(); - m_source = NULL; - } - if (m_sourceReader) { - m_sourceReader->Release(); - m_sourceReader = NULL; - } -} - -IMFMediaSource* MFDecoderSourceReader::mediaSource() -{ - return m_source; -} - -IMFMediaType* MFDecoderSourceReader::setSource(IMFMediaSource *source, const QAudioFormat &audioFormat) -{ - IMFMediaType *mediaType = NULL; - if (m_source == source) - return mediaType; - if (m_source) { - m_source->Release(); - m_source = NULL; - } - if (m_sourceReader) { - m_sourceReader->Release(); - m_sourceReader = NULL; - } - if (!source) - return mediaType; - IMFAttributes *attr = NULL; - MFCreateAttributes(&attr, 1); - if (SUCCEEDED(attr->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, this))) { - if (SUCCEEDED(MFCreateSourceReaderFromMediaSource(source, attr, &m_sourceReader))) { - m_source = source; - m_source->AddRef(); - m_sourceReader->SetStreamSelection(DWORD(MF_SOURCE_READER_ALL_STREAMS), FALSE); - m_sourceReader->SetStreamSelection(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), TRUE); - IMFMediaType *pPartialType = NULL; - MFCreateMediaType(&pPartialType); - pPartialType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio); - - if (audioFormat.sampleType() == QAudioFormat::Float) { - pPartialType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_Float); - } else { - pPartialType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM); - } - - m_sourceReader->SetCurrentMediaType(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), NULL, pPartialType); - pPartialType->Release(); - m_sourceReader->GetCurrentMediaType(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), &mediaType); - // Ensure the stream is selected. - m_sourceReader->SetStreamSelection(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), TRUE); - } - attr->Release(); - } - return mediaType; -} - -void MFDecoderSourceReader::reset() -{ - if (!m_sourceReader) - return; - PROPVARIANT vPos; - PropVariantInit(&vPos); - vPos.vt = VT_I8; - vPos.uhVal.QuadPart = 0; - m_sourceReader->SetCurrentPosition(GUID_NULL, vPos); -} - -void MFDecoderSourceReader::readNextSample() -{ - if (!m_sourceReader) - return; - m_sourceReader->ReadSample(MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, NULL, NULL, NULL, NULL); -} - -QList<IMFSample*> MFDecoderSourceReader::takeSamples() //internal samples will be cleared after this -{ - QList<IMFSample*> samples; - m_samplesMutex.lock(); - samples = m_cachedSamples; - m_cachedSamples.clear(); - m_samplesMutex.unlock(); - return samples; -} - -//from IUnknown -STDMETHODIMP MFDecoderSourceReader::QueryInterface(REFIID riid, LPVOID *ppvObject) -{ - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFSourceReaderCallback) { - *ppvObject = static_cast<IMFSourceReaderCallback*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -STDMETHODIMP_(ULONG) MFDecoderSourceReader::AddRef(void) -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) MFDecoderSourceReader::Release(void) -{ - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) { - this->deleteLater(); - } - return cRef; -} - -//from IMFSourceReaderCallback -STDMETHODIMP MFDecoderSourceReader::OnReadSample(HRESULT hrStatus, DWORD dwStreamIndex, - DWORD dwStreamFlags, LONGLONG llTimestamp, IMFSample *pSample) -{ - Q_UNUSED(hrStatus); - Q_UNUSED(dwStreamIndex); - Q_UNUSED(llTimestamp); - if (pSample) { - pSample->AddRef(); - m_samplesMutex.lock(); - m_cachedSamples.push_back(pSample); - m_samplesMutex.unlock(); - emit sampleAdded(); - } else if ((dwStreamFlags & MF_SOURCE_READERF_ENDOFSTREAM) == MF_SOURCE_READERF_ENDOFSTREAM) { - emit finished(); - } - return S_OK; -} - -STDMETHODIMP MFDecoderSourceReader::OnFlush(DWORD) -{ - return S_OK; -} - -STDMETHODIMP MFDecoderSourceReader::OnEvent(DWORD, IMFMediaEvent*) -{ - return S_OK; -} diff --git a/src/plugins/wmf/decoder/mfdecodersourcereader.h b/src/plugins/wmf/decoder/mfdecodersourcereader.h deleted file mode 100644 index 21c6b5eb3..000000000 --- a/src/plugins/wmf/decoder/mfdecodersourcereader.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFDECODERSOURCEREADER_H -#define MFDECODERSOURCEREADER_H -#include <mfapi.h> -#include <mfidl.h> -#include <Mfreadwrite.h> - -#include <QtCore/qobject.h> -#include <QtCore/qmutex.h> -#include "qaudioformat.h" - -QT_USE_NAMESPACE - -class MFDecoderSourceReader : public QObject, public IMFSourceReaderCallback -{ - Q_OBJECT -public: - MFDecoderSourceReader(QObject *parent = 0); - void shutdown(); - - IMFMediaSource* mediaSource(); - IMFMediaType* setSource(IMFMediaSource *source, const QAudioFormat &audioFormat); - - void reset(); - void readNextSample(); - QList<IMFSample*> takeSamples(); //internal samples will be cleared after this - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); - STDMETHODIMP_(ULONG) AddRef(void); - STDMETHODIMP_(ULONG) Release(void); - - //from IMFSourceReaderCallback - STDMETHODIMP OnReadSample(HRESULT hrStatus, DWORD dwStreamIndex, - DWORD dwStreamFlags, LONGLONG llTimestamp, IMFSample *pSample); - STDMETHODIMP OnFlush(DWORD dwStreamIndex); - STDMETHODIMP OnEvent(DWORD dwStreamIndex, IMFMediaEvent *pEvent); - -Q_SIGNALS: - void sampleAdded(); - void finished(); - -private: - long m_cRef; - QList<IMFSample*> m_cachedSamples; - QMutex m_samplesMutex; - - IMFSourceReader *m_sourceReader; - IMFMediaSource *m_source; -}; -#endif//MFDECODERSOURCEREADER_H diff --git a/src/plugins/wmf/mfstream.cpp b/src/plugins/wmf/mfstream.cpp deleted file mode 100644 index a98b5a704..000000000 --- a/src/plugins/wmf/mfstream.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfstream.h" -#include <QtCore/qcoreapplication.h> - -//MFStream is added for supporting QIODevice type of media source. -//It is used to delegate invocations from media foundation(through IMFByteStream) to QIODevice. - -MFStream::MFStream(QIODevice *stream, bool ownStream) - : m_cRef(1) - , m_stream(stream) - , m_ownStream(ownStream) - , m_currentReadResult(0) -{ - //Move to the thread of the stream object - //to make sure invocations on stream - //are happened in the same thread of stream object - this->moveToThread(stream->thread()); - connect(stream, SIGNAL(readyRead()), this, SLOT(handleReadyRead())); -} - -MFStream::~MFStream() -{ - if (m_currentReadResult) - m_currentReadResult->Release(); - if (m_ownStream) - m_stream->deleteLater(); -} - -//from IUnknown -STDMETHODIMP MFStream::QueryInterface(REFIID riid, LPVOID *ppvObject) -{ - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFByteStream) { - *ppvObject = static_cast<IMFByteStream*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -STDMETHODIMP_(ULONG) MFStream::AddRef(void) -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) MFStream::Release(void) -{ - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) { - this->deleteLater(); - } - return cRef; -} - - -//from IMFByteStream -STDMETHODIMP MFStream::GetCapabilities(DWORD *pdwCapabilities) -{ - if (!pdwCapabilities) - return E_INVALIDARG; - *pdwCapabilities = MFBYTESTREAM_IS_READABLE; - if (!m_stream->isSequential()) - *pdwCapabilities |= MFBYTESTREAM_IS_SEEKABLE; - return S_OK; -} - -STDMETHODIMP MFStream::GetLength(QWORD *pqwLength) -{ - if (!pqwLength) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - *pqwLength = QWORD(m_stream->size()); - return S_OK; -} - -STDMETHODIMP MFStream::SetLength(QWORD) -{ - return E_NOTIMPL; -} - -STDMETHODIMP MFStream::GetCurrentPosition(QWORD *pqwPosition) -{ - if (!pqwPosition) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - *pqwPosition = m_stream->pos(); - return S_OK; -} - -STDMETHODIMP MFStream::SetCurrentPosition(QWORD qwPosition) -{ - QMutexLocker locker(&m_mutex); - //SetCurrentPosition may happend during the BeginRead/EndRead pair, - //refusing to execute SetCurrentPosition during that time seems to be - //the simplest workable solution - if (m_currentReadResult) - return S_FALSE; - - bool seekOK = m_stream->seek(qint64(qwPosition)); - if (seekOK) - return S_OK; - else - return S_FALSE; -} - -STDMETHODIMP MFStream::IsEndOfStream(BOOL *pfEndOfStream) -{ - if (!pfEndOfStream) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - *pfEndOfStream = m_stream->atEnd() ? TRUE : FALSE; - return S_OK; -} - -STDMETHODIMP MFStream::Read(BYTE *pb, ULONG cb, ULONG *pcbRead) -{ - QMutexLocker locker(&m_mutex); - qint64 read = m_stream->read((char*)(pb), qint64(cb)); - if (pcbRead) - *pcbRead = ULONG(read); - return S_OK; -} - -STDMETHODIMP MFStream::BeginRead(BYTE *pb, ULONG cb, IMFAsyncCallback *pCallback, - IUnknown *punkState) -{ - if (!pCallback || !pb) - return E_INVALIDARG; - - Q_ASSERT(m_currentReadResult == NULL); - - AsyncReadState *state = new (std::nothrow) AsyncReadState(pb, cb); - if (state == NULL) - return E_OUTOFMEMORY; - - HRESULT hr = MFCreateAsyncResult(state, pCallback, punkState, &m_currentReadResult); - state->Release(); - if (FAILED(hr)) - return hr; - - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); - return hr; -} - -STDMETHODIMP MFStream::EndRead(IMFAsyncResult* pResult, ULONG *pcbRead) -{ - if (!pcbRead) - return E_INVALIDARG; - IUnknown *pUnk; - pResult->GetObject(&pUnk); - AsyncReadState *state = static_cast<AsyncReadState*>(pUnk); - *pcbRead = state->bytesRead(); - pUnk->Release(); - - m_currentReadResult->Release(); - m_currentReadResult = NULL; - - return S_OK; -} - -STDMETHODIMP MFStream::Write(const BYTE *, ULONG, ULONG *) -{ - return E_NOTIMPL; -} - -STDMETHODIMP MFStream::BeginWrite(const BYTE *, ULONG , - IMFAsyncCallback *, - IUnknown *) -{ - return E_NOTIMPL; -} - -STDMETHODIMP MFStream::EndWrite(IMFAsyncResult *, - ULONG *) -{ - return E_NOTIMPL; -} - -STDMETHODIMP MFStream::Seek( - MFBYTESTREAM_SEEK_ORIGIN SeekOrigin, - LONGLONG llSeekOffset, - DWORD, - QWORD *pqwCurrentPosition) -{ - QMutexLocker locker(&m_mutex); - if (m_currentReadResult) - return S_FALSE; - - qint64 pos = qint64(llSeekOffset); - switch (SeekOrigin) { - case msoBegin: - break; - case msoCurrent: - pos += m_stream->pos(); - break; - } - bool seekOK = m_stream->seek(pos); - if (pqwCurrentPosition) - *pqwCurrentPosition = pos; - if (seekOK) - return S_OK; - else - return S_FALSE; -} - -STDMETHODIMP MFStream::Flush() -{ - return E_NOTIMPL; -} - -STDMETHODIMP MFStream::Close() -{ - QMutexLocker locker(&m_mutex); - if (m_ownStream) - m_stream->close(); - return S_OK; -} - -void MFStream::doRead() -{ - bool readDone = true; - IUnknown *pUnk = NULL; - HRESULT hr = m_currentReadResult->GetObject(&pUnk); - if (SUCCEEDED(hr)) { - //do actual read - AsyncReadState *state = static_cast<AsyncReadState*>(pUnk); - ULONG cbRead; - Read(state->pb(), state->cb() - state->bytesRead(), &cbRead); - pUnk->Release(); - - state->setBytesRead(cbRead + state->bytesRead()); - if (state->cb() > state->bytesRead() && !m_stream->atEnd()) { - readDone = false; - } - } - - if (readDone) { - //now inform the original caller - m_currentReadResult->SetStatus(hr); - MFInvokeCallback(m_currentReadResult); - } -} - - -void MFStream::handleReadyRead() -{ - doRead(); -} - -void MFStream::customEvent(QEvent *event) -{ - if (event->type() != QEvent::User) { - QObject::customEvent(event); - return; - } - doRead(); -} - -//AsyncReadState is a helper class used in BeginRead for asynchronous operation -//to record some BeginRead parameters, so these parameters could be -//used later when actually executing the read operation in another thread. -MFStream::AsyncReadState::AsyncReadState(BYTE *pb, ULONG cb) - : m_cRef(1) - , m_pb(pb) - , m_cb(cb) - , m_cbRead(0) -{ -} - -//from IUnknown -STDMETHODIMP MFStream::AsyncReadState::QueryInterface(REFIID riid, LPVOID *ppvObject) -{ - if (!ppvObject) - return E_POINTER; - - if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -STDMETHODIMP_(ULONG) MFStream::AsyncReadState::AddRef(void) -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) MFStream::AsyncReadState::Release(void) -{ - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - // For thread safety, return a temporary variable. - return cRef; -} - -BYTE* MFStream::AsyncReadState::pb() const -{ - return m_pb; -} - -ULONG MFStream::AsyncReadState::cb() const -{ - return m_cb; -} - -ULONG MFStream::AsyncReadState::bytesRead() const -{ - return m_cbRead; -} - -void MFStream::AsyncReadState::setBytesRead(ULONG cbRead) -{ - m_cbRead = cbRead; -} diff --git a/src/plugins/wmf/mfstream.h b/src/plugins/wmf/mfstream.h deleted file mode 100644 index f98ab42a9..000000000 --- a/src/plugins/wmf/mfstream.h +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFSTREAM_H -#define MFSTREAM_H - -#include <mfapi.h> -#include <mfidl.h> -#include <QtCore/qmutex.h> -#include <QtCore/qiodevice.h> -#include <QtCore/qcoreevent.h> - -QT_USE_NAMESPACE - -class MFStream : public QObject, public IMFByteStream -{ - Q_OBJECT -public: - MFStream(QIODevice *stream, bool ownStream); - - ~MFStream(); - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); - - STDMETHODIMP_(ULONG) AddRef(void); - - STDMETHODIMP_(ULONG) Release(void); - - - //from IMFByteStream - STDMETHODIMP GetCapabilities(DWORD *pdwCapabilities); - - STDMETHODIMP GetLength(QWORD *pqwLength); - - STDMETHODIMP SetLength(QWORD); - - STDMETHODIMP GetCurrentPosition(QWORD *pqwPosition); - - STDMETHODIMP SetCurrentPosition(QWORD qwPosition); - - STDMETHODIMP IsEndOfStream(BOOL *pfEndOfStream); - - STDMETHODIMP Read(BYTE *pb, ULONG cb, ULONG *pcbRead); - - STDMETHODIMP BeginRead(BYTE *pb, ULONG cb, IMFAsyncCallback *pCallback, - IUnknown *punkState); - - STDMETHODIMP EndRead(IMFAsyncResult* pResult, ULONG *pcbRead); - - STDMETHODIMP Write(const BYTE *, ULONG, ULONG *); - - STDMETHODIMP BeginWrite(const BYTE *, ULONG , - IMFAsyncCallback *, - IUnknown *); - - STDMETHODIMP EndWrite(IMFAsyncResult *, - ULONG *); - - STDMETHODIMP Seek( - MFBYTESTREAM_SEEK_ORIGIN SeekOrigin, - LONGLONG llSeekOffset, - DWORD, - QWORD *pqwCurrentPosition); - - STDMETHODIMP Flush(); - - STDMETHODIMP Close(); - -private: - class AsyncReadState : public IUnknown - { - public: - AsyncReadState(BYTE *pb, ULONG cb); - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); - - STDMETHODIMP_(ULONG) AddRef(void); - - STDMETHODIMP_(ULONG) Release(void); - - BYTE* pb() const; - ULONG cb() const; - ULONG bytesRead() const; - - void setBytesRead(ULONG cbRead); - - private: - long m_cRef; - BYTE *m_pb; - ULONG m_cb; - ULONG m_cbRead; - }; - - long m_cRef; - QIODevice *m_stream; - bool m_ownStream; - DWORD m_workQueueId; - QMutex m_mutex; - - void doRead(); - -private Q_SLOTS: - void handleReadyRead(); - -protected: - void customEvent(QEvent *event); - IMFAsyncResult *m_currentReadResult; -}; - -#endif diff --git a/src/plugins/wmf/player/mfactivate.cpp b/src/plugins/wmf/player/mfactivate.cpp deleted file mode 100644 index e06906584..000000000 --- a/src/plugins/wmf/player/mfactivate.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfactivate.h" - -#include <mfapi.h> - -MFAbstractActivate::MFAbstractActivate() - : m_attributes(0) - , m_cRef(1) -{ - MFCreateAttributes(&m_attributes, 0); -} - -MFAbstractActivate::~MFAbstractActivate() -{ - if (m_attributes) - m_attributes->Release(); -} - - -HRESULT MFAbstractActivate::QueryInterface(REFIID riid, LPVOID *ppvObject) -{ - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFActivate) { - *ppvObject = static_cast<IMFActivate*>(this); - } else if (riid == IID_IMFAttributes) { - *ppvObject = static_cast<IMFAttributes*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(static_cast<IMFActivate*>(this)); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -ULONG MFAbstractActivate::AddRef(void) -{ - return InterlockedIncrement(&m_cRef); -} - -ULONG MFAbstractActivate::Release(void) -{ - ULONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - return cRef; -} diff --git a/src/plugins/wmf/player/mfactivate.h b/src/plugins/wmf/player/mfactivate.h deleted file mode 100644 index 3243296e8..000000000 --- a/src/plugins/wmf/player/mfactivate.h +++ /dev/null @@ -1,212 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFACTIVATE_H -#define MFACTIVATE_H - -#include <mfidl.h> - -class MFAbstractActivate : public IMFActivate -{ -public: - explicit MFAbstractActivate(); - virtual ~MFAbstractActivate(); - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); - STDMETHODIMP_(ULONG) AddRef(void); - STDMETHODIMP_(ULONG) Release(void); - - //from IMFAttributes - STDMETHODIMP GetItem(REFGUID guidKey, PROPVARIANT *pValue) - { - return m_attributes->GetItem(guidKey, pValue); - } - - STDMETHODIMP GetItemType(REFGUID guidKey, MF_ATTRIBUTE_TYPE *pType) - { - return m_attributes->GetItemType(guidKey, pType); - } - - STDMETHODIMP CompareItem(REFGUID guidKey, REFPROPVARIANT Value, BOOL *pbResult) - { - return m_attributes->CompareItem(guidKey, Value, pbResult); - } - - STDMETHODIMP Compare(IMFAttributes *pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, BOOL *pbResult) - { - return m_attributes->Compare(pTheirs, MatchType, pbResult); - } - - STDMETHODIMP GetUINT32(REFGUID guidKey, UINT32 *punValue) - { - return m_attributes->GetUINT32(guidKey, punValue); - } - - STDMETHODIMP GetUINT64(REFGUID guidKey, UINT64 *punValue) - { - return m_attributes->GetUINT64(guidKey, punValue); - } - - STDMETHODIMP GetDouble(REFGUID guidKey, double *pfValue) - { - return m_attributes->GetDouble(guidKey, pfValue); - } - - STDMETHODIMP GetGUID(REFGUID guidKey, GUID *pguidValue) - { - return m_attributes->GetGUID(guidKey, pguidValue); - } - - STDMETHODIMP GetStringLength(REFGUID guidKey, UINT32 *pcchLength) - { - return m_attributes->GetStringLength(guidKey, pcchLength); - } - - STDMETHODIMP GetString(REFGUID guidKey, LPWSTR pwszValue, UINT32 cchBufSize, UINT32 *pcchLength) - { - return m_attributes->GetString(guidKey, pwszValue, cchBufSize, pcchLength); - } - - STDMETHODIMP GetAllocatedString(REFGUID guidKey, LPWSTR *ppwszValue, UINT32 *pcchLength) - { - return m_attributes->GetAllocatedString(guidKey, ppwszValue, pcchLength); - } - - STDMETHODIMP GetBlobSize(REFGUID guidKey, UINT32 *pcbBlobSize) - { - return m_attributes->GetBlobSize(guidKey, pcbBlobSize); - } - - STDMETHODIMP GetBlob(REFGUID guidKey, UINT8 *pBuf, UINT32 cbBufSize, UINT32 *pcbBlobSize) - { - return m_attributes->GetBlob(guidKey, pBuf, cbBufSize, pcbBlobSize); - } - - STDMETHODIMP GetAllocatedBlob(REFGUID guidKey, UINT8 **ppBuf, UINT32 *pcbSize) - { - return m_attributes->GetAllocatedBlob(guidKey, ppBuf, pcbSize); - } - - STDMETHODIMP GetUnknown(REFGUID guidKey, REFIID riid, LPVOID *ppv) - { - return m_attributes->GetUnknown(guidKey, riid, ppv); - } - - STDMETHODIMP SetItem(REFGUID guidKey, REFPROPVARIANT Value) - { - return m_attributes->SetItem(guidKey, Value); - } - - STDMETHODIMP DeleteItem(REFGUID guidKey) - { - return m_attributes->DeleteItem(guidKey); - } - - STDMETHODIMP DeleteAllItems() - { - return m_attributes->DeleteAllItems(); - } - - STDMETHODIMP SetUINT32(REFGUID guidKey, UINT32 unValue) - { - return m_attributes->SetUINT32(guidKey, unValue); - } - - STDMETHODIMP SetUINT64(REFGUID guidKey, UINT64 unValue) - { - return m_attributes->SetUINT64(guidKey, unValue); - } - - STDMETHODIMP SetDouble(REFGUID guidKey, double fValue) - { - return m_attributes->SetDouble(guidKey, fValue); - } - - STDMETHODIMP SetGUID(REFGUID guidKey, REFGUID guidValue) - { - return m_attributes->SetGUID(guidKey, guidValue); - } - - STDMETHODIMP SetString(REFGUID guidKey, LPCWSTR wszValue) - { - return m_attributes->SetString(guidKey, wszValue); - } - - STDMETHODIMP SetBlob(REFGUID guidKey, const UINT8 *pBuf, UINT32 cbBufSize) - { - return m_attributes->SetBlob(guidKey, pBuf, cbBufSize); - } - - STDMETHODIMP SetUnknown(REFGUID guidKey, IUnknown *pUnknown) - { - return m_attributes->SetUnknown(guidKey, pUnknown); - } - - STDMETHODIMP LockStore() - { - return m_attributes->LockStore(); - } - - STDMETHODIMP UnlockStore() - { - return m_attributes->UnlockStore(); - } - - STDMETHODIMP GetCount(UINT32 *pcItems) - { - return m_attributes->GetCount(pcItems); - } - - STDMETHODIMP GetItemByIndex(UINT32 unIndex, GUID *pguidKey, PROPVARIANT *pValue) - { - return m_attributes->GetItemByIndex(unIndex, pguidKey, pValue); - } - - STDMETHODIMP CopyAllItems(IMFAttributes *pDest) - { - return m_attributes->CopyAllItems(pDest); - } - -private: - IMFAttributes *m_attributes; - ULONG m_cRef; -}; - -#endif // MFACTIVATE_H diff --git a/src/plugins/wmf/player/mfaudioendpointcontrol.cpp b/src/plugins/wmf/player/mfaudioendpointcontrol.cpp deleted file mode 100644 index 3b86c52b7..000000000 --- a/src/plugins/wmf/player/mfaudioendpointcontrol.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "QtCore/qdebug.h" -#include "mfaudioendpointcontrol.h" - -#include <mmdeviceapi.h> - -MFAudioEndpointControl::MFAudioEndpointControl(QObject *parent) - : QAudioOutputSelectorControl(parent) - , m_currentActivate(0) -{ -} - -MFAudioEndpointControl::~MFAudioEndpointControl() -{ - clear(); -} - -void MFAudioEndpointControl::clear() -{ - m_activeEndpoint.clear(); - - for (auto it = m_devices.cbegin(), end = m_devices.cend(); it != end; ++it) - CoTaskMemFree(it.value()); - - m_devices.clear(); - - if (m_currentActivate) - m_currentActivate->Release(); - m_currentActivate = NULL; -} - -QList<QString> MFAudioEndpointControl::availableOutputs() const -{ - return m_devices.keys(); -} - -QString MFAudioEndpointControl::outputDescription(const QString &name) const -{ - return name.section(QLatin1Char('\\'), -1); -} - -QString MFAudioEndpointControl::defaultOutput() const -{ - return m_defaultEndpoint; -} - -QString MFAudioEndpointControl::activeOutput() const -{ - return m_activeEndpoint; -} - -void MFAudioEndpointControl::setActiveOutput(const QString &name) -{ - if (m_activeEndpoint == name) - return; - QMap<QString, LPWSTR>::iterator it = m_devices.find(name); - if (it == m_devices.end()) - return; - - LPWSTR wstrID = *it; - IMFActivate *activate = NULL; - HRESULT hr = MFCreateAudioRendererActivate(&activate); - if (FAILED(hr)) { - qWarning() << "Failed to create audio renderer activate"; - return; - } - - if (wstrID) { - hr = activate->SetString(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, wstrID); - } else { - //This is the default one that has been inserted in updateEndpoints(), - //so give the activate a hint that we want to use the device for multimedia playback - //then the media foundation will choose an appropriate one. - - //from MSDN: - //The ERole enumeration defines constants that indicate the role that the system has assigned to an audio endpoint device. - //eMultimedia: Music, movies, narration, and live music recording. - hr = activate->SetUINT32(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, eMultimedia); - } - - if (FAILED(hr)) { - qWarning() << "Failed to set attribute for audio device" << name; - return; - } - - if (m_currentActivate) - m_currentActivate->Release(); - m_currentActivate = activate; - m_activeEndpoint = name; -} - -IMFActivate* MFAudioEndpointControl::createActivate() -{ - clear(); - - updateEndpoints(); - - // Check if an endpoint is available ("Default" is always inserted) - if (m_devices.count() <= 1) - return NULL; - - setActiveOutput(m_defaultEndpoint); - - return m_currentActivate; -} - -void MFAudioEndpointControl::updateEndpoints() -{ - m_defaultEndpoint = QString::fromLatin1("Default"); - m_devices.insert(m_defaultEndpoint, NULL); - - IMMDeviceEnumerator *pEnum = NULL; - HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), - NULL, CLSCTX_ALL, - __uuidof(IMMDeviceEnumerator), - (void**)&pEnum); - if (SUCCEEDED(hr)) { - IMMDeviceCollection *pDevices = NULL; - hr = pEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pDevices); - if (SUCCEEDED(hr)) { - UINT count; - hr = pDevices->GetCount(&count); - if (SUCCEEDED(hr)) { - for (UINT i = 0; i < count; ++i) { - IMMDevice *pDevice = NULL; - hr = pDevices->Item(i, &pDevice); - if (SUCCEEDED(hr)) { - LPWSTR wstrID = NULL; - hr = pDevice->GetId(&wstrID); - if (SUCCEEDED(hr)) { - QString deviceId = QString::fromWCharArray(wstrID); - m_devices.insert(deviceId, wstrID); - } - pDevice->Release(); - } - } - } - pDevices->Release(); - } - pEnum->Release(); - } -} diff --git a/src/plugins/wmf/player/mfaudioendpointcontrol.h b/src/plugins/wmf/player/mfaudioendpointcontrol.h deleted file mode 100644 index a439c31a5..000000000 --- a/src/plugins/wmf/player/mfaudioendpointcontrol.h +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFAUDIOENDPOINTCONTROL_H -#define MFAUDIOENDPOINTCONTROL_H - -#include <mfapi.h> -#include <mfidl.h> - -#include "qaudiooutputselectorcontrol.h" - -class MFPlayerService; - -QT_USE_NAMESPACE - -class MFAudioEndpointControl : public QAudioOutputSelectorControl -{ - Q_OBJECT -public: - MFAudioEndpointControl(QObject *parent = 0); - ~MFAudioEndpointControl(); - - QList<QString> availableOutputs() const; - - QString outputDescription(const QString &name) const; - - QString defaultOutput() const; - QString activeOutput() const; - - void setActiveOutput(const QString& name); - - IMFActivate* createActivate(); - -private: - void clear(); - void updateEndpoints(); - - QString m_defaultEndpoint; - QString m_activeEndpoint; - QMap<QString, LPWSTR> m_devices; - IMFActivate *m_currentActivate; - -}; - -#endif - diff --git a/src/plugins/wmf/player/mfaudioprobecontrol.cpp b/src/plugins/wmf/player/mfaudioprobecontrol.cpp deleted file mode 100644 index c703922c8..000000000 --- a/src/plugins/wmf/player/mfaudioprobecontrol.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfaudioprobecontrol.h" - -MFAudioProbeControl::MFAudioProbeControl(QObject *parent): - QMediaAudioProbeControl(parent) -{ -} - -MFAudioProbeControl::~MFAudioProbeControl() -{ -} - -void MFAudioProbeControl::bufferProbed(const char *data, quint32 size, const QAudioFormat& format, qint64 startTime) -{ - if (!format.isValid()) - return; - - QAudioBuffer audioBuffer = QAudioBuffer(QByteArray(data, size), format, startTime); - - { - QMutexLocker locker(&m_bufferMutex); - m_pendingBuffer = audioBuffer; - QMetaObject::invokeMethod(this, "bufferProbed", Qt::QueuedConnection); - } -} - -void MFAudioProbeControl::bufferProbed() -{ - QAudioBuffer audioBuffer; - { - QMutexLocker locker(&m_bufferMutex); - if (!m_pendingBuffer.isValid()) - return; - audioBuffer = m_pendingBuffer; - } - emit audioBufferProbed(audioBuffer); -} diff --git a/src/plugins/wmf/player/mfaudioprobecontrol.h b/src/plugins/wmf/player/mfaudioprobecontrol.h deleted file mode 100644 index c8a06148f..000000000 --- a/src/plugins/wmf/player/mfaudioprobecontrol.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFAUDIOPROBECONTROL_H -#define MFAUDIOPROBECONTROL_H - -#include <qmediaaudioprobecontrol.h> -#include <QtCore/qmutex.h> -#include <qaudiobuffer.h> - -QT_USE_NAMESPACE - -class MFAudioProbeControl : public QMediaAudioProbeControl -{ - Q_OBJECT -public: - explicit MFAudioProbeControl(QObject *parent); - virtual ~MFAudioProbeControl(); - - void bufferProbed(const char *data, quint32 size, const QAudioFormat& format, qint64 startTime); - -private slots: - void bufferProbed(); - -private: - QAudioBuffer m_pendingBuffer; - QMutex m_bufferMutex; -}; - -#endif diff --git a/src/plugins/wmf/player/mfevrvideowindowcontrol.cpp b/src/plugins/wmf/player/mfevrvideowindowcontrol.cpp deleted file mode 100644 index 4b3e0f303..000000000 --- a/src/plugins/wmf/player/mfevrvideowindowcontrol.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfevrvideowindowcontrol.h" - -#include <qdebug.h> - -MFEvrVideoWindowControl::MFEvrVideoWindowControl(QObject *parent) - : EvrVideoWindowControl(parent) - , m_currentActivate(NULL) - , m_evrSink(NULL) -{ -} - -MFEvrVideoWindowControl::~MFEvrVideoWindowControl() -{ - clear(); -} - -void MFEvrVideoWindowControl::clear() -{ - setEvr(NULL); - - if (m_evrSink) - m_evrSink->Release(); - if (m_currentActivate) { - m_currentActivate->ShutdownObject(); - m_currentActivate->Release(); - } - m_evrSink = NULL; - m_currentActivate = NULL; -} - -IMFActivate* MFEvrVideoWindowControl::createActivate() -{ - clear(); - - if (FAILED(MFCreateVideoRendererActivate(0, &m_currentActivate))) { - qWarning() << "Failed to create evr video renderer activate!"; - return NULL; - } - if (FAILED(m_currentActivate->ActivateObject(IID_IMFMediaSink, (LPVOID*)(&m_evrSink)))) { - qWarning() << "Failed to activate evr media sink!"; - return NULL; - } - if (!setEvr(m_evrSink)) - return NULL; - - return m_currentActivate; -} - -void MFEvrVideoWindowControl::releaseActivate() -{ - clear(); -} diff --git a/src/plugins/wmf/player/mfevrvideowindowcontrol.h b/src/plugins/wmf/player/mfevrvideowindowcontrol.h deleted file mode 100644 index 96634e6d8..000000000 --- a/src/plugins/wmf/player/mfevrvideowindowcontrol.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFEVRVIDEOWINDOWCONTROL_H -#define MFEVRVIDEOWINDOWCONTROL_H - -#include "evrvideowindowcontrol.h" - -QT_USE_NAMESPACE - -class MFEvrVideoWindowControl : public EvrVideoWindowControl -{ -public: - MFEvrVideoWindowControl(QObject *parent = 0); - ~MFEvrVideoWindowControl(); - - IMFActivate* createActivate(); - void releaseActivate(); - -private: - void clear(); - - IMFActivate *m_currentActivate; - IMFMediaSink *m_evrSink; -}; - -#endif // MFEVRVIDEOWINDOWCONTROL_H diff --git a/src/plugins/wmf/player/mfmetadatacontrol.cpp b/src/plugins/wmf/player/mfmetadatacontrol.cpp deleted file mode 100644 index 74063f7d1..000000000 --- a/src/plugins/wmf/player/mfmetadatacontrol.cpp +++ /dev/null @@ -1,431 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qmediametadata.h> -#include <qdatetime.h> -#include <qimage.h> - -#include "mfmetadatacontrol.h" -#include "mfplayerservice.h" -#include "Propkey.h" - -//#define DEBUG_MEDIAFOUNDATION - -static QString nameForGUID(GUID guid) -{ - // Audio formats - if (guid == MFAudioFormat_AAC) - return QStringLiteral("MPEG AAC Audio"); - else if (guid == MFAudioFormat_ADTS) - return QStringLiteral("MPEG ADTS AAC Audio"); - else if (guid == MFAudioFormat_Dolby_AC3_SPDIF) - return QStringLiteral("Dolby AC-3 SPDIF"); - else if (guid == MFAudioFormat_DRM) - return QStringLiteral("DRM"); - else if (guid == MFAudioFormat_DTS) - return QStringLiteral("Digital Theater Systems Audio (DTS)"); - else if (guid == MFAudioFormat_Float) - return QStringLiteral("IEEE Float Audio"); - else if (guid == MFAudioFormat_MP3) - return QStringLiteral("MPEG Audio Layer-3 (MP3)"); - else if (guid == MFAudioFormat_MPEG) - return QStringLiteral("MPEG-1 Audio"); - else if (guid == MFAudioFormat_MSP1) - return QStringLiteral("Windows Media Audio Voice"); - else if (guid == MFAudioFormat_PCM) - return QStringLiteral("Uncompressed PCM Audio"); - else if (guid == MFAudioFormat_WMASPDIF) - return QStringLiteral("Windows Media Audio 9 SPDIF"); - else if (guid == MFAudioFormat_WMAudioV8) - return QStringLiteral("Windows Media Audio 8 (WMA2)"); - else if (guid == MFAudioFormat_WMAudioV9) - return QStringLiteral("Windows Media Audio 9 (WMA3"); - else if (guid == MFAudioFormat_WMAudio_Lossless) - return QStringLiteral("Windows Media Audio 9 Lossless"); - - // Video formats - if (guid == MFVideoFormat_DV25) - return QStringLiteral("DVCPRO 25 (DV25)"); - else if (guid == MFVideoFormat_DV50) - return QStringLiteral("DVCPRO 50 (DV50)"); - else if (guid == MFVideoFormat_DVC) - return QStringLiteral("DVC/DV Video"); - else if (guid == MFVideoFormat_DVH1) - return QStringLiteral("DVCPRO 100 (DVH1)"); - else if (guid == MFVideoFormat_DVHD) - return QStringLiteral("HD-DVCR (DVHD)"); - else if (guid == MFVideoFormat_DVSD) - return QStringLiteral("SDL-DVCR (DVSD)"); - else if (guid == MFVideoFormat_DVSL) - return QStringLiteral("SD-DVCR (DVSL)"); - else if (guid == MFVideoFormat_H264) - return QStringLiteral("H.264 Video"); - else if (guid == MFVideoFormat_M4S2) - return QStringLiteral("MPEG-4 part 2 Video (M4S2)"); - else if (guid == MFVideoFormat_MJPG) - return QStringLiteral("Motion JPEG (MJPG)"); - else if (guid == MFVideoFormat_MP43) - return QStringLiteral("Microsoft MPEG 4 version 3 (MP43)"); - else if (guid == MFVideoFormat_MP4S) - return QStringLiteral("ISO MPEG 4 version 1 (MP4S)"); - else if (guid == MFVideoFormat_MP4V) - return QStringLiteral("MPEG-4 part 2 Video (MP4V)"); - else if (guid == MFVideoFormat_MPEG2) - return QStringLiteral("MPEG-2 Video"); - else if (guid == MFVideoFormat_MPG1) - return QStringLiteral("MPEG-1 Video"); - else if (guid == MFVideoFormat_MSS1) - return QStringLiteral("Windows Media Screen 1 (MSS1)"); - else if (guid == MFVideoFormat_MSS2) - return QStringLiteral("Windows Media Video 9 Screen (MSS2)"); - else if (guid == MFVideoFormat_WMV1) - return QStringLiteral("Windows Media Video 7 (WMV1)"); - else if (guid == MFVideoFormat_WMV2) - return QStringLiteral("Windows Media Video 8 (WMV2)"); - else if (guid == MFVideoFormat_WMV3) - return QStringLiteral("Windows Media Video 9 (WMV3)"); - else if (guid == MFVideoFormat_WVC1) - return QStringLiteral("Windows Media Video VC1 (WVC1)"); - - else - return QStringLiteral("Unknown codec"); -} - -MFMetaDataControl::MFMetaDataControl(QObject *parent) - : QMetaDataReaderControl(parent) - , m_metaData(0) - , m_content(0) -{ -} - -MFMetaDataControl::~MFMetaDataControl() -{ - if (m_metaData) - m_metaData->Release(); - if (m_content) - m_content->Release(); -} - -bool MFMetaDataControl::isMetaDataAvailable() const -{ - return m_content || m_metaData; -} - -QVariant MFMetaDataControl::metaData(const QString &key) const -{ - QVariant value; - if (!isMetaDataAvailable()) - return value; - - int index = m_availableMetaDatas.indexOf(key); - if (index < 0) - return value; - - PROPVARIANT var; - PropVariantInit(&var); - HRESULT hr = S_FALSE; - if (m_content) - hr = m_content->GetValue(m_commonKeys[index], &var); - else if (m_metaData) - hr = m_metaData->GetProperty(reinterpret_cast<LPCWSTR>(m_commonNames[index].utf16()), &var); - - if (SUCCEEDED(hr)) { - value = convertValue(var); - - // some metadata needs to be reformatted - if (value.isValid() && m_content) { - if (key == QMediaMetaData::MediaType) { - QString v = value.toString(); - if (v == QLatin1String("{D1607DBC-E323-4BE2-86A1-48A42A28441E}")) - value = QStringLiteral("Music"); - else if (v == QLatin1String("{DB9830BD-3AB3-4FAB-8A37-1A995F7FF74B}")) - value = QStringLiteral("Video"); - else if (v == QLatin1String("{01CD0F29-DA4E-4157-897B-6275D50C4F11}")) - value = QStringLiteral("Audio"); - else if (v == QLatin1String("{FCF24A76-9A57-4036-990D-E35DD8B244E1}")) - value = QStringLiteral("Other"); - } else if (key == QMediaMetaData::Duration) { - // duration is provided in 100-nanosecond units, convert to milliseconds - value = (value.toLongLong() + 10000) / 10000; - } else if (key == QMediaMetaData::AudioCodec || key == QMediaMetaData::VideoCodec) { - GUID guid; - if (SUCCEEDED(CLSIDFromString((const WCHAR*)value.toString().utf16(), &guid))) - value = nameForGUID(guid); - } else if (key == QMediaMetaData::Resolution) { - QSize res; - res.setHeight(value.toUInt()); - if (m_content && SUCCEEDED(m_content->GetValue(PKEY_Video_FrameWidth, &var))) - res.setWidth(convertValue(var).toUInt()); - value = res; - } else if (key == QMediaMetaData::Orientation) { - uint orientation = 0; - if (m_content && SUCCEEDED(m_content->GetValue(PKEY_Video_Orientation, &var))) - orientation = convertValue(var).toUInt(); - value = orientation; - } else if (key == QMediaMetaData::PixelAspectRatio) { - QSize aspectRatio; - aspectRatio.setWidth(value.toUInt()); - if (m_content && SUCCEEDED(m_content->GetValue(PKEY_Video_VerticalAspectRatio, &var))) - aspectRatio.setHeight(convertValue(var).toUInt()); - value = aspectRatio; - } else if (key == QMediaMetaData::VideoFrameRate) { - value = value.toReal() / 1000.f; - } - } - } - - PropVariantClear(&var); - return value; -} - -QVariant MFMetaDataControl::convertValue(const PROPVARIANT& var) const -{ - QVariant value; - switch (var.vt) { - case VT_LPWSTR: - value = QString::fromUtf16(reinterpret_cast<const ushort*>(var.pwszVal)); - break; - case VT_UI4: - value = uint(var.ulVal); - break; - case VT_UI8: - value = qulonglong(var.uhVal.QuadPart); - break; - case VT_BOOL: - value = bool(var.boolVal); - break; - case VT_FILETIME: - SYSTEMTIME sysDate; - if (!FileTimeToSystemTime(&var.filetime, &sysDate)) - break; - value = QDate(sysDate.wYear, sysDate.wMonth, sysDate.wDay); - break; - case VT_STREAM: - { - STATSTG stat; - if (FAILED(var.pStream->Stat(&stat, STATFLAG_NONAME))) - break; - void *data = malloc(stat.cbSize.QuadPart); - ULONG read = 0; - if (FAILED(var.pStream->Read(data, stat.cbSize.QuadPart, &read))) { - free(data); - break; - } - value = QImage::fromData((const uchar*)data, read); - free(data); - } - break; - case VT_VECTOR | VT_LPWSTR: - QStringList vList; - for (ULONG i = 0; i < var.calpwstr.cElems; ++i) - vList.append(QString::fromUtf16(reinterpret_cast<const ushort*>(var.calpwstr.pElems[i]))); - value = vList; - break; - } - return value; -} - -QStringList MFMetaDataControl::availableMetaData() const -{ - return m_availableMetaDatas; -} - -void MFMetaDataControl::updateSource(IMFPresentationDescriptor* sourcePD, IMFMediaSource* mediaSource) -{ - if (m_metaData) { - m_metaData->Release(); - m_metaData = 0; - } - - if (m_content) { - m_content->Release(); - m_content = 0; - } - - m_availableMetaDatas.clear(); - m_commonKeys.clear(); - m_commonNames.clear(); - - if (SUCCEEDED(MFGetService(mediaSource, MF_PROPERTY_HANDLER_SERVICE, IID_PPV_ARGS(&m_content)))) { - DWORD cProps; - if (SUCCEEDED(m_content->GetCount(&cProps))) { - for (DWORD i = 0; i < cProps; i++) - { - PROPERTYKEY key; - if (FAILED(m_content->GetAt(i, &key))) - continue; - bool common = true; - if (key == PKEY_Author) { - m_availableMetaDatas.push_back(QMediaMetaData::Author); - } else if (key == PKEY_Title) { - m_availableMetaDatas.push_back(QMediaMetaData::Title); - } else if (key == PKEY_Media_SubTitle) { - m_availableMetaDatas.push_back(QMediaMetaData::SubTitle); - } else if (key == PKEY_ParentalRating) { - m_availableMetaDatas.push_back(QMediaMetaData::ParentalRating); - } else if (key == PKEY_Media_EncodingSettings) { - m_availableMetaDatas.push_back(QMediaMetaData::Description); - } else if (key == PKEY_Copyright) { - m_availableMetaDatas.push_back(QMediaMetaData::Copyright); - } else if (key == PKEY_Comment) { - m_availableMetaDatas.push_back(QMediaMetaData::Comment); - } else if (key == PKEY_Media_ProviderStyle) { - m_availableMetaDatas.push_back(QMediaMetaData::Genre); - } else if (key == PKEY_Media_Year) { - m_availableMetaDatas.push_back(QMediaMetaData::Year); - } else if (key == PKEY_Media_DateEncoded) { - m_availableMetaDatas.push_back(QMediaMetaData::Date); - } else if (key == PKEY_Rating) { - m_availableMetaDatas.push_back(QMediaMetaData::UserRating); - } else if (key == PKEY_Keywords) { - m_availableMetaDatas.push_back(QMediaMetaData::Keywords); - } else if (key == PKEY_Language) { - m_availableMetaDatas.push_back(QMediaMetaData::Language); - } else if (key == PKEY_Media_Publisher) { - m_availableMetaDatas.push_back(QMediaMetaData::Publisher); - } else if (key == PKEY_Media_ClassPrimaryID) { - m_availableMetaDatas.push_back(QMediaMetaData::MediaType); - } else if (key == PKEY_Media_Duration) { - m_availableMetaDatas.push_back(QMediaMetaData::Duration); - } else if (key == PKEY_Audio_EncodingBitrate) { - m_availableMetaDatas.push_back(QMediaMetaData::AudioBitRate); - } else if (key == PKEY_Audio_Format) { - m_availableMetaDatas.push_back(QMediaMetaData::AudioCodec); - } else if (key == PKEY_Media_AverageLevel) { - m_availableMetaDatas.push_back(QMediaMetaData::AverageLevel); - } else if (key == PKEY_Audio_ChannelCount) { - m_availableMetaDatas.push_back(QMediaMetaData::ChannelCount); - } else if (key == PKEY_Audio_PeakValue) { - m_availableMetaDatas.push_back(QMediaMetaData::PeakValue); - } else if (key == PKEY_Audio_SampleRate) { - m_availableMetaDatas.push_back(QMediaMetaData::SampleRate); - } else if (key == PKEY_Music_AlbumTitle) { - m_availableMetaDatas.push_back(QMediaMetaData::AlbumTitle); - } else if (key == PKEY_Music_AlbumArtist) { - m_availableMetaDatas.push_back(QMediaMetaData::AlbumArtist); - } else if (key == PKEY_Music_Artist) { - m_availableMetaDatas.push_back(QMediaMetaData::ContributingArtist); - } else if (key == PKEY_Music_Composer) { - m_availableMetaDatas.push_back(QMediaMetaData::Composer); - } else if (key == PKEY_Music_Conductor) { - m_availableMetaDatas.push_back(QMediaMetaData::Conductor); - } else if (key == PKEY_Music_Lyrics) { - m_availableMetaDatas.push_back(QMediaMetaData::Lyrics); - } else if (key == PKEY_Music_Mood) { - m_availableMetaDatas.push_back(QMediaMetaData::Mood); - } else if (key == PKEY_Music_TrackNumber) { - m_availableMetaDatas.push_back(QMediaMetaData::TrackNumber); - } else if (key == PKEY_Music_Genre) { - m_availableMetaDatas.push_back(QMediaMetaData::Genre); - } else if (key == PKEY_ThumbnailStream) { - m_availableMetaDatas.push_back(QMediaMetaData::ThumbnailImage); - } else if (key == PKEY_Video_FrameHeight) { - m_availableMetaDatas.push_back(QMediaMetaData::Resolution); - } else if (key == PKEY_Video_Orientation) { - m_availableMetaDatas.push_back(QMediaMetaData::Orientation); - } else if (key == PKEY_Video_HorizontalAspectRatio) { - m_availableMetaDatas.push_back(QMediaMetaData::PixelAspectRatio); - } else if (key == PKEY_Video_FrameRate) { - m_availableMetaDatas.push_back(QMediaMetaData::VideoFrameRate); - } else if (key == PKEY_Video_EncodingBitrate) { - m_availableMetaDatas.push_back(QMediaMetaData::VideoBitRate); - } else if (key == PKEY_Video_Compression) { - m_availableMetaDatas.push_back(QMediaMetaData::VideoCodec); - } else if (key == PKEY_Video_Director) { - m_availableMetaDatas.push_back(QMediaMetaData::Director); - } else if (key == PKEY_Media_Writer) { - m_availableMetaDatas.push_back(QMediaMetaData::Writer); - } else { - common = false; - //TODO: add more extended keys - } - if (common) - m_commonKeys.push_back(key); - } - } else { - m_content->Release(); - m_content = NULL; - } - } - - if (!m_content) { - //fallback to Vista approach - IMFMetadataProvider *provider = NULL; - if (SUCCEEDED(MFGetService(mediaSource, MF_METADATA_PROVIDER_SERVICE, IID_PPV_ARGS(&provider)))) { - if (SUCCEEDED(provider->GetMFMetadata(sourcePD, 0, 0, &m_metaData))) { - PROPVARIANT varNames; - PropVariantInit(&varNames); - if (SUCCEEDED(m_metaData->GetAllPropertyNames(&varNames)) && varNames.vt == (VT_VECTOR | VT_LPWSTR)) { - ULONG cElements = varNames.calpwstr.cElems; - for (ULONG i = 0; i < cElements; i++) - { - const WCHAR* sName = varNames.calpwstr.pElems[i]; -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "metadata: " << QString::fromUtf16(sName); -#endif - if (wcscmp(sName, L"Author") == 0) { - m_availableMetaDatas.push_back(QMediaMetaData::Author); - } else if (wcscmp(sName, L"Title") == 0) { - m_availableMetaDatas.push_back(QMediaMetaData::Title); - } else if (wcscmp(sName, L"Rating") == 0) { - m_availableMetaDatas.push_back(QMediaMetaData::ParentalRating); - } else if (wcscmp(sName, L"Description") == 0) { - m_availableMetaDatas.push_back(QMediaMetaData::Description); - } else if (wcscmp(sName, L"Copyright") == 0) { - m_availableMetaDatas.push_back(QMediaMetaData::Copyright); - //TODO: add more common keys - } else { - m_availableMetaDatas.push_back(QString::fromUtf16(reinterpret_cast<const ushort*>(sName))); - } - m_commonNames.push_back(QString::fromUtf16(reinterpret_cast<const ushort*>(sName))); - } - } - PropVariantClear(&varNames); - } else { - qWarning("Failed to get IMFMetadata"); - } - provider->Release(); - } else { - qWarning("Failed to get IMFMetadataProvider from source"); - } - } - - emit metaDataChanged(); - emit metaDataAvailableChanged(m_metaData || m_content); -} diff --git a/src/plugins/wmf/player/mfmetadatacontrol.h b/src/plugins/wmf/player/mfmetadatacontrol.h deleted file mode 100644 index 7ae06cedb..000000000 --- a/src/plugins/wmf/player/mfmetadatacontrol.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFMETADATACONTROL_H -#define MFMETADATACONTROL_H - -#include <qmetadatareadercontrol.h> -#include "Mfidl.h" - -QT_USE_NAMESPACE - -class MFMetaDataControl : public QMetaDataReaderControl -{ - Q_OBJECT -public: - MFMetaDataControl(QObject *parent = 0); - ~MFMetaDataControl(); - - bool isMetaDataAvailable() const; - - QVariant metaData(const QString &key) const; - QStringList availableMetaData() const; - - void updateSource(IMFPresentationDescriptor* sourcePD, IMFMediaSource* mediaSource); - -private: - QVariant convertValue(const PROPVARIANT& var) const; - IPropertyStore *m_content; //for Windows7 - IMFMetadata *m_metaData; //for Vista - - QStringList m_availableMetaDatas; - QList<PROPERTYKEY> m_commonKeys; //for Windows7 - QStringList m_commonNames; //for Vista -}; - -#endif diff --git a/src/plugins/wmf/player/mfplayercontrol.cpp b/src/plugins/wmf/player/mfplayercontrol.cpp deleted file mode 100644 index 818d5c0f7..000000000 --- a/src/plugins/wmf/player/mfplayercontrol.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfplayercontrol.h" -#include <qtcore/qdebug.h> - -//#define DEBUG_MEDIAFOUNDATION - -MFPlayerControl::MFPlayerControl(MFPlayerSession *session) -: QMediaPlayerControl(session) -, m_state(QMediaPlayer::StoppedState) -, m_stateDirty(false) -, m_videoAvailable(false) -, m_audioAvailable(false) -, m_duration(-1) -, m_seekable(false) -, m_session(session) -{ - QObject::connect(m_session, SIGNAL(statusChanged()), this, SLOT(handleStatusChanged())); - QObject::connect(m_session, SIGNAL(videoAvailable()), this, SLOT(handleVideoAvailable())); - QObject::connect(m_session, SIGNAL(audioAvailable()), this, SLOT(handleAudioAvailable())); - QObject::connect(m_session, SIGNAL(durationUpdate(qint64)), this, SLOT(handleDurationUpdate(qint64))); - QObject::connect(m_session, SIGNAL(seekableUpdate(bool)), this, SLOT(handleSeekableUpdate(bool))); - QObject::connect(m_session, SIGNAL(error(QMediaPlayer::Error,QString,bool)), this, SLOT(handleError(QMediaPlayer::Error,QString,bool))); - QObject::connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(positionChanged(qint64))); - QObject::connect(m_session, SIGNAL(volumeChanged(int)), this, SIGNAL(volumeChanged(int))); - QObject::connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool))); - QObject::connect(m_session, SIGNAL(playbackRateChanged(qreal)), this, SIGNAL(playbackRateChanged(qreal))); - QObject::connect(m_session, SIGNAL(bufferStatusChanged(int)), this, SIGNAL(bufferStatusChanged(int))); -} - -MFPlayerControl::~MFPlayerControl() -{ -} - -void MFPlayerControl::setMedia(const QUrl &media, QIODevice *stream) -{ - if (m_state != QMediaPlayer::StoppedState) { - changeState(QMediaPlayer::StoppedState); - m_session->stop(true); - refreshState(); - } - - m_media = media; - m_stream = stream; - resetAudioVideoAvailable(); - handleDurationUpdate(-1); - handleSeekableUpdate(false); - m_session->load(media, stream); - emit mediaChanged(m_media); -} - -void MFPlayerControl::play() -{ - if (m_state == QMediaPlayer::PlayingState) - return; - if (QMediaPlayer::InvalidMedia == m_session->status()) - m_session->load(m_media, m_stream); - - switch (m_session->status()) { - case QMediaPlayer::UnknownMediaStatus: - case QMediaPlayer::NoMedia: - case QMediaPlayer::InvalidMedia: - return; - case QMediaPlayer::LoadedMedia: - case QMediaPlayer::BufferingMedia: - case QMediaPlayer::BufferedMedia: - case QMediaPlayer::EndOfMedia: - changeState(QMediaPlayer::PlayingState); - m_session->start(); - break; - default: //Loading/Stalled - changeState(QMediaPlayer::PlayingState); - break; - } - refreshState(); -} - -void MFPlayerControl::pause() -{ - if (m_state != QMediaPlayer::PlayingState) - return; - changeState(QMediaPlayer::PausedState); - m_session->pause(); - refreshState(); -} - -void MFPlayerControl::stop() -{ - if (m_state == QMediaPlayer::StoppedState) - return; - changeState(QMediaPlayer::StoppedState); - m_session->stop(); - refreshState(); -} - -void MFPlayerControl::changeState(QMediaPlayer::State state) -{ - if (m_state == state) - return; - m_state = state; - m_stateDirty = true; -} - -void MFPlayerControl::refreshState() -{ - if (!m_stateDirty) - return; - m_stateDirty = false; -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MFPlayerControl::emit stateChanged" << m_state; -#endif - emit stateChanged(m_state); -} - -void MFPlayerControl::handleStatusChanged() -{ - QMediaPlayer::MediaStatus status = m_session->status(); - switch (status) { - case QMediaPlayer::EndOfMedia: - changeState(QMediaPlayer::StoppedState); - break; - case QMediaPlayer::InvalidMedia: - break; - case QMediaPlayer::LoadedMedia: - case QMediaPlayer::BufferingMedia: - case QMediaPlayer::BufferedMedia: - if (m_state == QMediaPlayer::PlayingState) - m_session->start(); - break; - } - emit mediaStatusChanged(m_session->status()); - refreshState(); -} - -void MFPlayerControl::handleVideoAvailable() -{ - if (m_videoAvailable) - return; - m_videoAvailable = true; - emit videoAvailableChanged(m_videoAvailable); -} - -void MFPlayerControl::handleAudioAvailable() -{ - if (m_audioAvailable) - return; - m_audioAvailable = true; - emit audioAvailableChanged(m_audioAvailable); -} - -void MFPlayerControl::resetAudioVideoAvailable() -{ - bool videoDirty = false; - if (m_videoAvailable) { - m_videoAvailable = false; - videoDirty = true; - } - if (m_audioAvailable) { - m_audioAvailable = false; - emit audioAvailableChanged(m_audioAvailable); - } - if (videoDirty) - emit videoAvailableChanged(m_videoAvailable); -} - -void MFPlayerControl::handleDurationUpdate(qint64 duration) -{ - if (m_duration == duration) - return; - m_duration = duration; - emit durationChanged(m_duration); -} - -void MFPlayerControl::handleSeekableUpdate(bool seekable) -{ - if (m_seekable == seekable) - return; - m_seekable = seekable; - emit seekableChanged(m_seekable); -} - -QMediaPlayer::State MFPlayerControl::state() const -{ - return m_state; -} - -QMediaPlayer::MediaStatus MFPlayerControl::mediaStatus() const -{ - return m_session->status(); -} - -qint64 MFPlayerControl::duration() const -{ - return m_duration; -} - -qint64 MFPlayerControl::position() const -{ - return m_session->position(); -} - -void MFPlayerControl::setPosition(qint64 position) -{ - if (!m_seekable || position == m_session->position()) - return; - m_session->setPosition(position); -} - -int MFPlayerControl::volume() const -{ - return m_session->volume(); -} - -void MFPlayerControl::setVolume(int volume) -{ - m_session->setVolume(volume); -} - -bool MFPlayerControl::isMuted() const -{ - return m_session->isMuted(); -} - -void MFPlayerControl::setMuted(bool muted) -{ - m_session->setMuted(muted); -} - -int MFPlayerControl::bufferStatus() const -{ - return m_session->bufferStatus(); -} - -bool MFPlayerControl::isAudioAvailable() const -{ - return m_audioAvailable; -} - -bool MFPlayerControl::isVideoAvailable() const -{ - return m_videoAvailable; -} - -bool MFPlayerControl::isSeekable() const -{ - return m_seekable; -} - -QMediaTimeRange MFPlayerControl::availablePlaybackRanges() const -{ - return m_session->availablePlaybackRanges(); -} - -qreal MFPlayerControl::playbackRate() const -{ - return m_session->playbackRate(); -} - -void MFPlayerControl::setPlaybackRate(qreal rate) -{ - m_session->setPlaybackRate(rate); -} - -QUrl MFPlayerControl::media() const -{ - return m_media; -} - -const QIODevice* MFPlayerControl::mediaStream() const -{ - return m_stream; -} - -void MFPlayerControl::handleError(QMediaPlayer::Error errorCode, const QString& errorString, bool isFatal) -{ - if (isFatal) - stop(); - emit error(int(errorCode), errorString); -} diff --git a/src/plugins/wmf/player/mfplayercontrol.h b/src/plugins/wmf/player/mfplayercontrol.h deleted file mode 100644 index f74f414da..000000000 --- a/src/plugins/wmf/player/mfplayercontrol.h +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFPLAYERCONTROL_H -#define MFPLAYERCONTROL_H - -#include "QUrl.h" -#include "qmediaplayercontrol.h" - -#include <QtCore/qcoreevent.h> - -#include "mfplayersession.h" - -QT_USE_NAMESPACE - -class MFPlayerControl : public QMediaPlayerControl -{ - Q_OBJECT -public: - MFPlayerControl(MFPlayerSession *session); - ~MFPlayerControl(); - - QMediaPlayer::State state() const; - - QMediaPlayer::MediaStatus mediaStatus() const; - - qint64 duration() const; - - qint64 position() const; - void setPosition(qint64 position); - - int volume() const; - void setVolume(int volume); - - bool isMuted() const; - void setMuted(bool muted); - - int bufferStatus() const; - - bool isAudioAvailable() const; - bool isVideoAvailable() const; - - bool isSeekable() const; - - QMediaTimeRange availablePlaybackRanges() const; - - qreal playbackRate() const; - void setPlaybackRate(qreal rate); - - QUrl media() const; - const QIODevice *mediaStream() const; - void setMedia(const QUrl &media, QIODevice *stream); - - void play(); - void pause(); - void stop(); - - bool streamPlaybackSupported() const { return true; } - - -private Q_SLOTS: - void handleStatusChanged(); - void handleVideoAvailable(); - void handleAudioAvailable(); - void handleDurationUpdate(qint64 duration); - void handleSeekableUpdate(bool seekable); - void handleError(QMediaPlayer::Error errorCode, const QString& errorString, bool isFatal); - -private: - void changeState(QMediaPlayer::State state); - void resetAudioVideoAvailable(); - void refreshState(); - - QMediaPlayer::State m_state; - bool m_stateDirty; - QMediaPlayer::MediaStatus m_status; - QMediaPlayer::Error m_error; - - bool m_videoAvailable; - bool m_audioAvailable; - qint64 m_duration; - bool m_seekable; - - QIODevice *m_stream; - QUrl m_media; - MFPlayerSession *m_session; -}; - -#endif diff --git a/src/plugins/wmf/player/mfplayerservice.cpp b/src/plugins/wmf/player/mfplayerservice.cpp deleted file mode 100644 index fdb124f8e..000000000 --- a/src/plugins/wmf/player/mfplayerservice.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "QUrl.h" - -#include <QtCore/qdebug.h> - -#include "mfplayercontrol.h" -#include "mfevrvideowindowcontrol.h" -#include "mfvideorenderercontrol.h" -#include "mfaudioendpointcontrol.h" -#include "mfaudioprobecontrol.h" -#include "mfvideoprobecontrol.h" -#include "mfplayerservice.h" -#include "mfplayersession.h" -#include "mfmetadatacontrol.h" - -MFPlayerService::MFPlayerService(QObject *parent) - : QMediaService(parent) - , m_session(0) - , m_videoWindowControl(0) - , m_videoRendererControl(0) -{ - m_audioEndpointControl = new MFAudioEndpointControl(this); - m_session = new MFPlayerSession(this); - m_player = new MFPlayerControl(m_session); - m_metaDataControl = new MFMetaDataControl(this); -} - -MFPlayerService::~MFPlayerService() -{ - m_session->close(); - - if (m_videoWindowControl) - delete m_videoWindowControl; - - if (m_videoRendererControl) - delete m_videoRendererControl; - - m_session->Release(); -} - -QObject *MFPlayerService::requestControl(const char *name) -{ - if (qstrcmp(name, QMediaPlayerControl_iid) == 0) { - return m_player; - } else if (qstrcmp(name, QAudioOutputSelectorControl_iid) == 0) { - return m_audioEndpointControl; - } else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) { - return m_metaDataControl; - } else if (qstrcmp(name, QVideoRendererControl_iid) == 0) { - if (!m_videoRendererControl && !m_videoWindowControl) { - m_videoRendererControl = new MFVideoRendererControl; - return m_videoRendererControl; - } - } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) { - if (!m_videoRendererControl && !m_videoWindowControl) { - m_videoWindowControl = new MFEvrVideoWindowControl; - return m_videoWindowControl; - } - } else if (qstrcmp(name,QMediaAudioProbeControl_iid) == 0) { - if (m_session) { - MFAudioProbeControl *probe = new MFAudioProbeControl(this); - m_session->addProbe(probe); - return probe; - } - return 0; - } else if (qstrcmp(name,QMediaVideoProbeControl_iid) == 0) { - if (m_session) { - MFVideoProbeControl *probe = new MFVideoProbeControl(this); - m_session->addProbe(probe); - return probe; - } - return 0; - } - - return 0; -} - -void MFPlayerService::releaseControl(QObject *control) -{ - if (!control) { - qWarning("QMediaService::releaseControl():" - " Attempted release of null control"); - } else if (control == m_videoRendererControl) { - m_videoRendererControl->setSurface(0); - delete m_videoRendererControl; - m_videoRendererControl = 0; - return; - } else if (control == m_videoWindowControl) { - delete m_videoWindowControl; - m_videoWindowControl = 0; - return; - } - - MFAudioProbeControl* audioProbe = qobject_cast<MFAudioProbeControl*>(control); - if (audioProbe) { - if (m_session) - m_session->removeProbe(audioProbe); - delete audioProbe; - return; - } - - MFVideoProbeControl* videoProbe = qobject_cast<MFVideoProbeControl*>(control); - if (videoProbe) { - if (m_session) - m_session->removeProbe(videoProbe); - delete videoProbe; - return; - } -} - -MFAudioEndpointControl* MFPlayerService::audioEndpointControl() const -{ - return m_audioEndpointControl; -} - -MFVideoRendererControl* MFPlayerService::videoRendererControl() const -{ - return m_videoRendererControl; -} - -MFEvrVideoWindowControl* MFPlayerService::videoWindowControl() const -{ - return m_videoWindowControl; -} - -MFMetaDataControl* MFPlayerService::metaDataControl() const -{ - return m_metaDataControl; -} diff --git a/src/plugins/wmf/player/mfplayerservice.h b/src/plugins/wmf/player/mfplayerservice.h deleted file mode 100644 index 4bcccaf89..000000000 --- a/src/plugins/wmf/player/mfplayerservice.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFPLAYERSERVICE_H -#define MFPLAYERSERVICE_H - -#include <mfapi.h> -#include <mfidl.h> - -#include "qmediaplayer.h" -#include "qmediaservice.h" -#include "qmediatimerange.h" - -QT_BEGIN_NAMESPACE -class QUrl; -QT_END_NAMESPACE - -QT_USE_NAMESPACE - -class MFEvrVideoWindowControl; -class MFAudioEndpointControl; -class MFVideoRendererControl; -class MFPlayerControl; -class MFMetaDataControl; -class MFPlayerSession; - -class MFPlayerService : public QMediaService -{ - Q_OBJECT -public: - MFPlayerService(QObject *parent = 0); - ~MFPlayerService(); - - QObject *requestControl(const char *name); - void releaseControl(QObject *control); - - MFAudioEndpointControl* audioEndpointControl() const; - MFVideoRendererControl* videoRendererControl() const; - MFEvrVideoWindowControl* videoWindowControl() const; - MFMetaDataControl* metaDataControl() const; - -private: - MFPlayerSession *m_session; - MFVideoRendererControl *m_videoRendererControl; - MFAudioEndpointControl *m_audioEndpointControl; - MFEvrVideoWindowControl *m_videoWindowControl; - MFPlayerControl *m_player; - MFMetaDataControl *m_metaDataControl; -}; - -#endif diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp deleted file mode 100644 index 2dec144f3..000000000 --- a/src/plugins/wmf/player/mfplayersession.cpp +++ /dev/null @@ -1,1818 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "QUrl.h" -#include "qmediaplayercontrol.h" - -#include <QtCore/qcoreapplication.h> -#include <QtCore/qdatetime.h> -#include <QtCore/qthread.h> -#include <QtCore/qvarlengtharray.h> -#include <QtCore/qdebug.h> -#include <QtCore/qfile.h> -#include <QtCore/qbuffer.h> - -#include "mfplayercontrol.h" -#include "mfevrvideowindowcontrol.h" -#include "mfvideorenderercontrol.h" -#include "mfaudioendpointcontrol.h" - -#include "mfplayersession.h" -#include "mfplayerservice.h" -#include "mfmetadatacontrol.h" -#include <mferror.h> -#include <nserror.h> -#include "sourceresolver.h" -#include "samplegrabber.h" -#include "mftvideo.h" -#include <wmcodecdsp.h> - -//#define DEBUG_MEDIAFOUNDATION - -MFPlayerSession::MFPlayerSession(MFPlayerService *playerService) - : m_playerService(playerService) - , m_cRef(1) - , m_session(0) - , m_presentationClock(0) - , m_rateControl(0) - , m_rateSupport(0) - , m_volumeControl(0) - , m_netsourceStatistics(0) - , m_duration(0) - , m_sourceResolver(0) - , m_hCloseEvent(0) - , m_closing(false) - , m_pendingRate(1) - , m_volume(100) - , m_muted(false) - , m_status(QMediaPlayer::NoMedia) - , m_scrubbing(false) - , m_restoreRate(1) - , m_mediaTypes(0) - , m_audioSampleGrabber(0) - , m_audioSampleGrabberNode(0) - , m_videoProbeMFT(0) -{ - QObject::connect(this, SIGNAL(sessionEvent(IMFMediaEvent*)), this, SLOT(handleSessionEvent(IMFMediaEvent*))); - - m_pendingState = NoPending; - ZeroMemory(&m_state, sizeof(m_state)); - m_state.command = CmdStop; - m_state.prevCmd = CmdNone; - m_state.rate = 1.0f; - ZeroMemory(&m_request, sizeof(m_request)); - m_request.command = CmdNone; - m_request.prevCmd = CmdNone; - m_request.rate = 1.0f; - - m_audioSampleGrabber = new AudioSampleGrabberCallback; -} - -void MFPlayerSession::close() -{ -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "close"; -#endif - - clear(); - if (!m_session) - return; - - HRESULT hr = S_OK; - if (m_session) { - m_closing = true; - hr = m_session->Close(); - if (SUCCEEDED(hr)) { - DWORD dwWaitResult = WaitForSingleObject(m_hCloseEvent, 100); - if (dwWaitResult == WAIT_TIMEOUT) { - qWarning() << "session close time out!"; - } - } - m_closing = false; - } - - if (SUCCEEDED(hr)) { - if (m_session) - m_session->Shutdown(); - if (m_sourceResolver) - m_sourceResolver->shutdown(); - } - if (m_sourceResolver) { - m_sourceResolver->Release(); - m_sourceResolver = 0; - } - if (m_videoProbeMFT) { - m_videoProbeMFT->Release(); - m_videoProbeMFT = 0; - } - - if (m_playerService->videoRendererControl()) { - m_playerService->videoRendererControl()->releaseActivate(); - } else if (m_playerService->videoWindowControl()) { - m_playerService->videoWindowControl()->releaseActivate(); - } - - if (m_session) - m_session->Release(); - m_session = 0; - if (m_hCloseEvent) - CloseHandle(m_hCloseEvent); - m_hCloseEvent = 0; -} - -void MFPlayerSession::addProbe(MFAudioProbeControl *probe) -{ - m_audioSampleGrabber->addProbe(probe); -} - -void MFPlayerSession::removeProbe(MFAudioProbeControl *probe) -{ - m_audioSampleGrabber->removeProbe(probe); -} - -void MFPlayerSession::addProbe(MFVideoProbeControl* probe) -{ - if (m_videoProbes.contains(probe)) - return; - - m_videoProbes.append(probe); - - if (m_videoProbeMFT) - m_videoProbeMFT->addProbe(probe); -} - -void MFPlayerSession::removeProbe(MFVideoProbeControl* probe) -{ - m_videoProbes.removeOne(probe); - - if (m_videoProbeMFT) - m_videoProbeMFT->removeProbe(probe); -} - -MFPlayerSession::~MFPlayerSession() -{ - m_audioSampleGrabber->Release(); -} - - -void MFPlayerSession::load(const QUrl &media, QIODevice *stream) -{ -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "load"; -#endif - clear(); - QUrl url = media.request().url(); - - if (m_status == QMediaPlayer::LoadingMedia && m_sourceResolver) - m_sourceResolver->cancel(); - - if (url.isEmpty() && !stream) { - changeStatus(QMediaPlayer::NoMedia); - } else if (stream && (!stream->isReadable())) { - changeStatus(QMediaPlayer::InvalidMedia); - emit error(QMediaPlayer::ResourceError, tr("Invalid stream source."), true); - } else { - createSession(); - changeStatus(QMediaPlayer::LoadingMedia); - m_sourceResolver->load(url, stream); - } - emit positionChanged(position()); -} - -void MFPlayerSession::handleSourceError(long hr) -{ - QString errorString; - QMediaPlayer::Error errorCode = QMediaPlayer::ResourceError; - switch (hr) { - case QMediaPlayer::FormatError: - errorCode = QMediaPlayer::FormatError; - errorString = tr("Attempting to play invalid Qt resource."); - break; - case NS_E_FILE_NOT_FOUND: - errorString = tr("The system cannot find the file specified."); - break; - case NS_E_SERVER_NOT_FOUND: - errorString = tr("The specified server could not be found."); - break; - case MF_E_UNSUPPORTED_BYTESTREAM_TYPE: - errorCode = QMediaPlayer::FormatError; - errorString = tr("Unsupported media type."); - break; - default: - errorString = tr("Failed to load source."); - break; - } - changeStatus(QMediaPlayer::InvalidMedia); - emit error(errorCode, errorString, true); -} - -void MFPlayerSession::handleMediaSourceReady() -{ - if (QMediaPlayer::LoadingMedia != m_status || !m_sourceResolver || m_sourceResolver != sender()) - return; -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "handleMediaSourceReady"; -#endif - HRESULT hr = S_OK; - IMFMediaSource* mediaSource = m_sourceResolver->mediaSource(); - - DWORD dwCharacteristics = 0; - mediaSource->GetCharacteristics(&dwCharacteristics); - emit seekableUpdate(MFMEDIASOURCE_CAN_SEEK & dwCharacteristics); - - IMFPresentationDescriptor* sourcePD; - hr = mediaSource->CreatePresentationDescriptor(&sourcePD); - if (SUCCEEDED(hr)) { - m_duration = 0; - m_playerService->metaDataControl()->updateSource(sourcePD, mediaSource); - sourcePD->GetUINT64(MF_PD_DURATION, &m_duration); - //convert from 100 nanosecond to milisecond - emit durationUpdate(qint64(m_duration / 10000)); - setupPlaybackTopology(mediaSource, sourcePD); - sourcePD->Release(); - } else { - changeStatus(QMediaPlayer::InvalidMedia); - emit error(QMediaPlayer::ResourceError, tr("Cannot create presentation descriptor."), true); - } -} - -MFPlayerSession::MediaType MFPlayerSession::getStreamType(IMFStreamDescriptor *stream) const -{ - if (!stream) - return Unknown; - - struct SafeRelease { - IMFMediaTypeHandler *ptr = nullptr; - ~SafeRelease() { if (ptr) ptr->Release(); } - } typeHandler; - if (SUCCEEDED(stream->GetMediaTypeHandler(&typeHandler.ptr))) { - GUID guidMajorType; - if (SUCCEEDED(typeHandler.ptr->GetMajorType(&guidMajorType))) { - if (guidMajorType == MFMediaType_Audio) - return Audio; - else if (guidMajorType == MFMediaType_Video) - return Video; - } - } - - return Unknown; -} - -void MFPlayerSession::setupPlaybackTopology(IMFMediaSource *source, IMFPresentationDescriptor *sourcePD) -{ - HRESULT hr = S_OK; - // Get the number of streams in the media source. - DWORD cSourceStreams = 0; - hr = sourcePD->GetStreamDescriptorCount(&cSourceStreams); - if (FAILED(hr)) { - changeStatus(QMediaPlayer::UnknownMediaStatus); - emit error(QMediaPlayer::ResourceError, tr("Failed to get stream count."), true); - return; - } - - IMFTopology *topology; - hr = MFCreateTopology(&topology); - if (FAILED(hr)) { - changeStatus(QMediaPlayer::UnknownMediaStatus); - emit error(QMediaPlayer::ResourceError, tr("Failed to create topology."), true); - return; - } - - // Remember output node id for a first video stream - TOPOID outputNodeId = -1; - - // For each stream, create the topology nodes and add them to the topology. - DWORD succeededCount = 0; - for (DWORD i = 0; i < cSourceStreams; i++) - { - BOOL fSelected = FALSE; - bool streamAdded = false; - IMFStreamDescriptor *streamDesc = NULL; - - HRESULT hr = sourcePD->GetStreamDescriptorByIndex(i, &fSelected, &streamDesc); - if (SUCCEEDED(hr)) { - // The media might have multiple audio and video streams, - // only use one of each kind, and only if it is selected by default. - MediaType mediaType = getStreamType(streamDesc); - if (mediaType != Unknown - && ((m_mediaTypes & mediaType) == 0) // Check if this type isn't already added - && fSelected) { - - IMFTopologyNode *sourceNode = addSourceNode(topology, source, sourcePD, streamDesc); - if (sourceNode) { - IMFTopologyNode *outputNode = addOutputNode(mediaType, topology, 0); - if (outputNode) { - bool connected = false; - if (mediaType == Audio) { - if (!m_audioSampleGrabberNode) - connected = setupAudioSampleGrabber(topology, sourceNode, outputNode); - } else if (mediaType == Video && outputNodeId == -1) { - // Remember video output node ID. - outputNode->GetTopoNodeID(&outputNodeId); - } - - if (!connected) - hr = sourceNode->ConnectOutput(0, outputNode, 0); - - if (FAILED(hr)) { - emit error(QMediaPlayer::FormatError, tr("Unable to play any stream."), false); - } else { - streamAdded = true; - succeededCount++; - m_mediaTypes |= mediaType; - switch (mediaType) { - case Audio: - emit audioAvailable(); - break; - case Video: - emit videoAvailable(); - break; - } - } - outputNode->Release(); - } - sourceNode->Release(); - } - } - - if (fSelected && !streamAdded) - sourcePD->DeselectStream(i); - - streamDesc->Release(); - } - } - - if (succeededCount == 0) { - changeStatus(QMediaPlayer::InvalidMedia); - emit error(QMediaPlayer::ResourceError, tr("Unable to play."), true); - } else { - if (outputNodeId != -1) { - topology = insertMFT(topology, outputNodeId); - } - - hr = m_session->SetTopology(MFSESSION_SETTOPOLOGY_IMMEDIATE, topology); - if (FAILED(hr)) { - changeStatus(QMediaPlayer::UnknownMediaStatus); - emit error(QMediaPlayer::ResourceError, tr("Failed to set topology."), true); - } - } - topology->Release(); -} - -IMFTopologyNode* MFPlayerSession::addSourceNode(IMFTopology* topology, IMFMediaSource* source, - IMFPresentationDescriptor* presentationDesc, IMFStreamDescriptor *streamDesc) -{ - IMFTopologyNode *node = NULL; - HRESULT hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node); - if (SUCCEEDED(hr)) { - hr = node->SetUnknown(MF_TOPONODE_SOURCE, source); - if (SUCCEEDED(hr)) { - hr = node->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, presentationDesc); - if (SUCCEEDED(hr)) { - hr = node->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, streamDesc); - if (SUCCEEDED(hr)) { - hr = topology->AddNode(node); - if (SUCCEEDED(hr)) - return node; - } - } - } - node->Release(); - } - return NULL; -} - -IMFTopologyNode* MFPlayerSession::addOutputNode(MediaType mediaType, IMFTopology* topology, DWORD sinkID) -{ - IMFTopologyNode *node = NULL; - if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node))) - return NULL; - - IMFActivate *activate = NULL; - if (mediaType == Audio) { - activate = m_playerService->audioEndpointControl()->createActivate(); - } else if (mediaType == Video) { - if (m_playerService->videoRendererControl()) { - activate = m_playerService->videoRendererControl()->createActivate(); - } else if (m_playerService->videoWindowControl()) { - activate = m_playerService->videoWindowControl()->createActivate(); - } else { - qWarning() << "no videoWindowControl or videoRendererControl, unable to add output node for video data"; - } - } else { - // Unknown stream type. - emit error(QMediaPlayer::FormatError, tr("Unknown stream type."), false); - } - - if (!activate - || FAILED(node->SetObject(activate)) - || FAILED(node->SetUINT32(MF_TOPONODE_STREAMID, sinkID)) - || FAILED(node->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE)) - || FAILED(topology->AddNode(node))) { - node->Release(); - node = NULL; - } - - return node; -} - -bool MFPlayerSession::addAudioSampleGrabberNode(IMFTopology *topology) -{ - HRESULT hr = S_OK; - IMFMediaType *pType = 0; - IMFActivate *sinkActivate = 0; - do { - hr = MFCreateMediaType(&pType); - if (FAILED(hr)) - break; - - hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio); - if (FAILED(hr)) - break; - - hr = pType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM); - if (FAILED(hr)) - break; - - hr = MFCreateSampleGrabberSinkActivate(pType, m_audioSampleGrabber, &sinkActivate); - if (FAILED(hr)) - break; - - // Note: Data is distorted if this attribute is enabled - hr = sinkActivate->SetUINT32(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, FALSE); - if (FAILED(hr)) - break; - - hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &m_audioSampleGrabberNode); - if (FAILED(hr)) - break; - - hr = m_audioSampleGrabberNode->SetObject(sinkActivate); - if (FAILED(hr)) - break; - - hr = m_audioSampleGrabberNode->SetUINT32(MF_TOPONODE_STREAMID, 0); // Identifier of the stream sink. - if (FAILED(hr)) - break; - - hr = m_audioSampleGrabberNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE); - if (FAILED(hr)) - break; - - hr = topology->AddNode(m_audioSampleGrabberNode); - if (FAILED(hr)) - break; - - pType->Release(); - sinkActivate->Release(); - return true; - } while (false); - - if (pType) - pType->Release(); - if (sinkActivate) - sinkActivate->Release(); - if (m_audioSampleGrabberNode) { - m_audioSampleGrabberNode->Release(); - m_audioSampleGrabberNode = NULL; - } - return false; -} - -bool MFPlayerSession::setupAudioSampleGrabber(IMFTopology *topology, IMFTopologyNode *sourceNode, IMFTopologyNode *outputNode) -{ - if (!addAudioSampleGrabberNode(topology)) - return false; - - HRESULT hr = S_OK; - IMFTopologyNode *pTeeNode = NULL; - - IMFMediaTypeHandler *typeHandler = NULL; - IMFMediaType *mediaType = NULL; - do { - hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &pTeeNode); - if (FAILED(hr)) - break; - hr = sourceNode->ConnectOutput(0, pTeeNode, 0); - if (FAILED(hr)) - break; - hr = pTeeNode->ConnectOutput(0, outputNode, 0); - if (FAILED(hr)) - break; - hr = pTeeNode->ConnectOutput(1, m_audioSampleGrabberNode, 0); - if (FAILED(hr)) - break; - } while (false); - - if (pTeeNode) - pTeeNode->Release(); - if (mediaType) - mediaType->Release(); - if (typeHandler) - typeHandler->Release(); - return hr == S_OK; -} - -QAudioFormat MFPlayerSession::audioFormatForMFMediaType(IMFMediaType *mediaType) const -{ - WAVEFORMATEX *wfx = 0; - UINT32 size; - HRESULT hr = MFCreateWaveFormatExFromMFMediaType(mediaType, &wfx, &size, MFWaveFormatExConvertFlag_Normal); - if (FAILED(hr)) - return QAudioFormat(); - - if (size < sizeof(WAVEFORMATEX)) { - CoTaskMemFree(wfx); - return QAudioFormat(); - } - - if (wfx->wFormatTag != WAVE_FORMAT_PCM) { - CoTaskMemFree(wfx); - return QAudioFormat(); - } - - QAudioFormat format; - format.setSampleRate(wfx->nSamplesPerSec); - format.setChannelCount(wfx->nChannels); - format.setSampleSize(wfx->wBitsPerSample); - format.setCodec("audio/x-raw"); - format.setByteOrder(QAudioFormat::LittleEndian); - if (format.sampleSize() == 8) - format.setSampleType(QAudioFormat::UnSignedInt); - else - format.setSampleType(QAudioFormat::SignedInt); - - CoTaskMemFree(wfx); - return format; -} - -// BindOutputNode -// Sets the IMFStreamSink pointer on an output node. -// IMFActivate pointer in the output node must be converted to an -// IMFStreamSink pointer before the topology loader resolves the topology. -HRESULT BindOutputNode(IMFTopologyNode *pNode) -{ - IUnknown *nodeObject = NULL; - IMFActivate *activate = NULL; - IMFStreamSink *stream = NULL; - IMFMediaSink *sink = NULL; - - HRESULT hr = pNode->GetObject(&nodeObject); - if (FAILED(hr)) - return hr; - - hr = nodeObject->QueryInterface(IID_PPV_ARGS(&activate)); - if (SUCCEEDED(hr)) { - DWORD dwStreamID = 0; - - // Try to create the media sink. - hr = activate->ActivateObject(IID_PPV_ARGS(&sink)); - if (SUCCEEDED(hr)) - dwStreamID = MFGetAttributeUINT32(pNode, MF_TOPONODE_STREAMID, 0); - - if (SUCCEEDED(hr)) { - // First check if the media sink already has a stream sink with the requested ID. - hr = sink->GetStreamSinkById(dwStreamID, &stream); - if (FAILED(hr)) { - // Create the stream sink. - hr = sink->AddStreamSink(dwStreamID, NULL, &stream); - } - } - - // Replace the node's object pointer with the stream sink. - if (SUCCEEDED(hr)) { - hr = pNode->SetObject(stream); - } - } else { - hr = nodeObject->QueryInterface(IID_PPV_ARGS(&stream)); - } - - if (nodeObject) - nodeObject->Release(); - if (activate) - activate->Release(); - if (stream) - stream->Release(); - if (sink) - sink->Release(); - return hr; -} - -// BindOutputNodes -// Sets the IMFStreamSink pointers on all of the output nodes in a topology. -HRESULT BindOutputNodes(IMFTopology *pTopology) -{ - IMFCollection *collection; - - // Get the collection of output nodes. - HRESULT hr = pTopology->GetOutputNodeCollection(&collection); - - // Enumerate all of the nodes in the collection. - if (SUCCEEDED(hr)) { - DWORD cNodes; - hr = collection->GetElementCount(&cNodes); - - if (SUCCEEDED(hr)) { - for (DWORD i = 0; i < cNodes; i++) { - IUnknown *element; - hr = collection->GetElement(i, &element); - if (FAILED(hr)) - break; - - IMFTopologyNode *node; - hr = element->QueryInterface(IID_IMFTopologyNode, (void**)&node); - element->Release(); - if (FAILED(hr)) - break; - - // Bind this node. - hr = BindOutputNode(node); - node->Release(); - if (FAILED(hr)) - break; - } - } - collection->Release(); - } - - return hr; -} - -// This method binds output nodes to complete the topology, -// then loads the topology and inserts MFT between the output node -// and a filter connected to the output node. -IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNodeId) -{ - bool isNewTopology = false; - - IMFTopoLoader *topoLoader = 0; - IMFTopology *resolvedTopology = 0; - IMFCollection *outputNodes = 0; - - do { - if (FAILED(BindOutputNodes(topology))) - break; - - if (FAILED(MFCreateTopoLoader(&topoLoader))) - break; - - if (FAILED(topoLoader->Load(topology, &resolvedTopology, NULL))) { - // Topology could not be resolved, adding ourselves a color converter - // to the topology might solve the problem - insertColorConverter(topology, outputNodeId); - if (FAILED(topoLoader->Load(topology, &resolvedTopology, NULL))) - break; - } - - if (insertResizer(resolvedTopology)) - isNewTopology = true; - - // Get all output nodes and search for video output node. - if (FAILED(resolvedTopology->GetOutputNodeCollection(&outputNodes))) - break; - - DWORD elementCount = 0; - if (FAILED(outputNodes->GetElementCount(&elementCount))) - break; - - for (DWORD n = 0; n < elementCount; n++) { - IUnknown *element = 0; - IMFTopologyNode *node = 0; - IUnknown *outputObject = 0; - IMFTopologyNode *inputNode = 0; - IMFTopologyNode *mftNode = 0; - bool mftAdded = false; - - do { - if (FAILED(outputNodes->GetElement(n, &element))) - break; - - if (FAILED(element->QueryInterface(IID_IMFTopologyNode, (void**)&node))) - break; - - TOPOID id; - if (FAILED(node->GetTopoNodeID(&id))) - break; - - if (id != outputNodeId) - break; - - if (FAILED(node->GetObject(&outputObject))) - break; - - m_videoProbeMFT->setVideoSink(outputObject); - - // Insert MFT between the output node and the node connected to it. - DWORD outputIndex = 0; - if (FAILED(node->GetInput(0, &inputNode, &outputIndex))) - break; - - if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &mftNode))) - break; - - if (FAILED(mftNode->SetObject(m_videoProbeMFT))) - break; - - if (FAILED(resolvedTopology->AddNode(mftNode))) - break; - - if (FAILED(inputNode->ConnectOutput(0, mftNode, 0))) - break; - - if (FAILED(mftNode->ConnectOutput(0, node, 0))) - break; - - mftAdded = true; - isNewTopology = true; - } while (false); - - if (mftNode) - mftNode->Release(); - if (inputNode) - inputNode->Release(); - if (node) - node->Release(); - if (element) - element->Release(); - if (outputObject) - outputObject->Release(); - - if (mftAdded) - break; - else - m_videoProbeMFT->setVideoSink(NULL); - } - } while (false); - - if (outputNodes) - outputNodes->Release(); - - if (topoLoader) - topoLoader->Release(); - - if (isNewTopology) { - topology->Release(); - return resolvedTopology; - } - - if (resolvedTopology) - resolvedTopology->Release(); - - return topology; -} - -// This method checks if the topology contains a color converter transform (CColorConvertDMO), -// if it does it inserts a resizer transform (CResizerDMO) to handle dynamic frame size change -// of the video stream. -// Returns true if it inserted a resizer -bool MFPlayerSession::insertResizer(IMFTopology *topology) -{ - bool inserted = false; - WORD elementCount = 0; - IMFTopologyNode *node = 0; - IUnknown *object = 0; - IWMColorConvProps *colorConv = 0; - IMFTransform *resizer = 0; - IMFTopologyNode *resizerNode = 0; - IMFTopologyNode *inputNode = 0; - - HRESULT hr = topology->GetNodeCount(&elementCount); - if (FAILED(hr)) - return false; - - for (WORD i = 0; i < elementCount; ++i) { - if (node) { - node->Release(); - node = 0; - } - if (object) { - object->Release(); - object = 0; - } - - if (FAILED(topology->GetNode(i, &node))) - break; - - MF_TOPOLOGY_TYPE nodeType; - if (FAILED(node->GetNodeType(&nodeType))) - break; - - if (nodeType != MF_TOPOLOGY_TRANSFORM_NODE) - continue; - - if (FAILED(node->GetObject(&object))) - break; - - if (FAILED(object->QueryInterface(&colorConv))) - continue; - - if (FAILED(CoCreateInstance(CLSID_CResizerDMO, NULL, CLSCTX_INPROC_SERVER, IID_IMFTransform, (void**)&resizer))) - break; - - if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &resizerNode))) - break; - - if (FAILED(resizerNode->SetObject(resizer))) - break; - - if (FAILED(topology->AddNode(resizerNode))) - break; - - DWORD outputIndex = 0; - if (FAILED(node->GetInput(0, &inputNode, &outputIndex))) { - topology->RemoveNode(resizerNode); - break; - } - - if (FAILED(inputNode->ConnectOutput(0, resizerNode, 0))) { - topology->RemoveNode(resizerNode); - break; - } - - if (FAILED(resizerNode->ConnectOutput(0, node, 0))) { - inputNode->ConnectOutput(0, node, 0); - topology->RemoveNode(resizerNode); - break; - } - - inserted = true; - break; - } - - if (node) - node->Release(); - if (object) - object->Release(); - if (colorConv) - colorConv->Release(); - if (resizer) - resizer->Release(); - if (resizerNode) - resizerNode->Release(); - if (inputNode) - inputNode->Release(); - - return inserted; -} - -// This method inserts a color converter (CColorConvertDMO) in the topology, -// typically to convert to RGB format. -// Usually this converter is automatically inserted when the topology is resolved but -// for some reason it fails to do so in some cases, we then do it ourselves. -void MFPlayerSession::insertColorConverter(IMFTopology *topology, TOPOID outputNodeId) -{ - IMFCollection *outputNodes = 0; - - if (FAILED(topology->GetOutputNodeCollection(&outputNodes))) - return; - - DWORD elementCount = 0; - if (FAILED(outputNodes->GetElementCount(&elementCount))) - goto done; - - for (DWORD n = 0; n < elementCount; n++) { - IUnknown *element = 0; - IMFTopologyNode *node = 0; - IMFTopologyNode *inputNode = 0; - IMFTopologyNode *mftNode = 0; - IMFTransform *converter = 0; - - do { - if (FAILED(outputNodes->GetElement(n, &element))) - break; - - if (FAILED(element->QueryInterface(IID_IMFTopologyNode, (void**)&node))) - break; - - TOPOID id; - if (FAILED(node->GetTopoNodeID(&id))) - break; - - if (id != outputNodeId) - break; - - DWORD outputIndex = 0; - if (FAILED(node->GetInput(0, &inputNode, &outputIndex))) - break; - - if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &mftNode))) - break; - - if (FAILED(CoCreateInstance(CLSID_CColorConvertDMO, NULL, CLSCTX_INPROC_SERVER, IID_IMFTransform, (void**)&converter))) - break; - - if (FAILED(mftNode->SetObject(converter))) - break; - - if (FAILED(topology->AddNode(mftNode))) - break; - - if (FAILED(inputNode->ConnectOutput(0, mftNode, 0))) - break; - - if (FAILED(mftNode->ConnectOutput(0, node, 0))) - break; - - } while (false); - - if (mftNode) - mftNode->Release(); - if (inputNode) - inputNode->Release(); - if (node) - node->Release(); - if (element) - element->Release(); - if (converter) - converter->Release(); - } - -done: - if (outputNodes) - outputNodes->Release(); -} - -void MFPlayerSession::stop(bool immediate) -{ -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "stop"; -#endif - if (!immediate && m_pendingState != NoPending) { - m_request.setCommand(CmdStop); - } else { - if (m_state.command == CmdStop) - return; - - if (m_scrubbing) - scrub(false); - - if (SUCCEEDED(m_session->Stop())) { - m_state.setCommand(CmdStop); - m_pendingState = CmdPending; - if (m_status != QMediaPlayer::EndOfMedia) { - m_varStart.vt = VT_I8; - m_varStart.hVal.QuadPart = 0; - } - } else { - emit error(QMediaPlayer::ResourceError, tr("Failed to stop."), true); - } - } -} - -void MFPlayerSession::start() -{ - if (m_status == QMediaPlayer::EndOfMedia) - m_varStart.hVal.QuadPart = 0; // restart from the beginning - -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "start"; -#endif - - if (m_pendingState != NoPending) { - m_request.setCommand(CmdStart); - } else { - if (m_state.command == CmdStart) - return; - - if (m_scrubbing) - scrub(false); - - if (SUCCEEDED(m_session->Start(&GUID_NULL, &m_varStart))) { - m_state.setCommand(CmdStart); - m_pendingState = CmdPending; - PropVariantInit(&m_varStart); - } else { - emit error(QMediaPlayer::ResourceError, tr("failed to start playback"), true); - } - } -} - -void MFPlayerSession::pause() -{ -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "pause"; -#endif - if (m_pendingState != NoPending) { - m_request.setCommand(CmdPause); - } else { - if (m_state.command == CmdPause) - return; - - if (SUCCEEDED(m_session->Pause())) { - m_state.setCommand(CmdPause); - m_pendingState = CmdPending; - } else { - emit error(QMediaPlayer::ResourceError, tr("Failed to pause."), false); - } - } -} - -void MFPlayerSession::changeStatus(QMediaPlayer::MediaStatus newStatus) -{ - if (m_status == newStatus) - return; -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MFPlayerSession::changeStatus" << newStatus; -#endif - m_status = newStatus; - emit statusChanged(); -} - -QMediaPlayer::MediaStatus MFPlayerSession::status() const -{ - return m_status; -} - -void MFPlayerSession::createSession() -{ - close(); - - m_hCloseEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - - m_sourceResolver = new SourceResolver(); - QObject::connect(m_sourceResolver, SIGNAL(mediaSourceReady()), this, SLOT(handleMediaSourceReady())); - QObject::connect(m_sourceResolver, SIGNAL(error(long)), this, SLOT(handleSourceError(long))); - - m_videoProbeMFT = new MFTransform; - for (int i = 0; i < m_videoProbes.size(); ++i) - m_videoProbeMFT->addProbe(m_videoProbes.at(i)); - - Q_ASSERT(m_session == NULL); - HRESULT hr = MFCreateMediaSession(NULL, &m_session); - if (FAILED(hr)) { - changeStatus(QMediaPlayer::UnknownMediaStatus); - emit error(QMediaPlayer::ResourceError, tr("Unable to create mediasession."), true); - } - - hr = m_session->BeginGetEvent(this, m_session); - - if (FAILED(hr)) { - changeStatus(QMediaPlayer::UnknownMediaStatus); - emit error(QMediaPlayer::ResourceError, tr("Unable to pull session events."), false); - } - - PropVariantInit(&m_varStart); - m_varStart.vt = VT_I8; - m_varStart.hVal.QuadPart = 0; -} - -qint64 MFPlayerSession::position() -{ - if (m_request.command == CmdSeek || m_request.command == CmdSeekResume) - return m_request.start; - - if (m_pendingState == SeekPending) - return m_state.start; - - if (m_state.command == CmdStop) - return qint64(m_varStart.hVal.QuadPart / 10000); - - if (m_presentationClock) { - MFTIME time, sysTime; - if (FAILED(m_presentationClock->GetCorrelatedTime(0, &time, &sysTime))) - return 0; - return qint64(time / 10000); - } - return 0; -} - -void MFPlayerSession::setPosition(qint64 position) -{ -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "setPosition"; -#endif - if (m_pendingState != NoPending) { - m_request.setCommand(CmdSeek); - m_request.start = position; - } else { - setPositionInternal(position, CmdNone); - } -} - -void MFPlayerSession::setPositionInternal(qint64 position, Command requestCmd) -{ - if (m_status == QMediaPlayer::EndOfMedia) - changeStatus(QMediaPlayer::LoadedMedia); - if (m_state.command == CmdStop && requestCmd != CmdSeekResume) { - m_varStart.vt = VT_I8; - m_varStart.hVal.QuadPart = LONGLONG(position * 10000); - // Even though the position is not actually set on the session yet, - // report it to have changed anyway for UI controls to be updated - emit positionChanged(this->position()); - return; - } - - if (m_state.command == CmdPause) - scrub(true); - -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "setPositionInternal"; -#endif - - PROPVARIANT varStart; - varStart.vt = VT_I8; - varStart.hVal.QuadPart = LONGLONG(position * 10000); - if (SUCCEEDED(m_session->Start(NULL, &varStart))) - { - PropVariantInit(&m_varStart); - // Store the pending state. - m_state.setCommand(CmdStart); - m_state.start = position; - m_pendingState = SeekPending; - } else { - emit error(QMediaPlayer::ResourceError, tr("Failed to seek."), true); - } -} - -qreal MFPlayerSession::playbackRate() const -{ - if (m_scrubbing) - return m_restoreRate; - return m_state.rate; -} - -void MFPlayerSession::setPlaybackRate(qreal rate) -{ - if (m_scrubbing) { - m_restoreRate = rate; - emit playbackRateChanged(rate); - return; - } - setPlaybackRateInternal(rate); -} - -void MFPlayerSession::setPlaybackRateInternal(qreal rate) -{ - if (rate == m_request.rate) - return; - - m_pendingRate = rate; - if (!m_rateSupport) - return; - -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "setPlaybackRate"; -#endif - BOOL isThin = FALSE; - - //from MSDN http://msdn.microsoft.com/en-us/library/aa965220%28v=vs.85%29.aspx - //Thinning applies primarily to video streams. - //In thinned mode, the source drops delta frames and deliver only key frames. - //At very high playback rates, the source might skip some key frames (for example, deliver every other key frame). - - if (FAILED(m_rateSupport->IsRateSupported(FALSE, rate, NULL))) { - isThin = TRUE; - if (FAILED(m_rateSupport->IsRateSupported(isThin, rate, NULL))) { - qWarning() << "unable to set playbackrate = " << rate; - m_pendingRate = m_request.rate = m_state.rate; - return; - } - } - if (m_pendingState != NoPending) { - m_request.rate = rate; - m_request.isThin = isThin; - // Remember the current transport state (play, paused, etc), so that we - // can restore it after the rate change, if necessary. However, if - // anothercommand is already pending, that one takes precedent. - if (m_request.command == CmdNone) - m_request.setCommand(m_state.command); - } else { - //No pending operation. Commit the new rate. - commitRateChange(rate, isThin); - } -} - -void MFPlayerSession::commitRateChange(qreal rate, BOOL isThin) -{ -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "commitRateChange"; -#endif - Q_ASSERT(m_pendingState == NoPending); - MFTIME hnsSystemTime = 0; - MFTIME hnsClockTime = 0; - Command cmdNow = m_state.command; - bool resetPosition = false; - // Allowed rate transitions: - // Positive <-> negative: Stopped - // Negative <-> zero: Stopped - // Postive <-> zero: Paused or stopped - if ((rate > 0 && m_state.rate <= 0) || (rate < 0 && m_state.rate >= 0)) { - if (cmdNow == CmdStart) { - // Get the current clock position. This will be the restart time. - m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime); - Q_ASSERT(hnsSystemTime != 0); - - if (rate < 0 || m_state.rate < 0) - m_request.setCommand(CmdSeekResume); - else if (isThin || m_state.isThin) - m_request.setCommand(CmdStartAndSeek); - else - m_request.setCommand(CmdStart); - - // We need to stop only when dealing with negative rates - if (rate >= 0 && m_state.rate >= 0) - pause(); - else - stop(); - - // If we deal with negative rates, we stopped the session and consequently - // reset the position to zero. We then need to resume to the current position. - m_request.start = hnsClockTime / 10000; - } else if (cmdNow == CmdPause) { - if (rate < 0 || m_state.rate < 0) { - // The current state is paused. - // For this rate change, the session must be stopped. However, the - // session cannot transition back from stopped to paused. - // Therefore, this rate transition is not supported while paused. - qWarning() << "Unable to change rate from positive to negative or vice versa in paused state"; - rate = m_state.rate; - isThin = m_state.isThin; - goto done; - } - - // This happens when resuming playback after scrubbing in pause mode. - // This transition requires the session to be paused. Even though our - // internal state is set to paused, the session might not be so we need - // to enforce it - if (rate > 0 && m_state.rate == 0) { - m_state.setCommand(CmdNone); - pause(); - } - } - } else if (rate == 0 && m_state.rate > 0) { - if (cmdNow != CmdPause) { - // Transition to paused. - // This transisition requires the paused state. - // Pause and set the rate. - pause(); - - // Request: Switch back to current state. - m_request.setCommand(cmdNow); - } - } else if (rate == 0 && m_state.rate < 0) { - // Changing rate from negative to zero requires to stop the session - m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime); - - m_request.setCommand(CmdSeekResume); - - stop(); - - // Resume to the current position (stop() will reset the position to 0) - m_request.start = hnsClockTime / 10000; - } else if (!isThin && m_state.isThin) { - if (cmdNow == CmdStart) { - // When thinning, only key frames are read and presented. Going back - // to normal playback requires to reset the current position to force - // the pipeline to decode the actual frame at the current position - // (which might be earlier than the last decoded key frame) - resetPosition = true; - } else if (cmdNow == CmdPause) { - // If paused, don't reset the position until we resume, otherwise - // a new frame will be rendered - m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime); - m_request.setCommand(CmdSeekResume); - m_request.start = hnsClockTime / 10000; - } - - } - - // Set the rate. - if (FAILED(m_rateControl->SetRate(isThin, rate))) { - qWarning() << "failed to set playbackrate = " << rate; - rate = m_state.rate; - isThin = m_state.isThin; - goto done; - } - - if (resetPosition) { - m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime); - setPosition(hnsClockTime / 10000); - } - -done: - // Adjust our current rate and requested rate. - m_pendingRate = m_request.rate = m_state.rate = rate; - if (rate != 0) - m_state.isThin = isThin; - emit playbackRateChanged(rate); -} - -void MFPlayerSession::scrub(bool enableScrub) -{ - if (m_scrubbing == enableScrub) - return; - - m_scrubbing = enableScrub; - - if (!canScrub()) { - if (!enableScrub) - m_pendingRate = m_restoreRate; - return; - } - - if (enableScrub) { - // Enter scrubbing mode. Cache the rate. - m_restoreRate = m_request.rate; - setPlaybackRateInternal(0.0f); - } else { - // Leaving scrubbing mode. Restore the old rate. - setPlaybackRateInternal(m_restoreRate); - } -} - -int MFPlayerSession::volume() const -{ - return m_volume; -} - -void MFPlayerSession::setVolume(int volume) -{ - if (m_volume == volume) - return; - m_volume = volume; - - if (!m_muted) - setVolumeInternal(volume); - - emit volumeChanged(m_volume); -} - -bool MFPlayerSession::isMuted() const -{ - return m_muted; -} - -void MFPlayerSession::setMuted(bool muted) -{ - if (m_muted == muted) - return; - m_muted = muted; - - setVolumeInternal(muted ? 0 : m_volume); - - emit mutedChanged(m_muted); -} - -void MFPlayerSession::setVolumeInternal(int volume) -{ - if (m_volumeControl) { - quint32 channelCount = 0; - if (!SUCCEEDED(m_volumeControl->GetChannelCount(&channelCount)) - || channelCount == 0) - return; - - float scaled = volume * 0.01f; - for (quint32 i = 0; i < channelCount; ++i) - m_volumeControl->SetChannelVolume(i, scaled); - } -} - -int MFPlayerSession::bufferStatus() -{ - if (!m_netsourceStatistics) - return 0; - PROPVARIANT var; - PropVariantInit(&var); - PROPERTYKEY key; - key.fmtid = MFNETSOURCE_STATISTICS; - key.pid = MFNETSOURCE_BUFFERPROGRESS_ID; - int progress = -1; - // GetValue returns S_FALSE if the property is not available, which has - // a value > 0. We therefore can't use the SUCCEEDED macro here. - if (m_netsourceStatistics->GetValue(key, &var) == S_OK) { - progress = var.lVal; - PropVariantClear(&var); - } - -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "bufferStatus: progress = " << progress; -#endif - - return progress; -} - -QMediaTimeRange MFPlayerSession::availablePlaybackRanges() -{ - // defaults to the whole media - qint64 start = 0; - qint64 end = qint64(m_duration / 10000); - - if (m_netsourceStatistics) { - PROPVARIANT var; - PropVariantInit(&var); - PROPERTYKEY key; - key.fmtid = MFNETSOURCE_STATISTICS; - key.pid = MFNETSOURCE_SEEKRANGESTART_ID; - // GetValue returns S_FALSE if the property is not available, which has - // a value > 0. We therefore can't use the SUCCEEDED macro here. - if (m_netsourceStatistics->GetValue(key, &var) == S_OK) { - start = qint64(var.uhVal.QuadPart / 10000); - PropVariantClear(&var); - PropVariantInit(&var); - key.pid = MFNETSOURCE_SEEKRANGEEND_ID; - if (m_netsourceStatistics->GetValue(key, &var) == S_OK) { - end = qint64(var.uhVal.QuadPart / 10000); - PropVariantClear(&var); - } - } - } - - return QMediaTimeRange(start, end); -} - -HRESULT MFPlayerSession::QueryInterface(REFIID riid, void** ppvObject) -{ - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFAsyncCallback) { - *ppvObject = static_cast<IMFAsyncCallback*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - return S_OK; -} - -ULONG MFPlayerSession::AddRef(void) -{ - return InterlockedIncrement(&m_cRef); -} - -ULONG MFPlayerSession::Release(void) -{ - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - this->deleteLater(); - return cRef; -} - -HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult) -{ - if (pResult->GetStateNoAddRef() != m_session) - return S_OK; - - IMFMediaEvent *pEvent = NULL; - // Get the event from the event queue. - HRESULT hr = m_session->EndGetEvent(pResult, &pEvent); - if (FAILED(hr)) { - return S_OK; - } - - MediaEventType meType = MEUnknown; - hr = pEvent->GetType(&meType); - if (FAILED(hr)) { - pEvent->Release(); - return S_OK; - } - - if (meType == MESessionClosed) { - SetEvent(m_hCloseEvent); - pEvent->Release(); - return S_OK; - } else { - hr = m_session->BeginGetEvent(this, m_session); - if (FAILED(hr)) { - pEvent->Release(); - return S_OK; - } - } - - if (!m_closing) { - emit sessionEvent(pEvent); - } else { - pEvent->Release(); - } - return S_OK; -} - -void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent) -{ - HRESULT hrStatus = S_OK; - HRESULT hr = sessionEvent->GetStatus(&hrStatus); - if (FAILED(hr) || !m_session) { - sessionEvent->Release(); - return; - } - - MediaEventType meType = MEUnknown; - hr = sessionEvent->GetType(&meType); - -#ifdef DEBUG_MEDIAFOUNDATION - if (FAILED(hrStatus)) - qDebug() << "handleSessionEvent: MediaEventType = " << meType << "Failed"; - else - qDebug() << "handleSessionEvent: MediaEventType = " << meType; -#endif - - switch (meType) { - case MENonFatalError: { - PROPVARIANT var; - PropVariantInit(&var); - sessionEvent->GetValue(&var); - qWarning() << "handleSessionEvent: non fatal error = " << var.ulVal; - PropVariantClear(&var); - emit error(QMediaPlayer::ResourceError, tr("Media session non-fatal error."), false); - } - break; - case MESourceUnknown: - changeStatus(QMediaPlayer::InvalidMedia); - break; - case MEError: - changeStatus(QMediaPlayer::UnknownMediaStatus); - qWarning() << "handleSessionEvent: serious error = " << hrStatus; - emit error(QMediaPlayer::ResourceError, tr("Media session serious error."), true); - break; - case MESessionRateChanged: - // If the rate change succeeded, we've already got the rate - // cached. If it failed, try to get the actual rate. - if (FAILED(hrStatus)) { - PROPVARIANT var; - PropVariantInit(&var); - if (SUCCEEDED(sessionEvent->GetValue(&var)) && (var.vt == VT_R4)) { - m_state.rate = var.fltVal; - } - emit playbackRateChanged(playbackRate()); - } - break; - case MESessionScrubSampleComplete : - if (m_scrubbing) - updatePendingCommands(CmdStart); - break; - case MESessionStarted: - if (m_status == QMediaPlayer::EndOfMedia - || m_status == QMediaPlayer::LoadedMedia) { - // If the session started, then enough data is buffered to play - changeStatus(QMediaPlayer::BufferedMedia); - } - - updatePendingCommands(CmdStart); - // playback started, we can now set again the procAmpValues if they have been - // changed previously (these are lost when loading a new media) - if (m_playerService->videoWindowControl()) { - m_playerService->videoWindowControl()->applyImageControls(); - } - break; - case MESessionStopped: - if (m_status != QMediaPlayer::EndOfMedia) { - m_varStart.vt = VT_I8; - m_varStart.hVal.QuadPart = 0; - - // Reset to Loaded status unless we are loading a new media - // or changing the playback rate to negative values (stop required) - if (m_status != QMediaPlayer::LoadingMedia && m_request.command != CmdSeekResume) - changeStatus(QMediaPlayer::LoadedMedia); - } - updatePendingCommands(CmdStop); - break; - case MESessionPaused: - updatePendingCommands(CmdPause); - break; - case MEReconnectStart: -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MEReconnectStart" << ((hrStatus == S_OK) ? "OK" : "Failed"); -#endif - break; - case MEReconnectEnd: -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MEReconnectEnd" << ((hrStatus == S_OK) ? "OK" : "Failed"); -#endif - break; - case MESessionTopologySet: - if (FAILED(hrStatus)) { - changeStatus(QMediaPlayer::InvalidMedia); - emit error(QMediaPlayer::FormatError, tr("Unsupported media, a codec is missing."), true); - } else { - if (m_audioSampleGrabberNode) { - IUnknown *obj = 0; - if (SUCCEEDED(m_audioSampleGrabberNode->GetObject(&obj))) { - IMFStreamSink *streamSink = 0; - if (SUCCEEDED(obj->QueryInterface(IID_PPV_ARGS(&streamSink)))) { - IMFMediaTypeHandler *typeHandler = 0; - if (SUCCEEDED(streamSink->GetMediaTypeHandler((&typeHandler)))) { - IMFMediaType *mediaType = 0; - if (SUCCEEDED(typeHandler->GetCurrentMediaType(&mediaType))) { - m_audioSampleGrabber->setFormat(audioFormatForMFMediaType(mediaType)); - mediaType->Release(); - } - typeHandler->Release(); - } - streamSink->Release(); - } - obj->Release(); - } - } - - // Topology is resolved and successfuly set, this happens only after loading a new media. - // Make sure we always start the media from the beginning - m_varStart.vt = VT_I8; - m_varStart.hVal.QuadPart = 0; - - changeStatus(QMediaPlayer::LoadedMedia); - } - break; - } - - if (FAILED(hrStatus)) { - sessionEvent->Release(); - return; - } - - switch (meType) { - case MEBufferingStarted: - changeStatus(QMediaPlayer::StalledMedia); - emit bufferStatusChanged(bufferStatus()); - break; - case MEBufferingStopped: - changeStatus(QMediaPlayer::BufferedMedia); - emit bufferStatusChanged(bufferStatus()); - break; - case MESessionEnded: - m_pendingState = NoPending; - m_state.command = CmdStop; - m_state.prevCmd = CmdNone; - m_request.command = CmdNone; - m_request.prevCmd = CmdNone; - - m_varStart.vt = VT_I8; - //keep reporting the final position after end of media - m_varStart.hVal.QuadPart = m_duration; - emit positionChanged(position()); - - changeStatus(QMediaPlayer::EndOfMedia); - break; - case MEEndOfPresentationSegment: - break; - case MESessionTopologyStatus: { - UINT32 status; - if (SUCCEEDED(sessionEvent->GetUINT32(MF_EVENT_TOPOLOGY_STATUS, &status))) { - if (status == MF_TOPOSTATUS_READY) { - IMFClock* clock; - if (SUCCEEDED(m_session->GetClock(&clock))) { - clock->QueryInterface(IID_IMFPresentationClock, (void**)(&m_presentationClock)); - clock->Release(); - } - - if (SUCCEEDED(MFGetService(m_session, MF_RATE_CONTROL_SERVICE, IID_PPV_ARGS(&m_rateControl)))) { - if (SUCCEEDED(MFGetService(m_session, MF_RATE_CONTROL_SERVICE, IID_PPV_ARGS(&m_rateSupport)))) { - if ((m_mediaTypes & Video) == Video - && SUCCEEDED(m_rateSupport->IsRateSupported(TRUE, 0, NULL))) - m_canScrub = true; - } - BOOL isThin = FALSE; - float rate = 1; - if (SUCCEEDED(m_rateControl->GetRate(&isThin, &rate))) { - if (m_pendingRate != rate) { - m_state.rate = m_request.rate = rate; - setPlaybackRate(m_pendingRate); - } - } - } - MFGetService(m_session, MFNETSOURCE_STATISTICS_SERVICE, IID_PPV_ARGS(&m_netsourceStatistics)); - - if (SUCCEEDED(MFGetService(m_session, MR_STREAM_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl)))) - setVolumeInternal(m_muted ? 0 : m_volume); - } - } - } - break; - default: - break; - } - - sessionEvent->Release(); -} - -void MFPlayerSession::updatePendingCommands(Command command) -{ - emit positionChanged(position()); - if (m_state.command != command || m_pendingState == NoPending) - return; - - // Seek while paused completed - if (m_pendingState == SeekPending && m_state.prevCmd == CmdPause) { - m_pendingState = NoPending; - // A seek operation actually restarts playback. If scrubbing is possible, playback rate - // is set to 0.0 at this point and we just need to reset the current state to Pause. - // If scrubbing is not possible, the playback rate was not changed and we explicitly need - // to re-pause playback. - if (!canScrub()) - pause(); - else - m_state.setCommand(CmdPause); - } - - m_pendingState = NoPending; - - //First look for rate changes. - if (m_request.rate != m_state.rate) { - commitRateChange(m_request.rate, m_request.isThin); - } - - // Now look for new requests. - if (m_pendingState == NoPending) { - switch (m_request.command) { - case CmdStart: - start(); - break; - case CmdPause: - pause(); - break; - case CmdStop: - stop(); - break; - case CmdSeek: - case CmdSeekResume: - setPositionInternal(m_request.start, m_request.command); - break; - case CmdStartAndSeek: - start(); - setPositionInternal(m_request.start, m_request.command); - break; - } - m_request.setCommand(CmdNone); - } - -} - -bool MFPlayerSession::canScrub() const -{ - return m_canScrub && m_rateSupport && m_rateControl; -} - -void MFPlayerSession::clear() -{ -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MFPlayerSession::clear"; -#endif - m_mediaTypes = 0; - m_canScrub = false; - - m_pendingState = NoPending; - m_state.command = CmdStop; - m_state.prevCmd = CmdNone; - m_request.command = CmdNone; - m_request.prevCmd = CmdNone; - - if (m_presentationClock) { - m_presentationClock->Release(); - m_presentationClock = NULL; - } - if (m_rateControl) { - m_rateControl->Release(); - m_rateControl = NULL; - } - if (m_rateSupport) { - m_rateSupport->Release(); - m_rateSupport = NULL; - } - if (m_volumeControl) { - m_volumeControl->Release(); - m_volumeControl = NULL; - } - if (m_netsourceStatistics) { - m_netsourceStatistics->Release(); - m_netsourceStatistics = NULL; - } - if (m_audioSampleGrabberNode) { - m_audioSampleGrabberNode->Release(); - m_audioSampleGrabberNode = NULL; - } -} diff --git a/src/plugins/wmf/player/mfplayersession.h b/src/plugins/wmf/player/mfplayersession.h deleted file mode 100644 index 946207130..000000000 --- a/src/plugins/wmf/player/mfplayersession.h +++ /dev/null @@ -1,239 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFPLAYERSESSION_H -#define MFPLAYERSESSION_H - -#include <mfapi.h> -#include <mfidl.h> - -#include "qmediaplayer.h" -#include "qmediaservice.h" -#include "qmediatimerange.h" - -#include <QtCore/qcoreevent.h> -#include <QtCore/qmutex.h> -#include <QtCore/qurl.h> -#include <QtCore/qwaitcondition.h> -#include <QtMultimedia/qaudioformat.h> -#include <QtMultimedia/qvideosurfaceformat.h> - -QT_BEGIN_NAMESPACE -class QUrl; -QT_END_NAMESPACE - -QT_USE_NAMESPACE - -class SourceResolver; -class MFAudioEndpointControl; -class MFVideoRendererControl; -class MFPlayerControl; -class MFMetaDataControl; -class MFPlayerService; -class AudioSampleGrabberCallback; -class MFTransform; -class MFAudioProbeControl; -class MFVideoProbeControl; - -class MFPlayerSession : public QObject, public IMFAsyncCallback -{ - Q_OBJECT - friend class SourceResolver; -public: - MFPlayerSession(MFPlayerService *playerService = 0); - ~MFPlayerSession(); - - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); - - STDMETHODIMP_(ULONG) AddRef(void); - - STDMETHODIMP_(ULONG) Release(void); - - STDMETHODIMP Invoke(IMFAsyncResult *pResult); - - STDMETHODIMP GetParameters(DWORD *pdwFlags, DWORD *pdwQueue) - { - Q_UNUSED(pdwFlags); - Q_UNUSED(pdwQueue); - return E_NOTIMPL; - } - - void load(const QUrl &media, QIODevice *stream); - void stop(bool immediate = false); - void start(); - void pause(); - - QMediaPlayer::MediaStatus status() const; - qint64 position(); - void setPosition(qint64 position); - qreal playbackRate() const; - void setPlaybackRate(qreal rate); - int volume() const; - void setVolume(int volume); - bool isMuted() const; - void setMuted(bool muted); - int bufferStatus(); - QMediaTimeRange availablePlaybackRanges(); - - void changeStatus(QMediaPlayer::MediaStatus newStatus); - - void close(); - - void addProbe(MFAudioProbeControl* probe); - void removeProbe(MFAudioProbeControl* probe); - void addProbe(MFVideoProbeControl* probe); - void removeProbe(MFVideoProbeControl* probe); - -Q_SIGNALS: - void error(QMediaPlayer::Error error, QString errorString, bool isFatal); - void sessionEvent(IMFMediaEvent *sessionEvent); - void statusChanged(); - void audioAvailable(); - void videoAvailable(); - void durationUpdate(qint64 duration); - void seekableUpdate(bool seekable); - void positionChanged(qint64 position); - void playbackRateChanged(qreal rate); - void volumeChanged(int volume); - void mutedChanged(bool muted); - void bufferStatusChanged(int percentFilled); - -private Q_SLOTS: - void handleMediaSourceReady(); - void handleSessionEvent(IMFMediaEvent *sessionEvent); - void handleSourceError(long hr); - -private: - long m_cRef; - MFPlayerService *m_playerService; - IMFMediaSession *m_session; - IMFPresentationClock *m_presentationClock; - IMFRateControl *m_rateControl; - IMFRateSupport *m_rateSupport; - IMFAudioStreamVolume *m_volumeControl; - IPropertyStore *m_netsourceStatistics; - PROPVARIANT m_varStart; - UINT64 m_duration; - - enum Command - { - CmdNone = 0, - CmdStop, - CmdStart, - CmdPause, - CmdSeek, - CmdSeekResume, - CmdStartAndSeek - }; - - void clear(); - void setPositionInternal(qint64 position, Command requestCmd); - void setPlaybackRateInternal(qreal rate); - void commitRateChange(qreal rate, BOOL isThin); - bool canScrub() const; - void scrub(bool enableScrub); - bool m_scrubbing; - float m_restoreRate; - - SourceResolver *m_sourceResolver; - HANDLE m_hCloseEvent; - bool m_closing; - - enum MediaType - { - Unknown = 0, - Audio = 1, - Video = 2, - }; - DWORD m_mediaTypes; - - enum PendingState - { - NoPending = 0, - CmdPending, - SeekPending, - }; - - struct SeekState - { - void setCommand(Command cmd) { - prevCmd = command; - command = cmd; - } - Command command; - Command prevCmd; - float rate; // Playback rate - BOOL isThin; // Thinned playback? - qint64 start; // Start position - }; - SeekState m_state; // Current nominal state. - SeekState m_request; // Pending request. - PendingState m_pendingState; - float m_pendingRate; - void updatePendingCommands(Command command); - - QMediaPlayer::MediaStatus m_status; - bool m_canScrub; - int m_volume; - bool m_muted; - - void setVolumeInternal(int volume); - - void createSession(); - void setupPlaybackTopology(IMFMediaSource *source, IMFPresentationDescriptor *sourcePD); - MediaType getStreamType(IMFStreamDescriptor *stream) const; - IMFTopologyNode* addSourceNode(IMFTopology* topology, IMFMediaSource* source, - IMFPresentationDescriptor* presentationDesc, IMFStreamDescriptor *streamDesc); - IMFTopologyNode* addOutputNode(MediaType mediaType, IMFTopology* topology, DWORD sinkID); - - bool addAudioSampleGrabberNode(IMFTopology* topology); - bool setupAudioSampleGrabber(IMFTopology *topology, IMFTopologyNode *sourceNode, IMFTopologyNode *outputNode); - QAudioFormat audioFormatForMFMediaType(IMFMediaType *mediaType) const; - AudioSampleGrabberCallback *m_audioSampleGrabber; - IMFTopologyNode *m_audioSampleGrabberNode; - - IMFTopology *insertMFT(IMFTopology *topology, TOPOID outputNodeId); - bool insertResizer(IMFTopology *topology); - void insertColorConverter(IMFTopology *topology, TOPOID outputNodeId); - MFTransform *m_videoProbeMFT; - QList<MFVideoProbeControl*> m_videoProbes; -}; - - -#endif diff --git a/src/plugins/wmf/player/mftvideo.cpp b/src/plugins/wmf/player/mftvideo.cpp deleted file mode 100644 index 9dce654f2..000000000 --- a/src/plugins/wmf/player/mftvideo.cpp +++ /dev/null @@ -1,753 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mftvideo.h" -#include "mfvideoprobecontrol.h" -#include <private/qmemoryvideobuffer_p.h> -#include <mferror.h> -#include <strmif.h> -#include <uuids.h> -#include <InitGuid.h> -#include <d3d9.h> -#include <qdebug.h> - -// This MFT sends all samples it processes to connected video probes. -// Sample is sent to probes in ProcessInput. -// In ProcessOutput this MFT simply returns the original sample. - -// The implementation is based on a boilerplate from the MF SDK example. - -MFTransform::MFTransform(): - m_cRef(1), - m_inputType(0), - m_outputType(0), - m_sample(0), - m_videoSinkTypeHandler(0), - m_bytesPerLine(0) -{ -} - -MFTransform::~MFTransform() -{ - if (m_inputType) - m_inputType->Release(); - - if (m_outputType) - m_outputType->Release(); - - if (m_videoSinkTypeHandler) - m_videoSinkTypeHandler->Release(); -} - -void MFTransform::addProbe(MFVideoProbeControl *probe) -{ - QMutexLocker locker(&m_videoProbeMutex); - - if (m_videoProbes.contains(probe)) - return; - - m_videoProbes.append(probe); -} - -void MFTransform::removeProbe(MFVideoProbeControl *probe) -{ - QMutexLocker locker(&m_videoProbeMutex); - m_videoProbes.removeOne(probe); -} - -void MFTransform::setVideoSink(IUnknown *videoSink) -{ - // This transform supports the same input types as the video sink. - // Store its type handler interface in order to report the correct supported types. - - if (m_videoSinkTypeHandler) { - m_videoSinkTypeHandler->Release(); - m_videoSinkTypeHandler = NULL; - } - - if (videoSink) - videoSink->QueryInterface(IID_PPV_ARGS(&m_videoSinkTypeHandler)); -} - -STDMETHODIMP MFTransform::QueryInterface(REFIID riid, void** ppv) -{ - if (!ppv) - return E_POINTER; - if (riid == IID_IMFTransform) { - *ppv = static_cast<IMFTransform*>(this); - } else if (riid == IID_IUnknown) { - *ppv = static_cast<IUnknown*>(this); - } else { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -STDMETHODIMP_(ULONG) MFTransform::AddRef() -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) MFTransform::Release() -{ - ULONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) { - delete this; - } - return cRef; -} - -STDMETHODIMP MFTransform::GetStreamLimits(DWORD *pdwInputMinimum, DWORD *pdwInputMaximum, DWORD *pdwOutputMinimum, DWORD *pdwOutputMaximum) -{ - if (!pdwInputMinimum || !pdwInputMaximum || !pdwOutputMinimum || !pdwOutputMaximum) - return E_POINTER; - *pdwInputMinimum = 1; - *pdwInputMaximum = 1; - *pdwOutputMinimum = 1; - *pdwOutputMaximum = 1; - return S_OK; -} - -STDMETHODIMP MFTransform::GetStreamCount(DWORD *pcInputStreams, DWORD *pcOutputStreams) -{ - if (!pcInputStreams || !pcOutputStreams) - return E_POINTER; - - *pcInputStreams = 1; - *pcOutputStreams = 1; - return S_OK; -} - -STDMETHODIMP MFTransform::GetStreamIDs(DWORD dwInputIDArraySize, DWORD *pdwInputIDs, DWORD dwOutputIDArraySize, DWORD *pdwOutputIDs) -{ - // streams are numbered consecutively - Q_UNUSED(dwInputIDArraySize); - Q_UNUSED(pdwInputIDs); - Q_UNUSED(dwOutputIDArraySize); - Q_UNUSED(pdwOutputIDs); - return E_NOTIMPL; -} - -STDMETHODIMP MFTransform::GetInputStreamInfo(DWORD dwInputStreamID, MFT_INPUT_STREAM_INFO *pStreamInfo) -{ - QMutexLocker locker(&m_mutex); - - if (dwInputStreamID > 0) - return MF_E_INVALIDSTREAMNUMBER; - - if (!pStreamInfo) - return E_POINTER; - - pStreamInfo->cbSize = 0; - pStreamInfo->hnsMaxLatency = 0; - pStreamInfo->cbMaxLookahead = 0; - pStreamInfo->cbAlignment = 0; - pStreamInfo->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES - | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER - | MFT_INPUT_STREAM_PROCESSES_IN_PLACE; - - return S_OK; -} - -STDMETHODIMP MFTransform::GetOutputStreamInfo(DWORD dwOutputStreamID, MFT_OUTPUT_STREAM_INFO *pStreamInfo) -{ - QMutexLocker locker(&m_mutex); - - if (dwOutputStreamID > 0) - return MF_E_INVALIDSTREAMNUMBER; - - if (!pStreamInfo) - return E_POINTER; - - pStreamInfo->cbSize = 0; - pStreamInfo->cbAlignment = 0; - pStreamInfo->dwFlags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES - | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER - | MFT_OUTPUT_STREAM_PROVIDES_SAMPLES - | MFT_OUTPUT_STREAM_DISCARDABLE; - - return S_OK; -} - -STDMETHODIMP MFTransform::GetAttributes(IMFAttributes **pAttributes) -{ - // This MFT does not support attributes. - Q_UNUSED(pAttributes); - return E_NOTIMPL; -} - -STDMETHODIMP MFTransform::GetInputStreamAttributes(DWORD dwInputStreamID, IMFAttributes **pAttributes) -{ - // This MFT does not support input stream attributes. - Q_UNUSED(dwInputStreamID); - Q_UNUSED(pAttributes); - return E_NOTIMPL; -} - -STDMETHODIMP MFTransform::GetOutputStreamAttributes(DWORD dwOutputStreamID, IMFAttributes **pAttributes) -{ - // This MFT does not support output stream attributes. - Q_UNUSED(dwOutputStreamID); - Q_UNUSED(pAttributes); - return E_NOTIMPL; -} - -STDMETHODIMP MFTransform::DeleteInputStream(DWORD dwStreamID) -{ - // This MFT has a fixed number of input streams. - Q_UNUSED(dwStreamID); - return E_NOTIMPL; -} - -STDMETHODIMP MFTransform::AddInputStreams(DWORD cStreams, DWORD *adwStreamIDs) -{ - // This MFT has a fixed number of input streams. - Q_UNUSED(cStreams); - Q_UNUSED(adwStreamIDs); - return E_NOTIMPL; -} - -STDMETHODIMP MFTransform::GetInputAvailableType(DWORD dwInputStreamID, DWORD dwTypeIndex, IMFMediaType **ppType) -{ - // We support the same input types as the video sink - if (!m_videoSinkTypeHandler) - return E_NOTIMPL; - - if (dwInputStreamID > 0) - return MF_E_INVALIDSTREAMNUMBER; - - if (!ppType) - return E_POINTER; - - return m_videoSinkTypeHandler->GetMediaTypeByIndex(dwTypeIndex, ppType); -} - -STDMETHODIMP MFTransform::GetOutputAvailableType(DWORD dwOutputStreamID, DWORD dwTypeIndex, IMFMediaType **ppType) -{ - // Since we don't modify the samples, the output type must be the same as the input type. - // Report our input type as the only available output type. - - if (dwOutputStreamID > 0) - return MF_E_INVALIDSTREAMNUMBER; - - if (!ppType) - return E_POINTER; - - // Input type must be set first - if (!m_inputType) - return MF_E_TRANSFORM_TYPE_NOT_SET; - - if (dwTypeIndex > 0) - return MF_E_NO_MORE_TYPES; - - // Return a copy to make sure our type is not modified - if (FAILED(MFCreateMediaType(ppType))) - return E_OUTOFMEMORY; - - return m_inputType->CopyAllItems(*ppType); -} - -STDMETHODIMP MFTransform::SetInputType(DWORD dwInputStreamID, IMFMediaType *pType, DWORD dwFlags) -{ - if (dwInputStreamID > 0) - return MF_E_INVALIDSTREAMNUMBER; - - QMutexLocker locker(&m_mutex); - - if (m_sample) - return MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING; - - if (!isMediaTypeSupported(pType)) - return MF_E_INVALIDMEDIATYPE; - - if (dwFlags == MFT_SET_TYPE_TEST_ONLY) - return pType ? S_OK : E_POINTER; - - if (m_inputType) { - m_inputType->Release(); - // Input type has changed, discard output type (if it's set) so it's reset later on - DWORD flags = 0; - if (m_outputType && m_outputType->IsEqual(pType, &flags) != S_OK) { - m_outputType->Release(); - m_outputType = 0; - } - } - - m_inputType = pType; - - if (m_inputType) - m_inputType->AddRef(); - - return S_OK; -} - -STDMETHODIMP MFTransform::SetOutputType(DWORD dwOutputStreamID, IMFMediaType *pType, DWORD dwFlags) -{ - if (dwOutputStreamID > 0) - return MF_E_INVALIDSTREAMNUMBER; - - if (dwFlags == MFT_SET_TYPE_TEST_ONLY && !pType) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - - // Input type must be set first - if (!m_inputType) - return MF_E_TRANSFORM_TYPE_NOT_SET; - - if (m_sample) - return MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING; - - DWORD flags = 0; - if (pType && m_inputType->IsEqual(pType, &flags) != S_OK) - return MF_E_INVALIDMEDIATYPE; - - if (dwFlags == MFT_SET_TYPE_TEST_ONLY) - return pType ? S_OK : E_POINTER; - - if (m_outputType) - m_outputType->Release(); - - m_outputType = pType; - - if (m_outputType) { - m_outputType->AddRef(); - m_format = videoFormatForMFMediaType(m_outputType, &m_bytesPerLine); - } - - return S_OK; -} - -STDMETHODIMP MFTransform::GetInputCurrentType(DWORD dwInputStreamID, IMFMediaType **ppType) -{ - if (dwInputStreamID > 0) - return MF_E_INVALIDSTREAMNUMBER; - - if (ppType == NULL) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - - if (!m_inputType) - return MF_E_TRANSFORM_TYPE_NOT_SET; - - // Return a copy to make sure our type is not modified - if (FAILED(MFCreateMediaType(ppType))) - return E_OUTOFMEMORY; - - return m_inputType->CopyAllItems(*ppType); -} - -STDMETHODIMP MFTransform::GetOutputCurrentType(DWORD dwOutputStreamID, IMFMediaType **ppType) -{ - if (dwOutputStreamID > 0) - return MF_E_INVALIDSTREAMNUMBER; - - if (ppType == NULL) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - - if (!m_outputType) - return MF_E_TRANSFORM_TYPE_NOT_SET; - - // Return a copy to make sure our type is not modified - if (FAILED(MFCreateMediaType(ppType))) - return E_OUTOFMEMORY; - - return m_outputType->CopyAllItems(*ppType); -} - -STDMETHODIMP MFTransform::GetInputStatus(DWORD dwInputStreamID, DWORD *pdwFlags) -{ - if (dwInputStreamID > 0) - return MF_E_INVALIDSTREAMNUMBER; - - if (!pdwFlags) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - - if (!m_inputType || !m_outputType) - return MF_E_TRANSFORM_TYPE_NOT_SET; - - if (m_sample) - *pdwFlags = 0; - else - *pdwFlags = MFT_INPUT_STATUS_ACCEPT_DATA; - - return S_OK; -} - -STDMETHODIMP MFTransform::GetOutputStatus(DWORD *pdwFlags) -{ - if (!pdwFlags) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - - if (!m_inputType || !m_outputType) - return MF_E_TRANSFORM_TYPE_NOT_SET; - - if (m_sample) - *pdwFlags = MFT_OUTPUT_STATUS_SAMPLE_READY; - else - *pdwFlags = 0; - - return S_OK; -} - -STDMETHODIMP MFTransform::SetOutputBounds(LONGLONG hnsLowerBound, LONGLONG hnsUpperBound) -{ - Q_UNUSED(hnsLowerBound); - Q_UNUSED(hnsUpperBound); - return E_NOTIMPL; -} - -STDMETHODIMP MFTransform::ProcessEvent(DWORD dwInputStreamID, IMFMediaEvent *pEvent) -{ - // This MFT ignores all events, and the pipeline should send all events downstream. - Q_UNUSED(dwInputStreamID); - Q_UNUSED(pEvent); - return E_NOTIMPL; -} - -STDMETHODIMP MFTransform::ProcessMessage(MFT_MESSAGE_TYPE eMessage, ULONG_PTR ulParam) -{ - Q_UNUSED(ulParam); - - HRESULT hr = S_OK; - - switch (eMessage) - { - case MFT_MESSAGE_COMMAND_FLUSH: - hr = OnFlush(); - break; - - case MFT_MESSAGE_COMMAND_DRAIN: - // Drain: Tells the MFT not to accept any more input until - // all of the pending output has been processed. That is our - // default behevior already, so there is nothing to do. - break; - - case MFT_MESSAGE_SET_D3D_MANAGER: - // The pipeline should never send this message unless the MFT - // has the MF_SA_D3D_AWARE attribute set to TRUE. However, if we - // do get this message, it's invalid and we don't implement it. - hr = E_NOTIMPL; - break; - - // The remaining messages do not require any action from this MFT. - case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING: - case MFT_MESSAGE_NOTIFY_END_STREAMING: - case MFT_MESSAGE_NOTIFY_END_OF_STREAM: - case MFT_MESSAGE_NOTIFY_START_OF_STREAM: - break; - } - - return hr; -} - -STDMETHODIMP MFTransform::ProcessInput(DWORD dwInputStreamID, IMFSample *pSample, DWORD dwFlags) -{ - if (dwInputStreamID > 0) - return MF_E_INVALIDSTREAMNUMBER; - - if (dwFlags != 0) - return E_INVALIDARG; // dwFlags is reserved and must be zero. - - QMutexLocker locker(&m_mutex); - - if (!m_inputType) - return MF_E_TRANSFORM_TYPE_NOT_SET; - - if (m_sample) - return MF_E_NOTACCEPTING; - - // Validate the number of buffers. There should only be a single buffer to hold the video frame. - DWORD dwBufferCount = 0; - HRESULT hr = pSample->GetBufferCount(&dwBufferCount); - if (FAILED(hr)) - return hr; - - if (dwBufferCount == 0) - return E_FAIL; - - if (dwBufferCount > 1) - return MF_E_SAMPLE_HAS_TOO_MANY_BUFFERS; - - m_sample = pSample; - m_sample->AddRef(); - - QMutexLocker lockerProbe(&m_videoProbeMutex); - - if (!m_videoProbes.isEmpty()) { - QVideoFrame frame = makeVideoFrame(); - - for (MFVideoProbeControl* probe : qAsConst(m_videoProbes)) - probe->bufferProbed(frame); - } - - return S_OK; -} - -STDMETHODIMP MFTransform::ProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount, MFT_OUTPUT_DATA_BUFFER *pOutputSamples, DWORD *pdwStatus) -{ - if (pOutputSamples == NULL || pdwStatus == NULL) - return E_POINTER; - - if (cOutputBufferCount != 1) - return E_INVALIDARG; - - QMutexLocker locker(&m_mutex); - - if (!m_inputType) - return MF_E_TRANSFORM_TYPE_NOT_SET; - - if (!m_outputType) { - pOutputSamples[0].dwStatus = MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE; - return MF_E_TRANSFORM_STREAM_CHANGE; - } - - IMFMediaBuffer *input = NULL; - IMFMediaBuffer *output = NULL; - - if (dwFlags == MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER) - goto done; - else if (dwFlags != 0) - return E_INVALIDARG; - - if (!m_sample) - return MF_E_TRANSFORM_NEED_MORE_INPUT; - - // Since the MFT_OUTPUT_STREAM_PROVIDES_SAMPLES flag is set, the client - // should not be providing samples here - if (pOutputSamples[0].pSample != NULL) - return E_INVALIDARG; - - pOutputSamples[0].pSample = m_sample; - pOutputSamples[0].pSample->AddRef(); - - // Send video frame to probes - // We do it here (instead of inside ProcessInput) to make sure samples discarded by the renderer - // are not sent. - m_videoProbeMutex.lock(); - if (!m_videoProbes.isEmpty()) { - QVideoFrame frame = makeVideoFrame(); - - for (MFVideoProbeControl* probe : qAsConst(m_videoProbes)) - probe->bufferProbed(frame); - } - m_videoProbeMutex.unlock(); - -done: - pOutputSamples[0].dwStatus = 0; - *pdwStatus = 0; - - m_sample->Release(); - m_sample = 0; - - if (input) - input->Release(); - if (output) - output->Release(); - - return S_OK; -} - -HRESULT MFTransform::OnFlush() -{ - QMutexLocker locker(&m_mutex); - - if (m_sample) { - m_sample->Release(); - m_sample = 0; - } - return S_OK; -} - -QVideoFrame::PixelFormat MFTransform::formatFromSubtype(const GUID& subtype) -{ - if (subtype == MFVideoFormat_ARGB32) - return QVideoFrame::Format_ARGB32; - else if (subtype == MFVideoFormat_RGB32) - return QVideoFrame::Format_RGB32; - else if (subtype == MFVideoFormat_RGB24) - return QVideoFrame::Format_RGB24; - else if (subtype == MFVideoFormat_RGB565) - return QVideoFrame::Format_RGB565; - else if (subtype == MFVideoFormat_RGB555) - return QVideoFrame::Format_RGB555; - else if (subtype == MFVideoFormat_AYUV) - return QVideoFrame::Format_AYUV444; - else if (subtype == MFVideoFormat_I420) - return QVideoFrame::Format_YUV420P; - else if (subtype == MFVideoFormat_UYVY) - return QVideoFrame::Format_UYVY; - else if (subtype == MFVideoFormat_YV12) - return QVideoFrame::Format_YV12; - else if (subtype == MFVideoFormat_NV12) - return QVideoFrame::Format_NV12; - - return QVideoFrame::Format_Invalid; -} - -QVideoSurfaceFormat MFTransform::videoFormatForMFMediaType(IMFMediaType *mediaType, int *bytesPerLine) -{ - UINT32 stride; - if (FAILED(mediaType->GetUINT32(MF_MT_DEFAULT_STRIDE, &stride))) { - *bytesPerLine = 0; - return QVideoSurfaceFormat(); - } - - *bytesPerLine = (int)stride; - - QSize size; - UINT32 width, height; - if (FAILED(MFGetAttributeSize(mediaType, MF_MT_FRAME_SIZE, &width, &height))) - return QVideoSurfaceFormat(); - - size.setWidth(width); - size.setHeight(height); - - GUID subtype = GUID_NULL; - if (FAILED(mediaType->GetGUID(MF_MT_SUBTYPE, &subtype))) - return QVideoSurfaceFormat(); - - QVideoFrame::PixelFormat pixelFormat = formatFromSubtype(subtype); - QVideoSurfaceFormat format(size, pixelFormat); - - UINT32 num, den; - if (SUCCEEDED(MFGetAttributeRatio(mediaType, MF_MT_PIXEL_ASPECT_RATIO, &num, &den))) { - format.setPixelAspectRatio(num, den); - } - if (SUCCEEDED(MFGetAttributeRatio(mediaType, MF_MT_FRAME_RATE, &num, &den))) { - format.setFrameRate(qreal(num)/den); - } - - return format; -} - -QVideoFrame MFTransform::makeVideoFrame() -{ - QVideoFrame frame; - - if (!m_format.isValid()) - return frame; - - IMFMediaBuffer *buffer = 0; - - do { - if (FAILED(m_sample->ConvertToContiguousBuffer(&buffer))) - break; - - QByteArray array = dataFromBuffer(buffer, m_format.frameHeight(), &m_bytesPerLine); - if (array.isEmpty()) - break; - - // Wrapping IMFSample or IMFMediaBuffer in a QVideoFrame is not possible because we cannot hold - // IMFSample for a "long" time without affecting the rest of the topology. - // If IMFSample is held for more than 5 frames decoder starts to reuse it even though it hasn't been released it yet. - // That is why we copy data from IMFMediaBuffer here. - frame = QVideoFrame(new QMemoryVideoBuffer(array, m_bytesPerLine), m_format.frameSize(), m_format.pixelFormat()); - - // WMF uses 100-nanosecond units, Qt uses microseconds - LONGLONG startTime = -1; - if (SUCCEEDED(m_sample->GetSampleTime(&startTime))) { - frame.setStartTime(startTime * 0.1); - - LONGLONG duration = -1; - if (SUCCEEDED(m_sample->GetSampleDuration(&duration))) - frame.setEndTime((startTime + duration) * 0.1); - } - } while (false); - - if (buffer) - buffer->Release(); - - return frame; -} - -QByteArray MFTransform::dataFromBuffer(IMFMediaBuffer *buffer, int height, int *bytesPerLine) -{ - QByteArray array; - BYTE *bytes; - DWORD length; - HRESULT hr = buffer->Lock(&bytes, NULL, &length); - if (SUCCEEDED(hr)) { - array = QByteArray((const char *)bytes, (int)length); - buffer->Unlock(); - } else { - // try to lock as Direct3DSurface - IDirect3DSurface9 *surface = 0; - do { - if (FAILED(MFGetService(buffer, MR_BUFFER_SERVICE, IID_IDirect3DSurface9, (void**)&surface))) - break; - - D3DLOCKED_RECT rect; - if (FAILED(surface->LockRect(&rect, NULL, D3DLOCK_READONLY))) - break; - - if (bytesPerLine) - *bytesPerLine = (int)rect.Pitch; - - array = QByteArray((const char *)rect.pBits, rect.Pitch * height); - surface->UnlockRect(); - } while (false); - - if (surface) { - surface->Release(); - surface = 0; - } - } - - return array; -} - -bool MFTransform::isMediaTypeSupported(IMFMediaType *type) -{ - // If we don't have the video sink's type handler, - // assume it supports anything... - if (!m_videoSinkTypeHandler || !type) - return true; - - return m_videoSinkTypeHandler->IsMediaTypeSupported(type, NULL) == S_OK; -} diff --git a/src/plugins/wmf/player/mftvideo.h b/src/plugins/wmf/player/mftvideo.h deleted file mode 100644 index ffcb80b32..000000000 --- a/src/plugins/wmf/player/mftvideo.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFTRANSFORM_H -#define MFTRANSFORM_H - -#include <mfapi.h> -#include <mfidl.h> -#include <QtCore/qlist.h> -#include <QtCore/qmutex.h> -#include <QtMultimedia/qvideosurfaceformat.h> - -QT_USE_NAMESPACE - -class MFVideoProbeControl; - -class MFTransform: public IMFTransform -{ -public: - MFTransform(); - ~MFTransform(); - - void addProbe(MFVideoProbeControl* probe); - void removeProbe(MFVideoProbeControl* probe); - - void setVideoSink(IUnknown *videoSink); - - // IUnknown methods - STDMETHODIMP QueryInterface(REFIID iid, void** ppv); - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); - - // IMFTransform methods - STDMETHODIMP GetStreamLimits(DWORD *pdwInputMinimum, DWORD *pdwInputMaximum, DWORD *pdwOutputMinimum, DWORD *pdwOutputMaximum); - STDMETHODIMP GetStreamCount(DWORD *pcInputStreams, DWORD *pcOutputStreams); - STDMETHODIMP GetStreamIDs(DWORD dwInputIDArraySize, DWORD *pdwInputIDs, DWORD dwOutputIDArraySize, DWORD *pdwOutputIDs); - STDMETHODIMP GetInputStreamInfo(DWORD dwInputStreamID, MFT_INPUT_STREAM_INFO *pStreamInfo); - STDMETHODIMP GetOutputStreamInfo(DWORD dwOutputStreamID, MFT_OUTPUT_STREAM_INFO *pStreamInfo); - STDMETHODIMP GetAttributes(IMFAttributes **pAttributes); - STDMETHODIMP GetInputStreamAttributes(DWORD dwInputStreamID, IMFAttributes **pAttributes); - STDMETHODIMP GetOutputStreamAttributes(DWORD dwOutputStreamID, IMFAttributes **pAttributes); - STDMETHODIMP DeleteInputStream(DWORD dwStreamID); - STDMETHODIMP AddInputStreams(DWORD cStreams, DWORD *adwStreamIDs); - STDMETHODIMP GetInputAvailableType(DWORD dwInputStreamID, DWORD dwTypeIndex, IMFMediaType **ppType); - STDMETHODIMP GetOutputAvailableType(DWORD dwOutputStreamID,DWORD dwTypeIndex, IMFMediaType **ppType); - STDMETHODIMP SetInputType(DWORD dwInputStreamID, IMFMediaType *pType, DWORD dwFlags); - STDMETHODIMP SetOutputType(DWORD dwOutputStreamID, IMFMediaType *pType, DWORD dwFlags); - STDMETHODIMP GetInputCurrentType(DWORD dwInputStreamID, IMFMediaType **ppType); - STDMETHODIMP GetOutputCurrentType(DWORD dwOutputStreamID, IMFMediaType **ppType); - STDMETHODIMP GetInputStatus(DWORD dwInputStreamID, DWORD *pdwFlags); - STDMETHODIMP GetOutputStatus(DWORD *pdwFlags); - STDMETHODIMP SetOutputBounds(LONGLONG hnsLowerBound, LONGLONG hnsUpperBound); - STDMETHODIMP ProcessEvent(DWORD dwInputStreamID, IMFMediaEvent *pEvent); - STDMETHODIMP ProcessMessage(MFT_MESSAGE_TYPE eMessage, ULONG_PTR ulParam); - STDMETHODIMP ProcessInput(DWORD dwInputStreamID, IMFSample *pSample, DWORD dwFlags); - STDMETHODIMP ProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount, MFT_OUTPUT_DATA_BUFFER *pOutputSamples, DWORD *pdwStatus); - -private: - HRESULT OnFlush(); - static QVideoFrame::PixelFormat formatFromSubtype(const GUID& subtype); - static QVideoSurfaceFormat videoFormatForMFMediaType(IMFMediaType *mediaType, int *bytesPerLine); - QVideoFrame makeVideoFrame(); - QByteArray dataFromBuffer(IMFMediaBuffer *buffer, int height, int *bytesPerLine); - bool isMediaTypeSupported(IMFMediaType *type); - - long m_cRef; - IMFMediaType *m_inputType; - IMFMediaType *m_outputType; - IMFSample *m_sample; - QMutex m_mutex; - - IMFMediaTypeHandler *m_videoSinkTypeHandler; - - QList<MFVideoProbeControl*> m_videoProbes; - QMutex m_videoProbeMutex; - - QVideoSurfaceFormat m_format; - int m_bytesPerLine; -}; - -#endif diff --git a/src/plugins/wmf/player/mfvideoprobecontrol.cpp b/src/plugins/wmf/player/mfvideoprobecontrol.cpp deleted file mode 100644 index 13d9a1bfe..000000000 --- a/src/plugins/wmf/player/mfvideoprobecontrol.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfvideoprobecontrol.h" - -MFVideoProbeControl::MFVideoProbeControl(QObject *parent) - : QMediaVideoProbeControl(parent) -{ -} - -MFVideoProbeControl::~MFVideoProbeControl() -{ -} - -void MFVideoProbeControl::bufferProbed(const QVideoFrame& frame) -{ - QMetaObject::invokeMethod(this, "videoFrameProbed", Qt::QueuedConnection, Q_ARG(QVideoFrame, frame)); -} diff --git a/src/plugins/wmf/player/mfvideoprobecontrol.h b/src/plugins/wmf/player/mfvideoprobecontrol.h deleted file mode 100644 index 2b238725a..000000000 --- a/src/plugins/wmf/player/mfvideoprobecontrol.h +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFVIDEOPROBECONTROL_H -#define MFVIDEOPROBECONTROL_H - -#include <qmediavideoprobecontrol.h> -#include <QtCore/qmutex.h> -#include <qvideoframe.h> - -QT_USE_NAMESPACE - -class MFVideoProbeControl : public QMediaVideoProbeControl -{ - Q_OBJECT -public: - explicit MFVideoProbeControl(QObject *parent); - virtual ~MFVideoProbeControl(); - - void bufferProbed(const QVideoFrame& frame); -}; - -#endif diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp deleted file mode 100644 index 212533009..000000000 --- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp +++ /dev/null @@ -1,2424 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfvideorenderercontrol.h" -#include "mfactivate.h" - -#include "evrcustompresenter.h" - -#include <qabstractvideosurface.h> -#include <qvideosurfaceformat.h> -#include <qtcore/qtimer.h> -#include <qtcore/qmutex.h> -#include <qtcore/qcoreevent.h> -#include <qtcore/qcoreapplication.h> -#include <qtcore/qthread.h> -#include "guiddef.h" -#include <qtcore/qdebug.h> - -//#define DEBUG_MEDIAFOUNDATION -#define PAD_TO_DWORD(x) (((x) + 3) & ~3) - -namespace -{ - class MediaSampleVideoBuffer : public QAbstractVideoBuffer - { - public: - MediaSampleVideoBuffer(IMFMediaBuffer *buffer, int bytesPerLine) - : QAbstractVideoBuffer(NoHandle) - , m_buffer(buffer) - , m_bytesPerLine(bytesPerLine) - , m_mapMode(NotMapped) - { - buffer->AddRef(); - } - - ~MediaSampleVideoBuffer() - { - m_buffer->Release(); - } - - MapData map(MapMode mode) override - { - MapData mapData; - if (m_mapMode == NotMapped && mode != NotMapped) { - BYTE *bytes; - DWORD length; - HRESULT hr = m_buffer->Lock(&bytes, NULL, &length); - if (SUCCEEDED(hr)) { - mapData.nBytes = qsizetype(length); - mapData.nPlanes = 1; - mapData.bytesPerLine[0] = m_bytesPerLine; - mapData.data[0] = reinterpret_cast<uchar *>(bytes); - m_mapMode = mode; - } else { - qWarning("Faild to lock mf buffer!"); - } - } - return mapData; - } - - void unmap() override - { - if (m_mapMode == NotMapped) - return; - m_mapMode = NotMapped; - m_buffer->Unlock(); - } - - MapMode mapMode() const override - { - return m_mapMode; - } - - private: - IMFMediaBuffer *m_buffer; - int m_bytesPerLine; - MapMode m_mapMode; - }; - - // Custom interface for handling IMFStreamSink::PlaceMarker calls asynchronously. - MIDL_INTERFACE("a3ff32de-1031-438a-8b47-82f8acda59b7") - IMarker : public IUnknown - { - virtual STDMETHODIMP GetMarkerType(MFSTREAMSINK_MARKER_TYPE *pType) = 0; - virtual STDMETHODIMP GetMarkerValue(PROPVARIANT *pvar) = 0; - virtual STDMETHODIMP GetContext(PROPVARIANT *pvar) = 0; - }; - - class Marker : public IMarker - { - public: - static HRESULT Create( - MFSTREAMSINK_MARKER_TYPE eMarkerType, - const PROPVARIANT* pvarMarkerValue, // Can be NULL. - const PROPVARIANT* pvarContextValue, // Can be NULL. - IMarker **ppMarker) - { - if (ppMarker == NULL) - return E_POINTER; - - HRESULT hr = S_OK; - Marker *pMarker = new Marker(eMarkerType); - if (pMarker == NULL) - hr = E_OUTOFMEMORY; - - // Copy the marker data. - if (SUCCEEDED(hr) && pvarMarkerValue) - hr = PropVariantCopy(&pMarker->m_varMarkerValue, pvarMarkerValue); - - if (SUCCEEDED(hr) && pvarContextValue) - hr = PropVariantCopy(&pMarker->m_varContextValue, pvarContextValue); - - if (SUCCEEDED(hr)) { - *ppMarker = pMarker; - (*ppMarker)->AddRef(); - } - - if (pMarker) - pMarker->Release(); - - return hr; - } - - // IUnknown methods. - STDMETHODIMP QueryInterface(REFIID iid, void** ppv) - { - if (!ppv) - return E_POINTER; - if (iid == IID_IUnknown) { - *ppv = static_cast<IUnknown*>(this); - } else if (iid == __uuidof(IMarker)) { - *ppv = static_cast<IMarker*>(this); - } else { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - - STDMETHODIMP_(ULONG) AddRef() - { - return InterlockedIncrement(&m_cRef); - } - - STDMETHODIMP_(ULONG) Release() - { - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - // For thread safety, return a temporary variable. - return cRef; - } - - STDMETHODIMP GetMarkerType(MFSTREAMSINK_MARKER_TYPE *pType) - { - if (pType == NULL) - return E_POINTER; - *pType = m_eMarkerType; - return S_OK; - } - - STDMETHODIMP GetMarkerValue(PROPVARIANT *pvar) - { - if (pvar == NULL) - return E_POINTER; - return PropVariantCopy(pvar, &m_varMarkerValue); - } - - STDMETHODIMP GetContext(PROPVARIANT *pvar) - { - if (pvar == NULL) - return E_POINTER; - return PropVariantCopy(pvar, &m_varContextValue); - } - - protected: - MFSTREAMSINK_MARKER_TYPE m_eMarkerType; - PROPVARIANT m_varMarkerValue; - PROPVARIANT m_varContextValue; - - private: - long m_cRef; - - Marker(MFSTREAMSINK_MARKER_TYPE eMarkerType) : m_cRef(1), m_eMarkerType(eMarkerType) - { - PropVariantInit(&m_varMarkerValue); - PropVariantInit(&m_varContextValue); - } - - virtual ~Marker() - { - PropVariantClear(&m_varMarkerValue); - PropVariantClear(&m_varContextValue); - } - }; - - class MediaStream : public QObject, public IMFStreamSink, public IMFMediaTypeHandler - { - Q_OBJECT - friend class MFVideoRendererControl; - public: - static const DWORD DEFAULT_MEDIA_STREAM_ID = 0x0; - - MediaStream(IMFMediaSink *parent, MFVideoRendererControl *rendererControl) - : m_cRef(1) - , m_eventQueue(0) - , m_shutdown(false) - , m_surface(0) - , m_state(State_TypeNotSet) - , m_currentFormatIndex(-1) - , m_bytesPerLine(0) - , m_workQueueId(0) - , m_workQueueCB(this, &MediaStream::onDispatchWorkItem) - , m_finalizeResult(0) - , m_scheduledBuffer(0) - , m_bufferStartTime(-1) - , m_bufferDuration(-1) - , m_presentationClock(0) - , m_sampleRequested(false) - , m_currentMediaType(0) - , m_prerolling(false) - , m_prerollTargetTime(0) - , m_startTime(0) - , m_rendererControl(rendererControl) - , m_rate(1.f) - { - m_sink = parent; - - if (FAILED(MFCreateEventQueue(&m_eventQueue))) - qWarning("Failed to create mf event queue!"); - if (FAILED(MFAllocateWorkQueue(&m_workQueueId))) - qWarning("Failed to allocated mf work queue!"); - } - - ~MediaStream() - { - Q_ASSERT(m_shutdown); - } - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject) - { - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFStreamSink) { - *ppvObject = static_cast<IMFStreamSink*>(this); - } else if (riid == IID_IMFMediaEventGenerator) { - *ppvObject = static_cast<IMFMediaEventGenerator*>(this); - } else if (riid == IID_IMFMediaTypeHandler) { - *ppvObject = static_cast<IMFMediaTypeHandler*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(static_cast<IMFStreamSink*>(this)); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - - STDMETHODIMP_(ULONG) AddRef(void) - { - return InterlockedIncrement(&m_cRef); - } - - STDMETHODIMP_(ULONG) Release(void) - { - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - // For thread safety, return a temporary variable. - return cRef; - } - - //from IMFMediaEventGenerator - STDMETHODIMP GetEvent( - DWORD dwFlags, - IMFMediaEvent **ppEvent) - { - // GetEvent can block indefinitely, so we don't hold the lock. - // This requires some juggling with the event queue pointer. - HRESULT hr = S_OK; - IMFMediaEventQueue *queue = NULL; - - m_mutex.lock(); - if (m_shutdown) - hr = MF_E_SHUTDOWN; - if (SUCCEEDED(hr)) { - queue = m_eventQueue; - queue->AddRef(); - } - m_mutex.unlock(); - - // Now get the event. - if (SUCCEEDED(hr)) { - hr = queue->GetEvent(dwFlags, ppEvent); - queue->Release(); - } - - return hr; - } - - STDMETHODIMP BeginGetEvent( - IMFAsyncCallback *pCallback, - IUnknown *punkState) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_eventQueue->BeginGetEvent(pCallback, punkState); - } - - STDMETHODIMP EndGetEvent( - IMFAsyncResult *pResult, - IMFMediaEvent **ppEvent) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_eventQueue->EndGetEvent(pResult, ppEvent); - } - - STDMETHODIMP QueueEvent( - MediaEventType met, - REFGUID guidExtendedType, - HRESULT hrStatus, - const PROPVARIANT *pvValue) - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::QueueEvent" << met; -#endif - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_eventQueue->QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue); - } - - //from IMFStreamSink - STDMETHODIMP GetMediaSink( - IMFMediaSink **ppMediaSink) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - else if (!ppMediaSink) - return E_INVALIDARG; - - m_sink->AddRef(); - *ppMediaSink = m_sink; - return S_OK; - } - - STDMETHODIMP GetIdentifier( - DWORD *pdwIdentifier) - { - *pdwIdentifier = MediaStream::DEFAULT_MEDIA_STREAM_ID; - return S_OK; - } - - STDMETHODIMP GetMediaTypeHandler( - IMFMediaTypeHandler **ppHandler) - { - LPVOID handler = NULL; - HRESULT hr = QueryInterface(IID_IMFMediaTypeHandler, &handler); - *ppHandler = (IMFMediaTypeHandler*)(handler); - return hr; - } - - STDMETHODIMP ProcessSample( - IMFSample *pSample) - { - if (pSample == NULL) - return E_INVALIDARG; - HRESULT hr = S_OK; - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - if (!m_prerolling) { - hr = validateOperation(OpProcessSample); - if (FAILED(hr)) - return hr; - } - - pSample->AddRef(); - m_sampleQueue.push_back(pSample); - - // Unless we are paused, start an async operation to dispatch the next sample. - if (m_state != State_Paused) - hr = queueAsyncOperation(OpProcessSample); - - return hr; - } - - STDMETHODIMP PlaceMarker( - MFSTREAMSINK_MARKER_TYPE eMarkerType, - const PROPVARIANT *pvarMarkerValue, - const PROPVARIANT *pvarContextValue) - { - HRESULT hr = S_OK; - QMutexLocker locker(&m_mutex); - IMarker *pMarker = NULL; - if (m_shutdown) - return MF_E_SHUTDOWN; - - hr = validateOperation(OpPlaceMarker); - if (FAILED(hr)) - return hr; - - // Create a marker object and put it on the sample queue. - hr = Marker::Create(eMarkerType, pvarMarkerValue, pvarContextValue, &pMarker); - if (FAILED(hr)) - return hr; - - m_sampleQueue.push_back(pMarker); - - // Unless we are paused, start an async operation to dispatch the next sample/marker. - if (m_state != State_Paused) - hr = queueAsyncOperation(OpPlaceMarker); // Increments ref count on pOp. - return hr; - } - - STDMETHODIMP Flush( void) - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::Flush"; -#endif - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - // Note: Even though we are flushing data, we still need to send - // any marker events that were queued. - clearBufferCache(); - return processSamplesFromQueue(DropSamples); - } - - //from IMFMediaTypeHandler - STDMETHODIMP IsMediaTypeSupported( - IMFMediaType *pMediaType, - IMFMediaType **ppMediaType) - { - if (ppMediaType) - *ppMediaType = NULL; - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - int index = getMediaTypeIndex(pMediaType); - if (index < 0) { - if (ppMediaType && m_mediaTypes.size() > 0) { - *ppMediaType = m_mediaTypes[0]; - (*ppMediaType)->AddRef(); - } - return MF_E_INVALIDMEDIATYPE; - } - - BOOL compressed = TRUE; - pMediaType->IsCompressedFormat(&compressed); - if (compressed) { - if (ppMediaType && (SUCCEEDED(MFCreateMediaType(ppMediaType)))) { - (*ppMediaType)->CopyAllItems(pMediaType); - (*ppMediaType)->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE); - (*ppMediaType)->SetUINT32(MF_MT_COMPRESSED, FALSE); - (*ppMediaType)->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); - } - return MF_E_INVALIDMEDIATYPE; - } - - return S_OK; - } - - STDMETHODIMP GetMediaTypeCount( - DWORD *pdwTypeCount) - { - if (pdwTypeCount == NULL) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - *pdwTypeCount = DWORD(m_mediaTypes.size()); - return S_OK; - } - - STDMETHODIMP GetMediaTypeByIndex( - DWORD dwIndex, - IMFMediaType **ppType) - { - if (ppType == NULL) - return E_INVALIDARG; - HRESULT hr = S_OK; - QMutexLocker locker(&m_mutex); - if (m_shutdown) - hr = MF_E_SHUTDOWN; - - if (SUCCEEDED(hr)) { - if (dwIndex >= DWORD(m_mediaTypes.size())) - hr = MF_E_NO_MORE_TYPES; - } - - if (SUCCEEDED(hr)) { - *ppType = m_mediaTypes[dwIndex]; - (*ppType)->AddRef(); - } - return hr; - } - - STDMETHODIMP SetCurrentMediaType( - IMFMediaType *pMediaType) - { - HRESULT hr = S_OK; - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - DWORD flag = MF_MEDIATYPE_EQUAL_MAJOR_TYPES | - MF_MEDIATYPE_EQUAL_FORMAT_TYPES | - MF_MEDIATYPE_EQUAL_FORMAT_DATA; - - if (m_currentMediaType && (m_currentMediaType->IsEqual(pMediaType, &flag) == S_OK)) - return S_OK; - - hr = validateOperation(OpSetMediaType); - - if (SUCCEEDED(hr)) { - int index = getMediaTypeIndex(pMediaType); - if (index >= 0) { - UINT64 size; - hr = pMediaType->GetUINT64(MF_MT_FRAME_SIZE, &size); - if (SUCCEEDED(hr)) { - m_currentFormatIndex = index; - int width = int(HI32(size)); - int height = int(LO32(size)); - QVideoSurfaceFormat format(QSize(width, height), m_pixelFormats[index]); - m_surfaceFormat = format; - - MFVideoArea viewport; - if (SUCCEEDED(pMediaType->GetBlob(MF_MT_GEOMETRIC_APERTURE, - reinterpret_cast<UINT8*>(&viewport), - sizeof(MFVideoArea), - NULL))) { - - m_surfaceFormat.setViewport(QRect(viewport.OffsetX.value, - viewport.OffsetY.value, - viewport.Area.cx, - viewport.Area.cy)); - } - - if (FAILED(pMediaType->GetUINT32(MF_MT_DEFAULT_STRIDE, (UINT32*)&m_bytesPerLine))) { - m_bytesPerLine = getBytesPerLine(format); - } - - m_state = State_Ready; - if (m_currentMediaType) - m_currentMediaType->Release(); - m_currentMediaType = pMediaType; - pMediaType->AddRef(); - } - } else { - hr = MF_E_INVALIDREQUEST; - } - } - return hr; - } - - STDMETHODIMP GetCurrentMediaType( - IMFMediaType **ppMediaType) - { - if (ppMediaType == NULL) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - if (m_currentFormatIndex < 0) - return MF_E_NOT_INITIALIZED; - *ppMediaType = m_currentMediaType; - (*ppMediaType)->AddRef(); - return S_OK; - } - - STDMETHODIMP GetMajorType( - GUID *pguidMajorType) - { - if (pguidMajorType == NULL) - return E_INVALIDARG; - *pguidMajorType = MFMediaType_Video; - return S_OK; - } - - // - void setSurface(QAbstractVideoSurface *surface) - { - m_mutex.lock(); - m_surface = surface; - m_mutex.unlock(); - supportedFormatsChanged(); - } - - void setClock(IMFPresentationClock *presentationClock) - { - QMutexLocker locker(&m_mutex); - if (!m_shutdown) { - if (m_presentationClock) - m_presentationClock->Release(); - m_presentationClock = presentationClock; - if (m_presentationClock) - m_presentationClock->AddRef(); - } - } - - void shutdown() - { - QMutexLocker locker(&m_mutex); - Q_ASSERT(!m_shutdown); - - if (m_currentMediaType) { - m_currentMediaType->Release(); - m_currentMediaType = NULL; - m_currentFormatIndex = -1; - } - - if (m_eventQueue) - m_eventQueue->Shutdown(); - - MFUnlockWorkQueue(m_workQueueId); - - if (m_presentationClock) { - m_presentationClock->Release(); - m_presentationClock = NULL; - } - - clearMediaTypes(); - clearSampleQueue(); - clearBufferCache(); - - if (m_eventQueue) { - m_eventQueue->Release(); - m_eventQueue = NULL; - } - - m_shutdown = true; - } - - HRESULT startPreroll(MFTIME hnsUpcomingStartTime) - { - QMutexLocker locker(&m_mutex); - HRESULT hr = validateOperation(OpPreroll); - if (SUCCEEDED(hr)) { - m_state = State_Prerolling; - m_prerollTargetTime = hnsUpcomingStartTime; - hr = queueAsyncOperation(OpPreroll); - } - return hr; - } - - HRESULT finalize(IMFAsyncCallback *pCallback, IUnknown *punkState) - { - QMutexLocker locker(&m_mutex); - HRESULT hr = S_OK; - hr = validateOperation(OpFinalize); - if (SUCCEEDED(hr) && m_finalizeResult != NULL) - hr = MF_E_INVALIDREQUEST; // The operation is already pending. - - // Create and store the async result object. - if (SUCCEEDED(hr)) - hr = MFCreateAsyncResult(NULL, pCallback, punkState, &m_finalizeResult); - - if (SUCCEEDED(hr)) { - m_state = State_Finalized; - hr = queueAsyncOperation(OpFinalize); - } - return hr; - } - - HRESULT start(MFTIME start) - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::start" << start; -#endif - HRESULT hr = S_OK; - QMutexLocker locker(&m_mutex); - if (m_rate != 0) - hr = validateOperation(OpStart); - - if (SUCCEEDED(hr)) { - MFTIME sysTime; - if (start != PRESENTATION_CURRENT_POSITION) - m_startTime = start; // Cache the start time. - else - m_presentationClock->GetCorrelatedTime(0, &m_startTime, &sysTime); - m_state = State_Started; - hr = queueAsyncOperation(OpStart); - } - return hr; - } - - HRESULT restart() - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::restart"; -#endif - QMutexLocker locker(&m_mutex); - HRESULT hr = validateOperation(OpRestart); - if (SUCCEEDED(hr)) { - m_state = State_Started; - hr = queueAsyncOperation(OpRestart); - } - return hr; - } - - HRESULT stop() - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::stop"; -#endif - QMutexLocker locker(&m_mutex); - HRESULT hr = validateOperation(OpStop); - if (SUCCEEDED(hr)) { - m_state = State_Stopped; - hr = queueAsyncOperation(OpStop); - } - return hr; - } - - HRESULT pause() - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::pause"; -#endif - QMutexLocker locker(&m_mutex); - HRESULT hr = validateOperation(OpPause); - if (SUCCEEDED(hr)) { - m_state = State_Paused; - hr = queueAsyncOperation(OpPause); - } - return hr; - } - - HRESULT setRate(float rate) - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::setRate" << rate; -#endif - QMutexLocker locker(&m_mutex); - HRESULT hr = validateOperation(OpSetRate); - if (SUCCEEDED(hr)) { - m_rate = rate; - hr = queueAsyncOperation(OpSetRate); - } - return hr; - } - - void supportedFormatsChanged() - { - QMutexLocker locker(&m_mutex); - m_pixelFormats.clear(); - clearMediaTypes(); - if (!m_surface) - return; - const QList<QVideoFrame::PixelFormat> formats = m_surface->supportedPixelFormats(); - for (QVideoFrame::PixelFormat format : formats) { - IMFMediaType *mediaType; - if (FAILED(MFCreateMediaType(&mediaType))) { - qWarning("Failed to create mf media type!"); - continue; - } - mediaType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE); - mediaType->SetUINT32(MF_MT_COMPRESSED, FALSE); - mediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); - mediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); - switch (format) { - case QVideoFrame::Format_ARGB32: - case QVideoFrame::Format_ARGB32_Premultiplied: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_ARGB32); - break; - case QVideoFrame::Format_RGB32: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32); - break; - case QVideoFrame::Format_BGR24: // MFVideoFormat_RGB24 has a BGR layout - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24); - break; - case QVideoFrame::Format_RGB565: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB565); - break; - case QVideoFrame::Format_RGB555: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB555); - break; - case QVideoFrame::Format_AYUV444: - case QVideoFrame::Format_AYUV444_Premultiplied: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_AYUV); - break; - case QVideoFrame::Format_YUV420P: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_I420); - break; - case QVideoFrame::Format_UYVY: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_UYVY); - break; - case QVideoFrame::Format_YV12: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YV12); - break; - case QVideoFrame::Format_NV12: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12); - break; - default: - mediaType->Release(); - continue; - } - // QAbstractVideoSurface::supportedPixelFormats() returns formats in descending - // order of preference, while IMFMediaTypeHandler is supposed to return supported - // formats in ascending order of preference. We need to reverse the list. - m_pixelFormats.prepend(format); - m_mediaTypes.prepend(mediaType); - } - } - - void present() - { - QMutexLocker locker(&m_mutex); - if (!m_scheduledBuffer) - return; - QVideoFrame frame = QVideoFrame( - new MediaSampleVideoBuffer(m_scheduledBuffer, m_bytesPerLine), - m_surfaceFormat.frameSize(), - m_surfaceFormat.pixelFormat()); - frame.setStartTime(m_bufferStartTime * 0.1); - frame.setEndTime((m_bufferStartTime + m_bufferDuration) * 0.1); - m_surface->present(frame); - m_scheduledBuffer->Release(); - m_scheduledBuffer = NULL; - if (m_rate != 0) - schedulePresentation(true); - } - - void clearScheduledFrame() - { - QMutexLocker locker(&m_mutex); - if (m_scheduledBuffer) { - m_scheduledBuffer->Release(); - m_scheduledBuffer = NULL; - schedulePresentation(true); - } - } - - enum - { - StartSurface = QEvent::User, - StopSurface, - FlushSurface, - PresentSurface - }; - - class PresentEvent : public QEvent - { - public: - PresentEvent(MFTIME targetTime) - : QEvent(QEvent::Type(PresentSurface)) - , m_time(targetTime) - { - } - - MFTIME targetTime() - { - return m_time; - } - - private: - MFTIME m_time; - }; - - protected: - void customEvent(QEvent *event) - { - QMutexLocker locker(&m_mutex); - if (event->type() == StartSurface) { - if (m_state == State_WaitForSurfaceStart) { - m_startResult = startSurface(); - queueAsyncOperation(OpStart); - } - } else if (event->type() == StopSurface) { - stopSurface(); - } else { - QObject::customEvent(event); - } - } - HRESULT m_startResult; - - private: - HRESULT startSurface() - { - if (!m_surface->isFormatSupported(m_surfaceFormat)) - return S_FALSE; - if (!m_surface->start(m_surfaceFormat)) - return S_FALSE; - return S_OK; - } - - void stopSurface() - { - m_surface->stop(); - } - - enum FlushState - { - DropSamples = 0, - WriteSamples - }; - - // State enum: Defines the current state of the stream. - enum State - { - State_TypeNotSet = 0, // No media type is set - State_Ready, // Media type is set, Start has never been called. - State_Prerolling, - State_Started, - State_Paused, - State_Stopped, - State_WaitForSurfaceStart, - State_Finalized, - State_Count = State_Finalized + 1 // Number of states - }; - - // StreamOperation: Defines various operations that can be performed on the stream. - enum StreamOperation - { - OpSetMediaType = 0, - OpStart, - OpPreroll, - OpRestart, - OpPause, - OpStop, - OpSetRate, - OpProcessSample, - OpPlaceMarker, - OpFinalize, - - Op_Count = OpFinalize + 1 // Number of operations - }; - - // AsyncOperation: - // Used to queue asynchronous operations. When we call MFPutWorkItem, we use this - // object for the callback state (pState). Then, when the callback is invoked, - // we can use the object to determine which asynchronous operation to perform. - class AsyncOperation : public IUnknown - { - public: - AsyncOperation(StreamOperation op) - :m_cRef(1), m_op(op) - { - } - - StreamOperation m_op; // The operation to perform. - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID iid, void** ppv) - { - if (!ppv) - return E_POINTER; - if (iid == IID_IUnknown) { - *ppv = static_cast<IUnknown*>(this); - } else { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - STDMETHODIMP_(ULONG) AddRef() - { - return InterlockedIncrement(&m_cRef); - } - STDMETHODIMP_(ULONG) Release() - { - ULONG uCount = InterlockedDecrement(&m_cRef); - if (uCount == 0) - delete this; - // For thread safety, return a temporary variable. - return uCount; - } - - private: - long m_cRef; - virtual ~AsyncOperation() - { - Q_ASSERT(m_cRef == 0); - } - }; - - // ValidStateMatrix: Defines a look-up table that says which operations - // are valid from which states. - static BOOL ValidStateMatrix[State_Count][Op_Count]; - - long m_cRef; - QMutex m_mutex; - - IMFMediaType *m_currentMediaType; - State m_state; - IMFMediaSink *m_sink; - IMFMediaEventQueue *m_eventQueue; - DWORD m_workQueueId; - AsyncCallback<MediaStream> m_workQueueCB; - QList<IUnknown*> m_sampleQueue; - IMFAsyncResult *m_finalizeResult; // Result object for Finalize operation. - MFTIME m_startTime; // Presentation time when the clock started. - - bool m_shutdown; - QList<IMFMediaType*> m_mediaTypes; - QList<QVideoFrame::PixelFormat> m_pixelFormats; - int m_currentFormatIndex; - int m_bytesPerLine; - QVideoSurfaceFormat m_surfaceFormat; - QAbstractVideoSurface* m_surface; - MFVideoRendererControl *m_rendererControl; - - void clearMediaTypes() - { - for (IMFMediaType* mediaType : qAsConst(m_mediaTypes)) - mediaType->Release(); - m_mediaTypes.clear(); - } - - int getMediaTypeIndex(IMFMediaType *mt) - { - GUID majorType; - if (FAILED(mt->GetMajorType(&majorType))) - return -1; - if (majorType != MFMediaType_Video) - return -1; - - GUID subType; - if (FAILED(mt->GetGUID(MF_MT_SUBTYPE, &subType))) - return -1; - - for (int index = 0; index < m_mediaTypes.size(); ++index) { - GUID st; - m_mediaTypes[index]->GetGUID(MF_MT_SUBTYPE, &st); - if (st == subType) - return index; - } - return -1; - } - - int getBytesPerLine(const QVideoSurfaceFormat &format) - { - switch (format.pixelFormat()) { - // 32 bpp packed formats. - case QVideoFrame::Format_RGB32: - case QVideoFrame::Format_AYUV444: - return format.frameWidth() * 4; - // 24 bpp packed formats. - case QVideoFrame::Format_RGB24: - case QVideoFrame::Format_BGR24: - return PAD_TO_DWORD(format.frameWidth() * 3); - // 16 bpp packed formats. - case QVideoFrame::Format_RGB565: - case QVideoFrame::Format_RGB555: - case QVideoFrame::Format_YUYV: - case QVideoFrame::Format_UYVY: - return PAD_TO_DWORD(format.frameWidth() * 2); - // Planar formats. - case QVideoFrame::Format_IMC1: - case QVideoFrame::Format_IMC2: - case QVideoFrame::Format_IMC3: - case QVideoFrame::Format_IMC4: - case QVideoFrame::Format_YV12: - case QVideoFrame::Format_NV12: - case QVideoFrame::Format_YUV420P: - return PAD_TO_DWORD(format.frameWidth()); - default: - return 0; - } - } - - // Callback for MFPutWorkItem. - HRESULT onDispatchWorkItem(IMFAsyncResult* pAsyncResult) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - HRESULT hr = S_OK; - IUnknown *pState = NULL; - hr = pAsyncResult->GetState(&pState); - if (SUCCEEDED(hr)) { - // The state object is an AsncOperation object. - AsyncOperation *pOp = (AsyncOperation*)pState; - StreamOperation op = pOp->m_op; - switch (op) { - case OpStart: - endPreroll(S_FALSE); - if (m_state == State_WaitForSurfaceStart) { - hr = m_startResult; - m_state = State_Started; - } else if (!m_surface->isActive()) { - if (thread() == QThread::currentThread()) { - hr = startSurface(); - } - else { - m_state = State_WaitForSurfaceStart; - QCoreApplication::postEvent(m_rendererControl, new QChildEvent(QEvent::Type(StartSurface), this)); - break; - } - } - - if (m_state == State_Started) - schedulePresentation(true); - case OpRestart: - endPreroll(S_FALSE); - if (SUCCEEDED(hr)) { - // Send MEStreamSinkStarted. - hr = queueEvent(MEStreamSinkStarted, GUID_NULL, hr, NULL); - // Kick things off by requesting samples... - schedulePresentation(true); - // There might be samples queue from earlier (ie, while paused). - if (SUCCEEDED(hr)) - hr = processSamplesFromQueue(WriteSamples); - } - break; - case OpPreroll: - beginPreroll(); - break; - case OpStop: - // Drop samples from queue. - hr = processSamplesFromQueue(DropSamples); - clearBufferCache(); - // Send the event even if the previous call failed. - hr = queueEvent(MEStreamSinkStopped, GUID_NULL, hr, NULL); - if (m_surface->isActive()) { - if (thread() == QThread::currentThread()) { - stopSurface(); - } - else { - QCoreApplication::postEvent(m_rendererControl, new QChildEvent(QEvent::Type(StopSurface), this)); - } - } - break; - case OpPause: - hr = queueEvent(MEStreamSinkPaused, GUID_NULL, hr, NULL); - break; - case OpSetRate: - hr = queueEvent(MEStreamSinkRateChanged, GUID_NULL, S_OK, NULL); - break; - case OpProcessSample: - case OpPlaceMarker: - hr = dispatchProcessSample(pOp); - break; - case OpFinalize: - endPreroll(S_FALSE); - hr = dispatchFinalize(pOp); - break; - } - } - - if (pState) - pState->Release(); - return hr; - } - - - HRESULT queueEvent(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, const PROPVARIANT* pvValue) - { - HRESULT hr = S_OK; - if (m_shutdown) - hr = MF_E_SHUTDOWN; - if (SUCCEEDED(hr)) - hr = m_eventQueue->QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue); - return hr; - } - - HRESULT validateOperation(StreamOperation op) - { - Q_ASSERT(!m_shutdown); - if (ValidStateMatrix[m_state][op]) - return S_OK; - else - return MF_E_INVALIDREQUEST; - } - - HRESULT queueAsyncOperation(StreamOperation op) - { - HRESULT hr = S_OK; - AsyncOperation *asyncOp = new AsyncOperation(op); - if (asyncOp == NULL) - hr = E_OUTOFMEMORY; - - if (SUCCEEDED(hr)) - hr = MFPutWorkItem(m_workQueueId, &m_workQueueCB, asyncOp); - - if (asyncOp) - asyncOp->Release(); - - return hr; - } - - HRESULT processSamplesFromQueue(FlushState bFlushData) - { - HRESULT hr = S_OK; - QList<IUnknown*>::Iterator pos = m_sampleQueue.begin(); - // Enumerate all of the samples/markers in the queue. - while (pos != m_sampleQueue.end()) { - IUnknown *pUnk = NULL; - IMarker *pMarker = NULL; - IMFSample *pSample = NULL; - pUnk = *pos; - // Figure out if this is a marker or a sample. - if (SUCCEEDED(hr)) { - hr = pUnk->QueryInterface(__uuidof(IMarker), (void**)&pMarker); - if (hr == E_NOINTERFACE) - hr = pUnk->QueryInterface(IID_IMFSample, (void**)&pSample); - } - - // Now handle the sample/marker appropriately. - if (SUCCEEDED(hr)) { - if (pMarker) { - hr = sendMarkerEvent(pMarker, bFlushData); - } else { - Q_ASSERT(pSample != NULL); // Not a marker, must be a sample - if (bFlushData == WriteSamples) - hr = processSampleData(pSample); - } - } - if (pMarker) - pMarker->Release(); - if (pSample) - pSample->Release(); - - if (FAILED(hr)) - break; - - pos++; - } - - clearSampleQueue(); - return hr; - } - - void beginPreroll() - { - if (m_prerolling) - return; - m_prerolling = true; - clearSampleQueue(); - clearBufferCache(); - queueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL); - } - - void endPreroll(HRESULT hrStatus) - { - if (!m_prerolling) - return; - m_prerolling = false; - queueEvent(MEStreamSinkPrerolled, GUID_NULL, hrStatus, NULL); - } - MFTIME m_prerollTargetTime; - bool m_prerolling; - - void clearSampleQueue() { - for (IUnknown* sample : qAsConst(m_sampleQueue)) - sample->Release(); - m_sampleQueue.clear(); - } - - HRESULT sendMarkerEvent(IMarker *pMarker, FlushState FlushState) - { - HRESULT hr = S_OK; - HRESULT hrStatus = S_OK; // Status code for marker event. - if (FlushState == DropSamples) - hrStatus = E_ABORT; - - PROPVARIANT var; - PropVariantInit(&var); - - // Get the context data. - hr = pMarker->GetContext(&var); - - if (SUCCEEDED(hr)) - hr = queueEvent(MEStreamSinkMarker, GUID_NULL, hrStatus, &var); - - PropVariantClear(&var); - return hr; - } - - HRESULT dispatchProcessSample(AsyncOperation* pOp) - { - HRESULT hr = S_OK; - Q_ASSERT(pOp != NULL); - Q_UNUSED(pOp); - hr = processSamplesFromQueue(WriteSamples); - // We are in the middle of an asynchronous operation, so if something failed, send an error. - if (FAILED(hr)) - hr = queueEvent(MEError, GUID_NULL, hr, NULL); - - return hr; - } - - HRESULT dispatchFinalize(AsyncOperation*) - { - HRESULT hr = S_OK; - // Write any samples left in the queue... - hr = processSamplesFromQueue(WriteSamples); - - // Set the async status and invoke the callback. - m_finalizeResult->SetStatus(hr); - hr = MFInvokeCallback(m_finalizeResult); - return hr; - } - - HRESULT processSampleData(IMFSample *pSample) - { - m_sampleRequested = false; - - LONGLONG time, duration = -1; - HRESULT hr = pSample->GetSampleTime(&time); - if (SUCCEEDED(hr)) - pSample->GetSampleDuration(&duration); - - if (m_prerolling) { - if (SUCCEEDED(hr) && ((time - m_prerollTargetTime) * m_rate) >= 0) { - IMFMediaBuffer *pBuffer = NULL; - hr = pSample->ConvertToContiguousBuffer(&pBuffer); - if (SUCCEEDED(hr)) { - SampleBuffer sb; - sb.m_buffer = pBuffer; - sb.m_time = time; - sb.m_duration = duration; - m_bufferCache.push_back(sb); - endPreroll(S_OK); - } - } else { - queueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL); - } - } else { - bool requestSample = true; - // If the time stamp is too early, just discard this sample. - if (SUCCEEDED(hr) && ((time - m_startTime) * m_rate) >= 0) { - IMFMediaBuffer *pBuffer = NULL; - hr = pSample->ConvertToContiguousBuffer(&pBuffer); - if (SUCCEEDED(hr)) { - SampleBuffer sb; - sb.m_buffer = pBuffer; - sb.m_time = time; - sb.m_duration = duration; - m_bufferCache.push_back(sb); - } - if (m_rate == 0) - requestSample = false; - } - schedulePresentation(requestSample); - } - return hr; - } - - class SampleBuffer - { - public: - IMFMediaBuffer *m_buffer; - LONGLONG m_time; - LONGLONG m_duration; - }; - QList<SampleBuffer> m_bufferCache; - static const int BUFFER_CACHE_SIZE = 2; - - void clearBufferCache() - { - for (SampleBuffer sb : qAsConst(m_bufferCache)) - sb.m_buffer->Release(); - m_bufferCache.clear(); - - if (m_scheduledBuffer) { - m_scheduledBuffer->Release(); - m_scheduledBuffer = NULL; - } - } - - void schedulePresentation(bool requestSample) - { - if (m_state == State_Paused || m_state == State_Prerolling) - return; - if (!m_scheduledBuffer) { - //get time from presentation time - MFTIME currentTime = m_startTime, sysTime; - bool timeOK = true; - if (m_rate != 0) { - if (FAILED(m_presentationClock->GetCorrelatedTime(0, ¤tTime, &sysTime))) - timeOK = false; - } - while (!m_bufferCache.isEmpty()) { - SampleBuffer sb = m_bufferCache.takeFirst(); - if (timeOK && ((sb.m_time - currentTime) * m_rate) < 0) { - sb.m_buffer->Release(); -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "currentPresentTime =" << float(currentTime / 10000) * 0.001f << " and sampleTime is" << float(sb.m_time / 10000) * 0.001f; -#endif - continue; - } - m_scheduledBuffer = sb.m_buffer; - m_bufferStartTime = sb.m_time; - m_bufferDuration = sb.m_duration; - QCoreApplication::postEvent(m_rendererControl, new PresentEvent(sb.m_time)); - if (m_rate == 0) - queueEvent(MEStreamSinkScrubSampleComplete, GUID_NULL, S_OK, NULL); - break; - } - } - if (requestSample && !m_sampleRequested && m_bufferCache.size() < BUFFER_CACHE_SIZE) { - m_sampleRequested = true; - queueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL); - } - } - IMFMediaBuffer *m_scheduledBuffer; - MFTIME m_bufferStartTime; - MFTIME m_bufferDuration; - IMFPresentationClock *m_presentationClock; - bool m_sampleRequested; - float m_rate; - }; - - BOOL MediaStream::ValidStateMatrix[MediaStream::State_Count][MediaStream::Op_Count] = - { - // States: Operations: - // SetType Start Preroll, Restart Pause Stop SetRate Sample Marker Finalize - /* NotSet */ TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, - - /* Ready */ TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, - - /* Prerolling */ TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, - - /* Start */ FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, - - /* Pause */ FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, - - /* Stop */ FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, - - /*WaitForSurfaceStart*/ FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, - - /* Final */ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE - - // Note about states: - // 1. OnClockRestart should only be called from paused state. - // 2. While paused, the sink accepts samples but does not process them. - }; - - class MediaSink : public IMFFinalizableMediaSink, - public IMFClockStateSink, - public IMFMediaSinkPreroll, - public IMFGetService, - public IMFRateSupport - { - public: - MediaSink(MFVideoRendererControl *rendererControl) - : m_cRef(1) - , m_shutdown(false) - , m_presentationClock(0) - , m_playRate(1) - { - m_stream = new MediaStream(this, rendererControl); - } - - ~MediaSink() - { - Q_ASSERT(m_shutdown); - } - - void setSurface(QAbstractVideoSurface *surface) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return; - m_stream->setSurface(surface); - } - - void supportedFormatsChanged() - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return; - m_stream->supportedFormatsChanged(); - } - - void present() - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return; - m_stream->present(); - } - - void clearScheduledFrame() - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return; - m_stream->clearScheduledFrame(); - } - - MFTIME getTime() - { - QMutexLocker locker(&m_mutex); - if (!m_presentationClock) - return 0; - MFTIME time, sysTime; - m_presentationClock->GetCorrelatedTime(0, &time, &sysTime); - return time; - } - - float getPlayRate() - { - QMutexLocker locker(&m_mutex); - return m_playRate; - } - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject) - { - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFMediaSink) { - *ppvObject = static_cast<IMFMediaSink*>(this); - } else if (riid == IID_IMFGetService) { - *ppvObject = static_cast<IMFGetService*>(this); - } else if (riid == IID_IMFMediaSinkPreroll) { - *ppvObject = static_cast<IMFMediaSinkPreroll*>(this); - } else if (riid == IID_IMFClockStateSink) { - *ppvObject = static_cast<IMFClockStateSink*>(this); - } else if (riid == IID_IMFRateSupport) { - *ppvObject = static_cast<IMFRateSupport*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(static_cast<IMFFinalizableMediaSink*>(this)); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - - STDMETHODIMP_(ULONG) AddRef(void) - { - return InterlockedIncrement(&m_cRef); - } - - STDMETHODIMP_(ULONG) Release(void) - { - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - // For thread safety, return a temporary variable. - return cRef; - } - - // IMFGetService methods - STDMETHODIMP GetService(const GUID &guidService, - const IID &riid, - LPVOID *ppvObject) - { - if (!ppvObject) - return E_POINTER; - - if (guidService != MF_RATE_CONTROL_SERVICE) - return MF_E_UNSUPPORTED_SERVICE; - - return QueryInterface(riid, ppvObject); - } - - //IMFMediaSinkPreroll - STDMETHODIMP NotifyPreroll(MFTIME hnsUpcomingStartTime) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_stream->startPreroll(hnsUpcomingStartTime); - } - - //from IMFFinalizableMediaSink - STDMETHODIMP BeginFinalize(IMFAsyncCallback *pCallback, IUnknown *punkState) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_stream->finalize(pCallback, punkState); - } - - STDMETHODIMP EndFinalize(IMFAsyncResult *pResult) - { - HRESULT hr = S_OK; - // Return the status code from the async result. - if (pResult == NULL) - hr = E_INVALIDARG; - else - hr = pResult->GetStatus(); - return hr; - } - - //from IMFMediaSink - STDMETHODIMP GetCharacteristics( - DWORD *pdwCharacteristics) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - *pdwCharacteristics = MEDIASINK_FIXED_STREAMS | MEDIASINK_CAN_PREROLL; - return S_OK; - } - - STDMETHODIMP AddStreamSink( - DWORD, - IMFMediaType *, - IMFStreamSink **) - { - QMutexLocker locker(&m_mutex); - return m_shutdown ? MF_E_SHUTDOWN : MF_E_STREAMSINKS_FIXED; - } - - STDMETHODIMP RemoveStreamSink( - DWORD) - { - QMutexLocker locker(&m_mutex); - return m_shutdown ? MF_E_SHUTDOWN : MF_E_STREAMSINKS_FIXED; - } - - STDMETHODIMP GetStreamSinkCount( - DWORD *pcStreamSinkCount) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - *pcStreamSinkCount = 1; - return S_OK; - } - - STDMETHODIMP GetStreamSinkByIndex( - DWORD dwIndex, - IMFStreamSink **ppStreamSink) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - if (dwIndex != 0) - return MF_E_INVALIDINDEX; - - *ppStreamSink = m_stream; - m_stream->AddRef(); - return S_OK; - } - - STDMETHODIMP GetStreamSinkById( - DWORD dwStreamSinkIdentifier, - IMFStreamSink **ppStreamSink) - { - if (ppStreamSink == NULL) - return E_INVALIDARG; - if (dwStreamSinkIdentifier != MediaStream::DEFAULT_MEDIA_STREAM_ID) - return MF_E_INVALIDSTREAMNUMBER; - - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - *ppStreamSink = m_stream; - m_stream->AddRef(); - return S_OK; - } - - STDMETHODIMP SetPresentationClock( - IMFPresentationClock *pPresentationClock) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - if (m_presentationClock) { - m_presentationClock->RemoveClockStateSink(this); - m_presentationClock->Release(); - } - m_presentationClock = pPresentationClock; - if (m_presentationClock) { - m_presentationClock->AddRef(); - m_presentationClock->AddClockStateSink(this); - } - m_stream->setClock(m_presentationClock); - return S_OK; - } - - STDMETHODIMP GetPresentationClock( - IMFPresentationClock **ppPresentationClock) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - *ppPresentationClock = m_presentationClock; - if (m_presentationClock) { - m_presentationClock->AddRef(); - return S_OK; - } - return MF_E_NO_CLOCK; - } - - STDMETHODIMP Shutdown(void) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - m_stream->shutdown(); - if (m_presentationClock) { - m_presentationClock->Release(); - m_presentationClock = NULL; - } - m_stream->Release(); - m_stream = NULL; - m_shutdown = true; - return S_OK; - } - - // IMFClockStateSink methods - STDMETHODIMP OnClockStart(MFTIME, LONGLONG llClockStartOffset) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_stream->start(llClockStartOffset); - } - - STDMETHODIMP OnClockStop(MFTIME) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_stream->stop(); - } - - STDMETHODIMP OnClockPause(MFTIME) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_stream->pause(); - } - - STDMETHODIMP OnClockRestart(MFTIME) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_stream->restart(); - } - - STDMETHODIMP OnClockSetRate(MFTIME, float flRate) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - m_playRate = flRate; - return m_stream->setRate(flRate); - } - - // IMFRateSupport methods - STDMETHODIMP GetFastestRate(MFRATE_DIRECTION eDirection, - BOOL fThin, - float *pflRate) - { - if (!pflRate) - return E_POINTER; - - *pflRate = (fThin ? 8.f : 2.0f) * (eDirection == MFRATE_FORWARD ? 1 : -1) ; - - return S_OK; - } - - STDMETHODIMP GetSlowestRate(MFRATE_DIRECTION eDirection, - BOOL fThin, - float *pflRate) - { - Q_UNUSED(eDirection); - Q_UNUSED(fThin); - - if (!pflRate) - return E_POINTER; - - // we support any rate - *pflRate = 0.f; - - return S_OK; - } - - STDMETHODIMP IsRateSupported(BOOL fThin, - float flRate, - float *pflNearestSupportedRate) - { - HRESULT hr = S_OK; - - if (!qFuzzyIsNull(flRate)) { - MFRATE_DIRECTION direction = flRate > 0.f ? MFRATE_FORWARD - : MFRATE_REVERSE; - - float fastestRate = 0.f; - float slowestRate = 0.f; - GetFastestRate(direction, fThin, &fastestRate); - GetSlowestRate(direction, fThin, &slowestRate); - - if (direction == MFRATE_REVERSE) - qSwap(fastestRate, slowestRate); - - if (flRate < slowestRate || flRate > fastestRate) { - hr = MF_E_UNSUPPORTED_RATE; - if (pflNearestSupportedRate) { - *pflNearestSupportedRate = qBound(slowestRate, - flRate, - fastestRate); - } - } - } else if (pflNearestSupportedRate) { - *pflNearestSupportedRate = flRate; - } - - return hr; - } - - private: - long m_cRef; - QMutex m_mutex; - bool m_shutdown; - IMFPresentationClock *m_presentationClock; - MediaStream *m_stream; - float m_playRate; - }; - - class VideoRendererActivate : public IMFActivate - { - public: - VideoRendererActivate(MFVideoRendererControl *rendererControl) - : m_cRef(1) - , m_sink(0) - , m_rendererControl(rendererControl) - , m_attributes(0) - , m_surface(0) - { - MFCreateAttributes(&m_attributes, 0); - m_sink = new MediaSink(rendererControl); - } - - ~VideoRendererActivate() - { - m_attributes->Release(); - } - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject) - { - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFActivate) { - *ppvObject = static_cast<IMFActivate*>(this); - } else if (riid == IID_IMFAttributes) { - *ppvObject = static_cast<IMFAttributes*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(static_cast<IMFActivate*>(this)); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - - STDMETHODIMP_(ULONG) AddRef(void) - { - return InterlockedIncrement(&m_cRef); - } - - STDMETHODIMP_(ULONG) Release(void) - { - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - // For thread safety, return a temporary variable. - return cRef; - } - - //from IMFActivate - STDMETHODIMP ActivateObject(REFIID riid, void **ppv) - { - if (!ppv) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - if (!m_sink) { - m_sink = new MediaSink(m_rendererControl); - if (m_surface) - m_sink->setSurface(m_surface); - } - return m_sink->QueryInterface(riid, ppv); - } - - STDMETHODIMP ShutdownObject(void) - { - QMutexLocker locker(&m_mutex); - HRESULT hr = S_OK; - if (m_sink) { - hr = m_sink->Shutdown(); - m_sink->Release(); - m_sink = NULL; - } - return hr; - } - - STDMETHODIMP DetachObject(void) - { - QMutexLocker locker(&m_mutex); - if (m_sink) { - m_sink->Release(); - m_sink = NULL; - } - return S_OK; - } - - //from IMFAttributes - STDMETHODIMP GetItem( - REFGUID guidKey, - PROPVARIANT *pValue) - { - return m_attributes->GetItem(guidKey, pValue); - } - - STDMETHODIMP GetItemType( - REFGUID guidKey, - MF_ATTRIBUTE_TYPE *pType) - { - return m_attributes->GetItemType(guidKey, pType); - } - - STDMETHODIMP CompareItem( - REFGUID guidKey, - REFPROPVARIANT Value, - BOOL *pbResult) - { - return m_attributes->CompareItem(guidKey, Value, pbResult); - } - - STDMETHODIMP Compare( - IMFAttributes *pTheirs, - MF_ATTRIBUTES_MATCH_TYPE MatchType, - BOOL *pbResult) - { - return m_attributes->Compare(pTheirs, MatchType, pbResult); - } - - STDMETHODIMP GetUINT32( - REFGUID guidKey, - UINT32 *punValue) - { - return m_attributes->GetUINT32(guidKey, punValue); - } - - STDMETHODIMP GetUINT64( - REFGUID guidKey, - UINT64 *punValue) - { - return m_attributes->GetUINT64(guidKey, punValue); - } - - STDMETHODIMP GetDouble( - REFGUID guidKey, - double *pfValue) - { - return m_attributes->GetDouble(guidKey, pfValue); - } - - STDMETHODIMP GetGUID( - REFGUID guidKey, - GUID *pguidValue) - { - return m_attributes->GetGUID(guidKey, pguidValue); - } - - STDMETHODIMP GetStringLength( - REFGUID guidKey, - UINT32 *pcchLength) - { - return m_attributes->GetStringLength(guidKey, pcchLength); - } - - STDMETHODIMP GetString( - REFGUID guidKey, - LPWSTR pwszValue, - UINT32 cchBufSize, - UINT32 *pcchLength) - { - return m_attributes->GetString(guidKey, pwszValue, cchBufSize, pcchLength); - } - - STDMETHODIMP GetAllocatedString( - REFGUID guidKey, - LPWSTR *ppwszValue, - UINT32 *pcchLength) - { - return m_attributes->GetAllocatedString(guidKey, ppwszValue, pcchLength); - } - - STDMETHODIMP GetBlobSize( - REFGUID guidKey, - UINT32 *pcbBlobSize) - { - return m_attributes->GetBlobSize(guidKey, pcbBlobSize); - } - - STDMETHODIMP GetBlob( - REFGUID guidKey, - UINT8 *pBuf, - UINT32 cbBufSize, - UINT32 *pcbBlobSize) - { - return m_attributes->GetBlob(guidKey, pBuf, cbBufSize, pcbBlobSize); - } - - STDMETHODIMP GetAllocatedBlob( - REFGUID guidKey, - UINT8 **ppBuf, - UINT32 *pcbSize) - { - return m_attributes->GetAllocatedBlob(guidKey, ppBuf, pcbSize); - } - - STDMETHODIMP GetUnknown( - REFGUID guidKey, - REFIID riid, - LPVOID *ppv) - { - return m_attributes->GetUnknown(guidKey, riid, ppv); - } - - STDMETHODIMP SetItem( - REFGUID guidKey, - REFPROPVARIANT Value) - { - return m_attributes->SetItem(guidKey, Value); - } - - STDMETHODIMP DeleteItem( - REFGUID guidKey) - { - return m_attributes->DeleteItem(guidKey); - } - - STDMETHODIMP DeleteAllItems(void) - { - return m_attributes->DeleteAllItems(); - } - - STDMETHODIMP SetUINT32( - REFGUID guidKey, - UINT32 unValue) - { - return m_attributes->SetUINT32(guidKey, unValue); - } - - STDMETHODIMP SetUINT64( - REFGUID guidKey, - UINT64 unValue) - { - return m_attributes->SetUINT64(guidKey, unValue); - } - - STDMETHODIMP SetDouble( - REFGUID guidKey, - double fValue) - { - return m_attributes->SetDouble(guidKey, fValue); - } - - STDMETHODIMP SetGUID( - REFGUID guidKey, - REFGUID guidValue) - { - return m_attributes->SetGUID(guidKey, guidValue); - } - - STDMETHODIMP SetString( - REFGUID guidKey, - LPCWSTR wszValue) - { - return m_attributes->SetString(guidKey, wszValue); - } - - STDMETHODIMP SetBlob( - REFGUID guidKey, - const UINT8 *pBuf, - UINT32 cbBufSize) - { - return m_attributes->SetBlob(guidKey, pBuf, cbBufSize); - } - - STDMETHODIMP SetUnknown( - REFGUID guidKey, - IUnknown *pUnknown) - { - return m_attributes->SetUnknown(guidKey, pUnknown); - } - - STDMETHODIMP LockStore(void) - { - return m_attributes->LockStore(); - } - - STDMETHODIMP UnlockStore(void) - { - return m_attributes->UnlockStore(); - } - - STDMETHODIMP GetCount( - UINT32 *pcItems) - { - return m_attributes->GetCount(pcItems); - } - - STDMETHODIMP GetItemByIndex( - UINT32 unIndex, - GUID *pguidKey, - PROPVARIANT *pValue) - { - return m_attributes->GetItemByIndex(unIndex, pguidKey, pValue); - } - - STDMETHODIMP CopyAllItems( - IMFAttributes *pDest) - { - return m_attributes->CopyAllItems(pDest); - } - - ///////////////////////////////// - void setSurface(QAbstractVideoSurface *surface) - { - QMutexLocker locker(&m_mutex); - if (m_surface == surface) - return; - - m_surface = surface; - - if (!m_sink) - return; - m_sink->setSurface(m_surface); - } - - void supportedFormatsChanged() - { - QMutexLocker locker(&m_mutex); - if (!m_sink) - return; - m_sink->supportedFormatsChanged(); - } - - void present() - { - QMutexLocker locker(&m_mutex); - if (!m_sink) - return; - m_sink->present(); - } - - void clearScheduledFrame() - { - QMutexLocker locker(&m_mutex); - if (!m_sink) - return; - m_sink->clearScheduledFrame(); - } - - MFTIME getTime() - { - if (m_sink) - return m_sink->getTime(); - return 0; - } - - float getPlayRate() - { - if (m_sink) - return m_sink->getPlayRate(); - return 1; - } - - private: - long m_cRef; - bool m_shutdown; - MediaSink *m_sink; - MFVideoRendererControl *m_rendererControl; - IMFAttributes *m_attributes; - QAbstractVideoSurface *m_surface; - QMutex m_mutex; - }; -} - - -class EVRCustomPresenterActivate : public MFAbstractActivate -{ -public: - EVRCustomPresenterActivate(); - ~EVRCustomPresenterActivate() - { } - - STDMETHODIMP ActivateObject(REFIID riid, void **ppv); - STDMETHODIMP ShutdownObject(); - STDMETHODIMP DetachObject(); - - void setSurface(QAbstractVideoSurface *surface); - -private: - EVRCustomPresenter *m_presenter; - QAbstractVideoSurface *m_surface; - QMutex m_mutex; -}; - - -MFVideoRendererControl::MFVideoRendererControl(QObject *parent) - : QVideoRendererControl(parent) - , m_surface(0) - , m_currentActivate(0) - , m_callback(0) - , m_presenterActivate(0) -{ -} - -MFVideoRendererControl::~MFVideoRendererControl() -{ - clear(); -} - -void MFVideoRendererControl::clear() -{ - if (m_surface) - m_surface->stop(); - - if (m_presenterActivate) { - m_presenterActivate->ShutdownObject(); - m_presenterActivate->Release(); - m_presenterActivate = NULL; - } - - if (m_currentActivate) { - m_currentActivate->ShutdownObject(); - m_currentActivate->Release(); - } - m_currentActivate = NULL; -} - -void MFVideoRendererControl::releaseActivate() -{ - clear(); -} - -QAbstractVideoSurface *MFVideoRendererControl::surface() const -{ - return m_surface; -} - -void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface) -{ - if (m_surface) - disconnect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged())); - m_surface = surface; - - if (m_surface) { - connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged())); - } - - if (m_presenterActivate) - m_presenterActivate->setSurface(m_surface); - else if (m_currentActivate) - static_cast<VideoRendererActivate*>(m_currentActivate)->setSurface(m_surface); -} - -void MFVideoRendererControl::customEvent(QEvent *event) -{ - if (m_presenterActivate) - return; - - if (!m_currentActivate) - return; - - if (event->type() == MediaStream::PresentSurface) { - MFTIME targetTime = static_cast<MediaStream::PresentEvent*>(event)->targetTime(); - MFTIME currentTime = static_cast<VideoRendererActivate*>(m_currentActivate)->getTime(); - float playRate = static_cast<VideoRendererActivate*>(m_currentActivate)->getPlayRate(); - if (!qFuzzyIsNull(playRate) && targetTime != currentTime) { - // If the scheduled frame is too late, skip it - const int interval = ((targetTime - currentTime) / 10000) / playRate; - if (interval < 0) - static_cast<VideoRendererActivate*>(m_currentActivate)->clearScheduledFrame(); - else - QTimer::singleShot(interval, this, SLOT(present())); - } else { - present(); - } - return; - } - if (event->type() >= MediaStream::StartSurface) { - QChildEvent *childEvent = static_cast<QChildEvent*>(event); - static_cast<MediaStream*>(childEvent->child())->customEvent(event); - } else { - QObject::customEvent(event); - } -} - -void MFVideoRendererControl::supportedFormatsChanged() -{ - if (m_presenterActivate) - return; - - if (m_currentActivate) - static_cast<VideoRendererActivate*>(m_currentActivate)->supportedFormatsChanged(); -} - -void MFVideoRendererControl::present() -{ - if (m_presenterActivate) - return; - - if (m_currentActivate) - static_cast<VideoRendererActivate*>(m_currentActivate)->present(); -} - -IMFActivate* MFVideoRendererControl::createActivate() -{ - Q_ASSERT(m_surface); - - clear(); - - // Create the EVR media sink, but replace the presenter with our own - if (SUCCEEDED(MFCreateVideoRendererActivate(::GetShellWindow(), &m_currentActivate))) { - m_presenterActivate = new EVRCustomPresenterActivate; - m_currentActivate->SetUnknown(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE, m_presenterActivate); - } else { - m_currentActivate = new VideoRendererActivate(this); - } - - setSurface(m_surface); - - return m_currentActivate; -} - - -EVRCustomPresenterActivate::EVRCustomPresenterActivate() - : MFAbstractActivate() - , m_presenter(0) - , m_surface(0) -{ } - -HRESULT EVRCustomPresenterActivate::ActivateObject(REFIID riid, void **ppv) -{ - if (!ppv) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - if (!m_presenter) { - m_presenter = new EVRCustomPresenter; - if (m_surface) - m_presenter->setSurface(m_surface); - } - return m_presenter->QueryInterface(riid, ppv); -} - -HRESULT EVRCustomPresenterActivate::ShutdownObject() -{ - // The presenter does not implement IMFShutdown so - // this function is the same as DetachObject() - return DetachObject(); -} - -HRESULT EVRCustomPresenterActivate::DetachObject() -{ - QMutexLocker locker(&m_mutex); - if (m_presenter) { - m_presenter->Release(); - m_presenter = 0; - } - return S_OK; -} - -void EVRCustomPresenterActivate::setSurface(QAbstractVideoSurface *surface) -{ - QMutexLocker locker(&m_mutex); - if (m_surface == surface) - return; - - m_surface = surface; - - if (m_presenter) - m_presenter->setSurface(surface); -} - -#include "moc_mfvideorenderercontrol.cpp" -#include "mfvideorenderercontrol.moc" diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.h b/src/plugins/wmf/player/mfvideorenderercontrol.h deleted file mode 100644 index da9e97ba9..000000000 --- a/src/plugins/wmf/player/mfvideorenderercontrol.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFVIDEORENDERERCONTROL_H -#define MFVIDEORENDERERCONTROL_H - -#include "qvideorenderercontrol.h" -#include <mfapi.h> -#include <mfidl.h> - -QT_USE_NAMESPACE - -class EVRCustomPresenterActivate; - -class MFVideoRendererControl : public QVideoRendererControl -{ - Q_OBJECT -public: - MFVideoRendererControl(QObject *parent = 0); - ~MFVideoRendererControl(); - - QAbstractVideoSurface *surface() const; - void setSurface(QAbstractVideoSurface *surface); - - IMFActivate* createActivate(); - void releaseActivate(); - -protected: - void customEvent(QEvent *event); - -private Q_SLOTS: - void supportedFormatsChanged(); - void present(); - -private: - void clear(); - - QAbstractVideoSurface *m_surface; - IMFActivate *m_currentActivate; - IMFSampleGrabberSinkCallback *m_callback; - - EVRCustomPresenterActivate *m_presenterActivate; -}; - -#endif diff --git a/src/plugins/wmf/player/player.pri b/src/plugins/wmf/player/player.pri deleted file mode 100644 index af2f7458b..000000000 --- a/src/plugins/wmf/player/player.pri +++ /dev/null @@ -1,34 +0,0 @@ -INCLUDEPATH += $$PWD - -LIBS += -lgdi32 -luser32 -QMAKE_USE += wmf - -HEADERS += \ - $$PWD/mfplayerservice.h \ - $$PWD/mfplayersession.h \ - $$PWD/mfplayercontrol.h \ - $$PWD/mfvideorenderercontrol.h \ - $$PWD/mfaudioendpointcontrol.h \ - $$PWD/mfmetadatacontrol.h \ - $$PWD/mfaudioprobecontrol.h \ - $$PWD/mfvideoprobecontrol.h \ - $$PWD/mfevrvideowindowcontrol.h \ - $$PWD/samplegrabber.h \ - $$PWD/mftvideo.h \ - $$PWD/mfactivate.h - -SOURCES += \ - $$PWD/mfplayerservice.cpp \ - $$PWD/mfplayersession.cpp \ - $$PWD/mfplayercontrol.cpp \ - $$PWD/mfvideorenderercontrol.cpp \ - $$PWD/mfaudioendpointcontrol.cpp \ - $$PWD/mfmetadatacontrol.cpp \ - $$PWD/mfaudioprobecontrol.cpp \ - $$PWD/mfvideoprobecontrol.cpp \ - $$PWD/mfevrvideowindowcontrol.cpp \ - $$PWD/samplegrabber.cpp \ - $$PWD/mftvideo.cpp \ - $$PWD/mfactivate.cpp - -include($$PWD/../../common/evr.pri) diff --git a/src/plugins/wmf/player/samplegrabber.cpp b/src/plugins/wmf/player/samplegrabber.cpp deleted file mode 100644 index d137335f3..000000000 --- a/src/plugins/wmf/player/samplegrabber.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "samplegrabber.h" -#include "mfaudioprobecontrol.h" - -STDMETHODIMP SampleGrabberCallback::QueryInterface(REFIID riid, void** ppv) -{ - if (!ppv) - return E_POINTER; - if (riid == IID_IMFSampleGrabberSinkCallback) { - *ppv = static_cast<IMFSampleGrabberSinkCallback*>(this); - } else if (riid == IID_IMFClockStateSink) { - *ppv = static_cast<IMFClockStateSink*>(this); - } else if (riid == IID_IUnknown) { - *ppv = static_cast<IUnknown*>(this); - } else { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -STDMETHODIMP_(ULONG) SampleGrabberCallback::AddRef() -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) SampleGrabberCallback::Release() -{ - ULONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) { - delete this; - } - return cRef; - -} - -// IMFClockStateSink methods. - -STDMETHODIMP SampleGrabberCallback::OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset) -{ - Q_UNUSED(hnsSystemTime); - Q_UNUSED(llClockStartOffset); - return S_OK; -} - -STDMETHODIMP SampleGrabberCallback::OnClockStop(MFTIME hnsSystemTime) -{ - Q_UNUSED(hnsSystemTime); - return S_OK; -} - -STDMETHODIMP SampleGrabberCallback::OnClockPause(MFTIME hnsSystemTime) -{ - Q_UNUSED(hnsSystemTime); - return S_OK; -} - -STDMETHODIMP SampleGrabberCallback::OnClockRestart(MFTIME hnsSystemTime) -{ - Q_UNUSED(hnsSystemTime); - return S_OK; -} - -STDMETHODIMP SampleGrabberCallback::OnClockSetRate(MFTIME hnsSystemTime, float flRate) -{ - Q_UNUSED(hnsSystemTime); - Q_UNUSED(flRate); - return S_OK; -} - -// IMFSampleGrabberSink methods. - -STDMETHODIMP SampleGrabberCallback::OnSetPresentationClock(IMFPresentationClock* pClock) -{ - Q_UNUSED(pClock); - return S_OK; -} - -STDMETHODIMP SampleGrabberCallback::OnShutdown() -{ - return S_OK; -} - -void AudioSampleGrabberCallback::addProbe(MFAudioProbeControl* probe) -{ - QMutexLocker locker(&m_audioProbeMutex); - - if (m_audioProbes.contains(probe)) - return; - - m_audioProbes.append(probe); -} - -void AudioSampleGrabberCallback::removeProbe(MFAudioProbeControl* probe) -{ - QMutexLocker locker(&m_audioProbeMutex); - m_audioProbes.removeOne(probe); -} - -void AudioSampleGrabberCallback::setFormat(const QAudioFormat& format) -{ - m_format = format; -} - -STDMETHODIMP AudioSampleGrabberCallback::OnProcessSample(REFGUID guidMajorMediaType, DWORD dwSampleFlags, - LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer, - DWORD dwSampleSize) -{ - Q_UNUSED(dwSampleFlags); - Q_UNUSED(llSampleTime); - Q_UNUSED(llSampleDuration); - - if (guidMajorMediaType != GUID_NULL && guidMajorMediaType != MFMediaType_Audio) - return S_OK; - - QMutexLocker locker(&m_audioProbeMutex); - - if (m_audioProbes.isEmpty()) - return S_OK; - - // Check if sample has a presentation time - if (llSampleTime == _I64_MAX) { - // Set default QAudioBuffer start time - llSampleTime = -1; - } else { - // WMF uses 100-nanosecond units, Qt uses microseconds - llSampleTime /= 10; - } - - for (MFAudioProbeControl* probe : qAsConst(m_audioProbes)) - probe->bufferProbed((const char*)pSampleBuffer, dwSampleSize, m_format, llSampleTime); - - return S_OK; -} diff --git a/src/plugins/wmf/player/samplegrabber.h b/src/plugins/wmf/player/samplegrabber.h deleted file mode 100644 index 9ca673a1b..000000000 --- a/src/plugins/wmf/player/samplegrabber.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SAMPLEGRABBER_H -#define SAMPLEGRABBER_H - -#include <QtCore/qmutex.h> -#include <QtCore/qlist.h> -#include <QtMultimedia/qaudioformat.h> -#include <mfapi.h> -#include <mfidl.h> - -class MFAudioProbeControl; - -class SampleGrabberCallback : public IMFSampleGrabberSinkCallback -{ -public: - // IUnknown methods - STDMETHODIMP QueryInterface(REFIID iid, void** ppv); - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); - - // IMFClockStateSink methods - STDMETHODIMP OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset); - STDMETHODIMP OnClockStop(MFTIME hnsSystemTime); - STDMETHODIMP OnClockPause(MFTIME hnsSystemTime); - STDMETHODIMP OnClockRestart(MFTIME hnsSystemTime); - STDMETHODIMP OnClockSetRate(MFTIME hnsSystemTime, float flRate); - - // IMFSampleGrabberSinkCallback methods - STDMETHODIMP OnSetPresentationClock(IMFPresentationClock* pClock); - STDMETHODIMP OnShutdown(); - -protected: - SampleGrabberCallback() : m_cRef(1) {} - -public: - virtual ~SampleGrabberCallback() {} - -private: - long m_cRef; -}; - -class AudioSampleGrabberCallback: public SampleGrabberCallback { -public: - void addProbe(MFAudioProbeControl* probe); - void removeProbe(MFAudioProbeControl* probe); - void setFormat(const QAudioFormat& format); - - STDMETHODIMP OnProcessSample(REFGUID guidMajorMediaType, DWORD dwSampleFlags, - LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer, - DWORD dwSampleSize); - -private: - QList<MFAudioProbeControl*> m_audioProbes; - QMutex m_audioProbeMutex; - QAudioFormat m_format; -}; - -#endif // SAMPLEGRABBER_H diff --git a/src/plugins/wmf/sourceresolver.cpp b/src/plugins/wmf/sourceresolver.cpp deleted file mode 100644 index 15ef6f0ab..000000000 --- a/src/plugins/wmf/sourceresolver.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfstream.h" -#include "sourceresolver.h" -#include <mferror.h> -#include <nserror.h> -#include <QtCore/qfile.h> -#include <QtCore/qdebug.h> -#include <QtMultimedia/qmediaplayer.h> - -/* - SourceResolver is separated from MFPlayerSession to handle the work of resolving a media source - asynchronously. You call SourceResolver::load to request resolving a media source asynchronously, - and it will emit mediaSourceReady() when resolving is done. You can call SourceResolver::cancel to - stop the previous load operation if there is any. -*/ - -SourceResolver::SourceResolver() - : m_cRef(1) - , m_cancelCookie(0) - , m_sourceResolver(0) - , m_mediaSource(0) - , m_stream(0) -{ -} - -SourceResolver::~SourceResolver() -{ - shutdown(); - if (m_mediaSource) { - m_mediaSource->Release(); - m_mediaSource = NULL; - } - - if (m_cancelCookie) - m_cancelCookie->Release(); - if (m_sourceResolver) - m_sourceResolver->Release(); -} - -STDMETHODIMP SourceResolver::QueryInterface(REFIID riid, LPVOID *ppvObject) -{ - if (!ppvObject) - return E_POINTER; - if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - } else if (riid == IID_IMFAsyncCallback) { - *ppvObject = static_cast<IMFAsyncCallback*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -STDMETHODIMP_(ULONG) SourceResolver::AddRef(void) -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) SourceResolver::Release(void) -{ - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - this->deleteLater(); - return cRef; -} - -HRESULT STDMETHODCALLTYPE SourceResolver::Invoke(IMFAsyncResult *pAsyncResult) -{ - QMutexLocker locker(&m_mutex); - - if (!m_sourceResolver) - return S_OK; - - MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID; - IUnknown* pSource = NULL; - State *state = static_cast<State*>(pAsyncResult->GetStateNoAddRef()); - - HRESULT hr = S_OK; - if (state->fromStream()) - hr = m_sourceResolver->EndCreateObjectFromByteStream(pAsyncResult, &ObjectType, &pSource); - else - hr = m_sourceResolver->EndCreateObjectFromURL(pAsyncResult, &ObjectType, &pSource); - - if (state->sourceResolver() != m_sourceResolver) { - //This is a cancelled one - return S_OK; - } - - if (m_cancelCookie) { - m_cancelCookie->Release(); - m_cancelCookie = NULL; - } - - if (FAILED(hr)) { - emit error(hr); - return S_OK; - } - - if (m_mediaSource) { - m_mediaSource->Release(); - m_mediaSource = NULL; - } - - hr = pSource->QueryInterface(IID_PPV_ARGS(&m_mediaSource)); - pSource->Release(); - if (FAILED(hr)) { - emit error(hr); - return S_OK; - } - - emit mediaSourceReady(); - - return S_OK; -} - -HRESULT STDMETHODCALLTYPE SourceResolver::GetParameters(DWORD*, DWORD*) -{ - return E_NOTIMPL; -} - -void SourceResolver::load(const QUrl &url, QIODevice* stream) -{ - QMutexLocker locker(&m_mutex); - HRESULT hr = S_OK; - if (!m_sourceResolver) - hr = MFCreateSourceResolver(&m_sourceResolver); - - if (m_stream) { - m_stream->Release(); - m_stream = NULL; - } - - if (FAILED(hr)) { - qWarning() << "Failed to create Source Resolver!"; - emit error(hr); - } else if (stream) { - QString urlString = url.toString(); - m_stream = new MFStream(stream, false); - hr = m_sourceResolver->BeginCreateObjectFromByteStream( - m_stream, urlString.isEmpty() ? 0 : reinterpret_cast<LPCWSTR>(urlString.utf16()), - MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE - , NULL, &m_cancelCookie, this, new State(m_sourceResolver, true)); - if (FAILED(hr)) { - qWarning() << "Unsupported stream!"; - emit error(hr); - } - } else { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "loading :" << url; - qDebug() << "url path =" << url.path().mid(1); -#endif -#ifdef TEST_STREAMING - //Testing stream function - if (url.scheme() == QLatin1String("file")) { - stream = new QFile(url.path().mid(1)); - if (stream->open(QIODevice::ReadOnly)) { - m_stream = new MFStream(stream, true); - hr = m_sourceResolver->BeginCreateObjectFromByteStream( - m_stream, reinterpret_cast<const OLECHAR *>(url.toString().utf16()), - MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE, - NULL, &m_cancelCookie, this, new State(m_sourceResolver, true)); - if (FAILED(hr)) { - qWarning() << "Unsupported stream!"; - emit error(hr); - } - } else { - delete stream; - emit error(QMediaPlayer::FormatError); - } - } else -#endif - if (url.scheme() == QLatin1String("qrc")) { - // If the canonical URL refers to a Qt resource, open with QFile and use - // the stream playback capability to play. - stream = new QFile(QLatin1Char(':') + url.path()); - if (stream->open(QIODevice::ReadOnly)) { - m_stream = new MFStream(stream, true); - hr = m_sourceResolver->BeginCreateObjectFromByteStream( - m_stream, reinterpret_cast<const OLECHAR *>(url.toString().utf16()), - MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE, - NULL, &m_cancelCookie, this, new State(m_sourceResolver, true)); - if (FAILED(hr)) { - qWarning() << "Unsupported stream!"; - emit error(hr); - } - } else { - delete stream; - emit error(QMediaPlayer::FormatError); - } - } else { - hr = m_sourceResolver->BeginCreateObjectFromURL( - reinterpret_cast<const OLECHAR *>(url.toString().utf16()), - MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE, - NULL, &m_cancelCookie, this, new State(m_sourceResolver, false)); - if (FAILED(hr)) { - qWarning() << "Unsupported url scheme!"; - emit error(hr); - } - } - } -} - -void SourceResolver::cancel() -{ - QMutexLocker locker(&m_mutex); - if (m_cancelCookie) { - m_sourceResolver->CancelObjectCreation(m_cancelCookie); - m_cancelCookie->Release(); - m_cancelCookie = NULL; - m_sourceResolver->Release(); - m_sourceResolver = NULL; - } -} - -void SourceResolver::shutdown() -{ - if (m_mediaSource) { - m_mediaSource->Shutdown(); - m_mediaSource->Release(); - m_mediaSource = NULL; - } - - if (m_stream) { - m_stream->Release(); - m_stream = NULL; - } -} - -IMFMediaSource* SourceResolver::mediaSource() const -{ - return m_mediaSource; -} - -///////////////////////////////////////////////////////////////////////////////// -SourceResolver::State::State(IMFSourceResolver *sourceResolver, bool fromStream) - : m_cRef(0) - , m_sourceResolver(sourceResolver) - , m_fromStream(fromStream) -{ - sourceResolver->AddRef(); -} - -SourceResolver::State::~State() -{ - m_sourceResolver->Release(); -} - -STDMETHODIMP SourceResolver::State::QueryInterface(REFIID riid, LPVOID *ppvObject) -{ - if (!ppvObject) - return E_POINTER; - if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -STDMETHODIMP_(ULONG) SourceResolver::State::AddRef(void) -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) SourceResolver::State::Release(void) -{ - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - // For thread safety, return a temporary variable. - return cRef; -} - -IMFSourceResolver* SourceResolver::State::sourceResolver() const -{ - return m_sourceResolver; -} - -bool SourceResolver::State::fromStream() const -{ - return m_fromStream; -} - diff --git a/src/plugins/wmf/sourceresolver.h b/src/plugins/wmf/sourceresolver.h deleted file mode 100644 index 007552cb0..000000000 --- a/src/plugins/wmf/sourceresolver.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SOURCERESOLVER_H -#define SOURCERESOLVER_H - -#include "mfstream.h" -#include <QUrl> - -class SourceResolver: public QObject, public IMFAsyncCallback -{ - Q_OBJECT -public: - SourceResolver(); - - ~SourceResolver(); - - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); - STDMETHODIMP_(ULONG) AddRef(void); - STDMETHODIMP_(ULONG) Release(void); - - HRESULT STDMETHODCALLTYPE Invoke(IMFAsyncResult *pAsyncResult); - - HRESULT STDMETHODCALLTYPE GetParameters(DWORD*, DWORD*); - - void load(const QUrl &url, QIODevice* stream); - - void cancel(); - - void shutdown(); - - IMFMediaSource* mediaSource() const; - -Q_SIGNALS: - void error(long hr); - void mediaSourceReady(); - -private: - class State : public IUnknown - { - public: - State(IMFSourceResolver *sourceResolver, bool fromStream); - ~State(); - - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); - - STDMETHODIMP_(ULONG) AddRef(void); - - STDMETHODIMP_(ULONG) Release(void); - - IMFSourceResolver* sourceResolver() const; - bool fromStream() const; - - private: - long m_cRef; - IMFSourceResolver *m_sourceResolver; - bool m_fromStream; - }; - - long m_cRef; - IUnknown *m_cancelCookie; - IMFSourceResolver *m_sourceResolver; - IMFMediaSource *m_mediaSource; - MFStream *m_stream; - QMutex m_mutex; -}; - -#endif diff --git a/src/plugins/wmf/wmf.json b/src/plugins/wmf/wmf.json deleted file mode 100644 index e70736480..000000000 --- a/src/plugins/wmf/wmf.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["windowsmediafoundation"], - "Services": ["org.qt-project.qt.mediaplayer", "org.qt-project.qt.audiodecode"] -} diff --git a/src/plugins/wmf/wmf.pro b/src/plugins/wmf/wmf.pro deleted file mode 100644 index 7c712233d..000000000 --- a/src/plugins/wmf/wmf.pro +++ /dev/null @@ -1,28 +0,0 @@ -TARGET = wmfengine -QT += multimedia-private network - -win32:!qtHaveModule(opengl) { - LIBS_PRIVATE += -lgdi32 -luser32 -} - -INCLUDEPATH += . - -HEADERS += \ - wmfserviceplugin.h \ - mfstream.h \ - sourceresolver.h - -SOURCES += \ - wmfserviceplugin.cpp \ - mfstream.cpp \ - sourceresolver.cpp - -include (player/player.pri) -include (decoder/decoder.pri) - -OTHER_FILES += \ - wmf.json - -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = WMFServicePlugin -load(qt_plugin) diff --git a/src/plugins/wmf/wmfserviceplugin.cpp b/src/plugins/wmf/wmfserviceplugin.cpp deleted file mode 100644 index 09cade82f..000000000 --- a/src/plugins/wmf/wmfserviceplugin.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qstring.h> -#include <QtCore/qdebug.h> -#include <QtCore/QFile> - -#include "wmfserviceplugin.h" -#include "mfplayerservice.h" -#include "mfdecoderservice.h" - -#include <mfapi.h> - -namespace -{ -static int g_refCount = 0; -void addRefCount() -{ - g_refCount++; - if (g_refCount == 1) { - CoInitialize(NULL); - MFStartup(MF_VERSION); - } -} - -void releaseRefCount() -{ - g_refCount--; - if (g_refCount == 0) { - MFShutdown(); - CoUninitialize(); - } -} - -} - -QMediaService* WMFServicePlugin::create(QString const& key) -{ - if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) { - addRefCount(); - return new MFPlayerService; - } - - if (key == QLatin1String(Q_MEDIASERVICE_AUDIODECODER)) { - addRefCount(); - return new MFAudioDecoderService; - } - //qDebug() << "unsupported key:" << key; - return 0; -} - -void WMFServicePlugin::release(QMediaService *service) -{ - delete service; - releaseRefCount(); -} - -QByteArray WMFServicePlugin::defaultDevice(const QByteArray &) const -{ - return QByteArray(); -} - -QList<QByteArray> WMFServicePlugin::devices(const QByteArray &) const -{ - return QList<QByteArray>(); -} - -QString WMFServicePlugin::deviceDescription(const QByteArray &, const QByteArray &) -{ - return QString(); -} - diff --git a/src/plugins/wmf/wmfserviceplugin.h b/src/plugins/wmf/wmfserviceplugin.h deleted file mode 100644 index a9a722043..000000000 --- a/src/plugins/wmf/wmfserviceplugin.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WMFSERVICEPLUGIN_H -#define WMFSERVICEPLUGIN_H - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include "qmediaserviceproviderplugin.h" - -QT_USE_NAMESPACE - -class WMFServicePlugin - : public QMediaServiceProviderPlugin - , public QMediaServiceSupportedDevicesInterface -{ - Q_OBJECT - Q_INTERFACES(QMediaServiceSupportedDevicesInterface) - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "wmf.json") - -public: - QMediaService* create(QString const& key); - void release(QMediaService *service); - - QMediaServiceFeaturesInterface::Features supportedFeatures(const QByteArray &service) const; - - QByteArray defaultDevice(const QByteArray &service) const; - QList<QByteArray> devices(const QByteArray &service) const; - QString deviceDescription(const QByteArray &service, const QByteArray &device); -}; - -#endif // WMFSERVICEPLUGIN_H |