summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Mira <samuel.mira@qt.io>2022-05-18 17:00:13 +0300
committerSamuel Mira <samuel.mira@qt.io>2022-05-18 17:47:38 +0300
commit9e66b1d4f620e4adaa4ec870f9b4d348758e20ce (patch)
treeeee68f94e291b4aa7e525f2a5046e2fca2dab43f
parent5aee7ce23d139e7e4c36cad6d2bbf861eddc8d01 (diff)
Android: Enable FFmpeg playback - SW rendering
This patch enables video playback on Android using the FFmpeg backend. For now, just Software rendering with audio subsystem integration. Also, to get basic rendering working, this patch adds the conversion of content scheme URLs into qmediaplayer.cpp. Task-number: QTBUG-102232 Task-number: QTBUG-100474 Change-Id: I0e0efa8d05ad9c1bfaaedd2a18d6d2e7a163b999 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
-rw-r--r--cmake/FindFFmpeg.cmake16
-rw-r--r--src/multimedia/configure.cmake2
-rw-r--r--src/multimedia/playback/qmediaplayer.cpp16
-rw-r--r--src/plugins/multimedia/ffmpeg/CMakeLists.txt17
-rw-r--r--src/plugins/multimedia/ffmpeg/qffmpegmediaintegration.cpp28
5 files changed, 78 insertions, 1 deletions
diff --git a/cmake/FindFFmpeg.cmake b/cmake/FindFFmpeg.cmake
index bb7cf1ea9..1ee312578 100644
--- a/cmake/FindFFmpeg.cmake
+++ b/cmake/FindFFmpeg.cmake
@@ -102,6 +102,18 @@ macro(find_component _component _pkgconfig _library _header)
pkg_check_modules(PC_${_component} ${_pkgconfig})
endif ()
+ if (FFMPEG_DIR OR FFMPEG_ROOT)
+ set(__find_ffmpeg_backup_root_dir "${CMAKE_FIND_ROOT_PATH}")
+ endif()
+
+ if(FFMPEG_DIR)
+ list(APPEND CMAKE_FIND_ROOT_PATH "${FFMPEG_DIR}")
+ endif()
+
+ if(FFMPEG_ROOT)
+ list(APPEND CMAKE_FIND_ROOT_PATH "${FFMPEG_ROOT}")
+ endif()
+
find_path(${_component}_INCLUDE_DIRS ${_header}
HINTS
${PC_${_component}_INCLUDEDIR}
@@ -124,6 +136,10 @@ macro(find_component _component _pkgconfig _library _header)
lib
)
+ if(FFMPEG_DIR OR FFMPEG_ROOT)
+ set(CMAKE_FIND_ROOT_PATH "${__find_ffmpeg_backup_root_dir}")
+ endif()
+
get_filename_component(${_component}_LIBRARY_DIR_FROM_FIND ${${_component}_LIBRARY} DIRECTORY)
get_filename_component(${_component}_LIBRARY_FROM_FIND ${${_component}_LIBRARY} NAME)
diff --git a/src/multimedia/configure.cmake b/src/multimedia/configure.cmake
index f4e2b173e..efcadfc5c 100644
--- a/src/multimedia/configure.cmake
+++ b/src/multimedia/configure.cmake
@@ -73,7 +73,7 @@ qt_feature("ffmpeg" PRIVATE
LABEL "FFmpeg"
ENABLE INPUT_ffmpeg STREQUAL 'yes'
DISABLE INPUT_ffmpeg STREQUAL 'no'
- CONDITION FFmpeg_FOUND AND (APPLE OR WIN32 OR QNX OR QT_FEATURE_pulseaudio)
+ CONDITION FFmpeg_FOUND AND (APPLE OR WIN32 OR ANDROID OR QNX OR QT_FEATURE_pulseaudio)
)
qt_feature("alsa" PUBLIC PRIVATE
LABEL "ALSA (experimental)"
diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp
index a93453ebb..ac7c8fa06 100644
--- a/src/multimedia/playback/qmediaplayer.cpp
+++ b/src/multimedia/playback/qmediaplayer.cpp
@@ -51,6 +51,8 @@
#include <QtCore/qfileinfo.h>
#include <QtCore/qtemporaryfile.h>
#include <QtCore/qdir.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qjniobject.h>
QT_BEGIN_NAMESPACE
@@ -218,6 +220,20 @@ void QMediaPlayerPrivate::setMedia(const QUrl &media, QIODevice *stream)
qWarning("Qt was built with -no-feature-temporaryfile: playback from resource file is not supported!");
#endif
}
+#if defined(Q_OS_ANDROID)
+ } else if (media.scheme() == QLatin1String("content") && !stream) {
+ // content scheme should happen only on android
+ const int fd = QJniObject::callStaticMethod<jint>(
+ "org/qtproject/qt/android/QtNative", "openFdForContentUrl",
+ "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I",
+ QNativeInterface::QAndroidApplication::context(),
+ QJniObject::fromString(media.toString()).object(),
+ QJniObject::fromString(QLatin1String("r")).object());
+
+ file.reset(new QFile(QLatin1Char(':') + media.path()));
+ file->open(fd, QFile::ReadOnly, QFile::FileHandleFlag::AutoCloseHandle);
+ control->setMedia(media, file.get());
+#endif
} else {
qrcMedia = QUrl();
QUrl url = media;
diff --git a/src/plugins/multimedia/ffmpeg/CMakeLists.txt b/src/plugins/multimedia/ffmpeg/CMakeLists.txt
index 1a42af31d..402a3b0aa 100644
--- a/src/plugins/multimedia/ffmpeg/CMakeLists.txt
+++ b/src/plugins/multimedia/ffmpeg/CMakeLists.txt
@@ -83,3 +83,20 @@ qt_internal_extend_target(QFFmpegMediaPlugin CONDITION QT_FEATURE_linux_v4l
SOURCES
qv4l2camera.cpp qv4l2camera_p.h
)
+
+if (ANDROID)
+ qt_internal_extend_target(QFFmpegMediaPlugin
+ INCLUDE_DIRECTORIES
+ ${FFMPEG_DIR}/include
+ )
+
+ set_property(TARGET QFFmpegMediaPlugin APPEND PROPERTY QT_ANDROID_LIB_DEPENDENCIES
+ plugins/multimedia/libplugins_multimedia_ffmegmediaplugin.so
+ )
+
+ set_property(TARGET QFFmpegMediaPlugin APPEND PROPERTY QT_ANDROID_PERMISSIONS
+ android.permission.CAMERA android.permission.RECORD_AUDIO
+ android.permission.BLUETOOTH
+ android.permission.MODIFY_AUDIO_SETTINGS
+ )
+endif()
diff --git a/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration.cpp b/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration.cpp
index 791a75cee..791b59d47 100644
--- a/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration.cpp
+++ b/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration.cpp
@@ -60,6 +60,13 @@
#include "qwindowsvideodevices_p.h"
#endif
+#ifdef Q_OS_ANDROID
+# include "jni.h"
+extern "C" {
+# include <libavcodec/jni.h>
+}
+#endif
+
#if QT_CONFIG(linux_v4l)
#include "qv4l2camera_p.h"
#endif
@@ -164,6 +171,27 @@ QPlatformAudioInput *QFFmpegMediaIntegration::createAudioInput(QAudioInput *inpu
return new QFFmpegAudioInput(input);
}
+#ifdef Q_OS_ANDROID
+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
+ void *environment;
+ if (vm->GetEnv(&environment, JNI_VERSION_1_6))
+ return JNI_ERR;
+
+ // setting our javavm into ffmpeg.
+ if (av_jni_set_java_vm(vm, nullptr))
+ return JNI_ERR;
+
+ return JNI_VERSION_1_6;
+}
+#endif
+
QT_END_NAMESPACE
#include "qffmpegmediaintegration.moc"